Cuda 如何选择在哪个GPU上运行作业?

Cuda 如何选择在哪个GPU上运行作业?,cuda,nvidia,Cuda,Nvidia,在多GPU计算机中,如何指定CUDA作业应在哪个GPU上运行 例如,在安装CUDA时,我选择安装NVIDIA_CUDA-\u示例,然后运行了几个nbody模拟实例,但它们都在一个GPU 0上运行;GPU 1完全闲置(使用监视-n 1 nvidia dmi进行监视)。检查CUDA\u可见\u设备使用 echo $CUDA_VISIBLE_DEVICES 我发现这是没有设置的。我试着用 CUDA_VISIBLE_DEVICES=1 然后再次运行nbody,但它也转到GPU 0 我查看了相关问题,

在多GPU计算机中,如何指定CUDA作业应在哪个GPU上运行

例如,在安装CUDA时,我选择安装
NVIDIA_CUDA-\u示例
,然后运行了几个
nbody
模拟实例,但它们都在一个GPU 0上运行;GPU 1完全闲置(使用
监视-n 1 nvidia dmi
进行监视)。检查
CUDA\u可见\u设备
使用

echo $CUDA_VISIBLE_DEVICES
我发现这是没有设置的。我试着用

CUDA_VISIBLE_DEVICES=1
然后再次运行
nbody
,但它也转到GPU 0

我查看了相关问题,但是
deviceQuery
命令不在CUDA8.0bin目录中。除了
$CUDA\u VISIBLE\u DEVICES$
,我还看到其他帖子引用了环境变量
$CUDA\u DEVICES
,但这些都没有设置,我也没有找到如何使用它的信息

虽然与我的问题没有直接关系,但使用
nbody-device=1
我能够让应用程序在GPU 1上运行,但使用
nbody-numdevices=2
并没有在GPU 0和GPU 1上运行

我正在使用bash shell、CentOS 6.8、CUDA 8.0、2 GTX 1080 GPU和NVIDIA驱动程序367.44运行的系统上进行测试


我知道在使用CUDA编写时,您可以管理和控制要使用的CUDA资源,但在运行已编译的CUDA可执行文件时,如何从命令行进行管理?

问题是由于未正确设置shell中的
CUDA\u VISIBLE\u DEVICES
变量造成的

例如,要指定CUDA设备
1
,可以使用

export CUDA_VISIBLE_DEVICES=1

前者为当前shell的生命周期设置变量,后者仅为特定可执行调用的生命周期设置变量

如果要指定多个设备,请使用

export CUDA_VISIBLE_DEVICES=0,1


设置以下两个环境变量:

NVIDIA_VISIBLE_DEVICES=$gpu_id
CUDA_VISIBLE_DEVICES=0
其中,
gpu\U id
是所选gpu的id,如主机系统的
nvidia smi
(一个基于0的整数)中所示,将提供给来宾系统(例如Docker容器环境)

您可以通过检查
nvidia smi
中的
总线id
参数(在来宾系统的终端中运行),验证是否为每个gpu id值选择了不同的卡

更多信息 这种基于
NVIDIA_VISIBLE_DEVICES
的方法只向系统公开一张卡(本地ID为零),因此我们还将另一个变量
CUDA_VISIBLE_DEVICES
硬编码为0(主要是防止它默认为空字符串,表示没有GPU)

请注意,应该在来宾系统启动之前设置环境变量(因此在Jupyter笔记本的终端中不可能设置),例如使用Kubernetes或Openshift中的
docker run-e NVIDIA_VISIBLE_DEVICES=0
env

如果您想要GPU负载平衡,请在每个来宾系统启动时随机设置
GPU\id

如果使用python设置此选项,请确保您适用于所有环境变量,包括数值变量

通过检查
nvidia smi
的总线id参数(在来宾系统的终端运行中),可以验证是否为
gpu id
的每个值选择了不同的卡

仅基于
CUDA\u VISIBLE\u设备的公认解决方案
不会隐藏其他卡(与固定卡不同),因此,如果您尝试在支持GPU的python包中使用这些卡,则会导致访问错误。使用此解决方案,来宾系统看不到其他卡,但其他用户仍然可以访问它们,并在平等的基础上共享它们的计算能力,就像使用CPU一样(已验证)

这也比使用Kubernetes/Openshift控制器(
resources.limits.nvidia.com/gpu
)的解决方案更可取,后者会对分配的卡施加锁,将其从可用资源池中移除(因此具有gpu访问权限的容器数量不能超过物理卡的数量)


这已经在CUDA 8.0、9.0和10.1下,在运行Openshift 3.11编排的Ubuntu18.04的docker容器中进行了测试。

如果其他人正在用Python进行测试,但它不起作用,请尝试在导入pycuda和tensorflow之前设置它

即:


如前所述。

您还可以在命令行中设置GPU,这样就不需要将设备硬编码到脚本中(在没有多个GPU的系统上可能会失败)。假设您想在5号GPU上运行脚本,您可以在命令行中键入以下内容,它将在5号GPU上只运行一次脚本:


对于随机gpu,您可以执行以下操作:

export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))

nbody
nbody
应用程序有一个命令行选项来选择要运行的GPU—您可能需要研究该代码。对于更一般的情况,
CUDA\u可视设备
应该可以工作。如果没有,您可能没有正确使用它,您可能应该给出一个您尝试过的完整示例。您还应该指出您正在为linux操作的操作系统、shell(例如bash、csh等)
deviceQuery
对于这些都不是必需的,它只是一个示例应用程序,用于演示
CUDA\u可视设备的行为。正确的环境变量名中没有
$
。您需要了解有关正在使用的bash shell的更多信息。这:
CUDA\u VISIBLE\u DEVICES=1
不会永久设置环境变量(事实上,如果您在该命令行上只设置了这些,那么它实际上没有任何用处)。此:
export-CUDA\u-VISIBLE\u-DEVICES=1
将为该会话的其余部分永久设置它。您可能想研究bash中环境变量的工作方式,以及各种命令如何影响它们,以及持续多长时间。
deviceQuery
随CUDA 8提供,但您必须构建它。如果你读了CU
NVIDIA_VISIBLE_DEVICES=$gpu_id
CUDA_VISIBLE_DEVICES=0
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
...
import pycuda.autoinit
import tensorflow as tf
...
CUDA_VISIBLE_DEVICES=5, python test_script.py
export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))