在多GPU计算机中,如何指定应运行CUDA作业的GPU?
例如,在安装CUDA时,我选择安装NVIDIA_CUDA-<#.#>_Samples
然后运行nbody
模拟的几个实例,但它们都在一个GPU 0上运行; GPU 1完全空闲(使用watch -n 1 nvidia-dmi
监控)。使用
CUDA_VISIBLE_DEVICES
echo $CUDA_VISIBLE_DEVICES
我发现这没有设定。我尝试使用
进行设置CUDA_VISIBLE_DEVICES=1
然后再次运行nbody
,但它也转到GPU 0。
我查看了相关问题how to choose designated GPU to run CUDA program?,但deviceQuery
命令不在CUDA 8.0 bin目录中。除$CUDA_VISIBLE_DEVICES$
之外,我看到其他帖子引用了环境变量$CUDA_DEVICES
,但这些帖子未设置,我没有找到有关如何使用它的信息。
虽然与我的问题没有直接关系,但使用nbody -device=1
我能够让应用程序在GPU 1上运行,但使用nbody -numdevices=2
并未在GPU 0和1上运行。
我在使用bash shell运行的系统上测试,在CentOS 6.8上运行CUDA 8.0,2 GTX 1080 GPU和NVIDIA驱动程序367.44。
我知道在使用CUDA编写时,您可以管理和控制要使用的CUDA资源,但在运行已编译的CUDA可执行文件时,如何从命令行管理它?
答案 0 :(得分:52)
问题是由于没有正确设置shell中的CUDA_VISIBLE_DEVICES
变量引起的。
例如,要指定CUDA设备1
,您可以使用
CUDA_VISIBLE_DEVICES
export CUDA_VISIBLE_DEVICES=1
或
CUDA_VISIBLE_DEVICES=1 ./cuda_executable
前者为当前shell的生命周期设置变量,后者仅用于特定可执行调用的生命周期。
如果要指定多个设备,请使用
export CUDA_VISIBLE_DEVICES=0,1
或
CUDA_VISIBLE_DEVICES=0,1 ./cuda_executable
答案 1 :(得分:9)
如果其他人正在使用Python进行操作且无法正常工作,请尝试设置,然后再导入pycuda和tensorflow。
即:
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
...
import pycuda.autoinit
import tensorflow as tf
...
看到了here。
答案 2 :(得分:4)
您还可以在命令行中设置GPU,这样就无需将设备硬编码到脚本中(在没有多个GPU的系统上可能会失败)。假设您要在5号GPU上运行脚本,可以在命令行中键入以下内容,它将在GPU#5上仅运行一次脚本:
CUDA_VISIBLE_DEVICES=5, python test_script.py
答案 3 :(得分:3)
设置以下两个环境变量:
NVIDIA_VISIBLE_DEVICES=$gpu_id
CUDA_VISIBLE_DEVICES=0
其中gpu_id
是所选GPU的ID,如主机系统的nvidia-smi
(基于0的整数)所示,该虚拟机将对来宾系统(例如Docker容器)可用环境)。
您可以通过检查在来宾系统的终端中运行的Bus-Id
中的nvidia-smi
参数来验证是否为gpu_id的每个值选择了不同的卡。
基于NVIDIA_VISIBLE_DEVICES
的此方法仅向系统公开单张卡(本地ID为零),因此我们还将另一变量CUDA_VISIBLE_DEVICES
硬编码为0(主要是为了防止它默认为一个空字符串,表示没有GPU。
请注意,应该在启动来宾系统之前设置环境变量(因此,没有机会在Jupyter Notebook的终端中进行设置),例如在Kubernetes或Openshift中使用docker run -e NVIDIA_VISIBLE_DEVICES=0
或env
。
如果要GPU负载平衡,请在每个来宾系统启动时随机设置gpu_id
。
如果使用python进行设置,请确保您对所有环境变量(包括数字变量)都using strings。
通过检查gpu_id
的Bus-Id参数(在来宾系统中运行的终端中),可以验证为nvidia-smi
的每个值选择了不同的卡。
仅基于CUDA_VISIBLE_DEVICES
的公认解决方案不会隐藏其他卡(与固定卡不同),因此,如果尝试在启用GPU的python软件包中使用它们,则会导致访问错误。使用此解决方案,来宾系统看不到其他卡,但是其他用户仍然可以平等地共享它们并共享其计算能力,就像使用CPU(已验证)一样。
这也比使用Kubernetes / Openshift控制器(resources.limits.nvidia.com/gpu
)的解决方案更好,该解决方案将对分配的卡施加锁定,将其从可用资源池中删除(因此可以访问GPU的容器数量可以不超过实体卡的数量。
这已在CUDA 8.0、9.0和10.1下在由Openshift 3.11精心组织的运行Ubuntu 18.04的Docker容器中进行了测试。
答案 4 :(得分:0)
对于随机 GPU,您可以这样做:
export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))