如何选择运行作业的GPU?

时间:2016-09-22 21:23:54

标签: cuda nvidia

在多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可执行文件时,如何从命令行管理它?

5 个答案:

答案 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=0env

如果要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 )))