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の普及により、誰かが解決したに違いありません。
難しい方法を見つけたので、デバイスを列挙してから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を要求しないようにし、排他モードを利用して衝突を防ぎます。
これは本当にコードレベルで解決されるべき問題です。排他モードのデバイスがある場合は、CUDA APIを使用してすべてのGPUを列挙し、使用可能なGPUが得られるまでそれらを選択してみてください。すでに使用されている排他モードのデバイスを選択しようとすると、CUDA APIはエラーを返します。その場合、次のデバイスに移動します。スケジューリングに関して特別なことをする必要はありません。