使用CUDA_VISIBLE_DEVICES和sge

使用sge与称为“gpu.q”的资源复合体允许gpu设备(这些都是nvidia设备)的资源pipe理。 但是,在系统中有多个gpu设备(独占模式),如果两个作业分配在同一个节点上,则用户无法在正确的gpu上不透明地创build上下文。

有没有人遇到这个问题? 我正在想办法pipe理特定的GPU资源,并映射主机和设备ID。 就像是

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

等等…然后根据资源请求,通过CUDA_VISIBLE_DEVICESvariables显示在每个主机上分配的gpu资源。

这似乎是一个相当普遍的问题 – 到目前为止,一些人已经通过计算集群中gpu的普及来解决这个问题。

当我发现困难的方式,你不能枚举设备,然后调用cudaSetDevice()。 CudaSetDevice()总是成功,如果设备是存在​​的,你还没有创build一个上下文。 我在这里提出的解决scheme是使用nvidia-smi在所有GPU上设置计算模式来处理独占,然后用cudaSetValidDevices()过滤出不能用于你的任务的设备,调用cudaFree()来强制CUDA驱动程序在可用设备上创build上下文。

如果对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不是独占模式,你需要以某种方式从你的排队系统pipe理它们。 这里描述的方法将允许使用可用资源来监视节点上的所有任务,以确保他们从未请求比可用GPU更多的GPU,然后利用独占模式来防止冲突。

这真的是一个应该在代码级别解决的问题。 如果您的设备处于独占模式,则可以使用CUDA API枚举所有GPU,然后尝试select它们,直到获得可用的GPU。 如果您尝试select已使用的独占模式的设备,则CUDA API将返回错误,在这种情况下,您只需转到下一个模式。 你不应该花时间做任何事情。