web-dev-qa-db-ja.com

sgeでのCUDA_VISIBLE_DEVICESの使用

Gpuデバイス(これらはすべてnvidiaデバイス)のリソース管理を可能にする「gpu.q」と呼ばれるリソースコンプレックスでsgeを使用します。ただし、システムには複数のGPUデバイス(排他モード)があり、2つのジョブが同じノードに割り当てられている場合、ユーザーが正しいGPUにコンテキストを不透明に作成する方法はありません。

誰かがこの問題に遭遇しましたか?どういうわけか特定のGPUリソ​​ースを管理し、ホストとデバイスIDをマッピングすることを考えていました。何かのようなもの

hostA -> gpu0:in_use
hostA -> gpu1:free
hostB -> gpu0:free
hostB -> gpu1:in_use

など...そして、リソースの要求に応じて、CUDA_VISIBLE_DEVICES変数を介して各ホストに割り当てられたGPUリソ​​ースを明らかにします。

これはかなり一般的な問題のようです。計算クラスターでのGPUの普及により、誰かが解決したに違いありません。

1
Marm0t

難しい方法を見つけたので、デバイスを列挙してからcudaSetDevice()を呼び出すことはできません。 CudaSetDevice()は、デバイスが存在し、コンテキストを作成していない場合は常に成功します。 NVidiansからのいくつかのヒントを使用してここで解決した解決策は、nvidia-smiを使用して、すべてのGPUの計算モードを排他的に処理するように設定し、cudaSetValidDevices()を使用してタスクに使用できないデバイスをフィルターで除外することです。 cudaFree()を呼び出して、CUDAドライバーに使用可能なデバイス上にコンテキストを作成させる。

CudaFreeの呼び出しが失敗した場合、使用可能なデバイスはありません。

// Let CUDA select any device from this list of device IDs filtered by your
// own criteria (not shown)
status                                      = cudaSetValidDevices(pGPUList, nGpus);
if (status != cudaSuccess)
{
    printf(("Error searching for compatible GPU\n");
    exit(-1);
}

// Trick driver into creating a context on an available and valid GPU
status                                      = cudaFree(0);
if (status != cudaSuccess)
{
    printf("Error selecting compatible GPU\n");
    exit(-1);
}

// Get device selected by driver
status                                      = cudaGetDevice(&device);
if (status != cudaSuccess)
{
    printf("Error fetching current GPU\n");
    exit(-1);
}

// Your amazing CUDA program goes here...

注:GPUが排他モードでない場合は、何らかの方法でキューイングシステムから明示的にGPUを管理する必要があります。ここで説明する方法では、消費可能なリソースを使用してノード上のすべてのタスクを監視し、ノードで使用可能な数を超えるGPUを要求しないようにし、排他モードを利用して衝突を防ぎます。

1
Scott LeGrand

これは本当にコードレベルで解決されるべき問題です。排他モードのデバイスがある場合は、CUDA APIを使用してすべてのGPUを列挙し、使用可能なGPUが得られるまでそれらを選択してみてください。すでに使用されている排他モードのデバイスを選択しようとすると、CUDA APIはエラーを返します。その場合、次のデバイスに移動します。スケジューリングに関して特別なことをする必要はありません。

0
Kamil Kisiel