如何为每个任务设置1个gpu的slurm / salloc但让工作使用多个gpus?

时间:2017-09-05 18:14:25

标签: gpu cluster-computing nvidia slurm

我们正在寻找有关slurm salloc gpu分配的一些建议。目前,鉴于:

% salloc -n 4 -c 2 -gres=gpu:1
% srun env | grep CUDA   
CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=0

但是,我们不仅仅需要使用设备0 有没有办法用srun / mpirun指定一个salloc来获取以下内容?

CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=1
CUDA_VISIBLE_DEVICES=2
CUDA_VISIBLE_DEVICES=3

这是期望的,每个任务获得1个gpu,但总体gpu使用分布在4个可用设备中(参见下面的gres.conf)。并非所有任务都获得device = 0。

这样,每个任务都不会在设备0上等待从其他任务中解脱出来,就像目前的情况一样。

或者这是预期的行为,即使我们有4个任务可用/免费(总共4个)超过1个gpu?我们缺少什么或误解了什么?

  • salloc / srun参数?
  • slurm.conf或gres.conf设置?

摘要我们希望能够使用slurm和mpi这样每个等级/任务使用1个gpu,但是这个工作可以在4个gpus中传播任务/等级。目前看来我们仅限于设备0。我们还希望避免因使用mpi而在salloc / sbatch中进行多次srun提交。

操作系统:CentOS 7

Slurm版本:16.05.6

我们是否被迫使用wrapper based methods

如何分配gpus,与slurm版本(14到16)有区别吗?

谢谢!

参考:gres.conf

Name=gpu File=/dev/nvidia0
Name=gpu File=/dev/nvidia1
Name=gpu File=/dev/nvidia2
Name=gpu File=/dev/nvidia3

3 个答案:

答案 0 :(得分:2)

首先,尝试使用

请求四个GPU
% salloc -n 4 -c 2 -gres=gpu:4

使用--gres=gpu:1,预期的行为是所有任务只能看到一个GPU。使用--gres=gpu:4,输出将为

CUDA_VISIBLE_DEVICES=0,1,2,3
CUDA_VISIBLE_DEVICES=0,1,2,3
CUDA_VISIBLE_DEVICES=0,1,2,3
CUDA_VISIBLE_DEVICES=0,1,2,3

要获得您想要的内容,您可以使用包装器脚本,或者像这样修改您的srun命令:

srun bash -c 'CUDA_VISIBLE_DEVICES=$SLURM_PROCID env' | grep CUDA

然后你会得到

CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=1
CUDA_VISIBLE_DEVICES=2
CUDA_VISIBLE_DEVICES=3

答案 1 :(得分:0)

此功能计划于19.05发行。有关详细信息,请参见https://bugs.schedmd.com/show_bug.cgi?id=4979

请注意,如果您的工作不要求该节点上的所有GPU,则建议的“运行bash ...”解决方案将会中断,因为其他进程可能会控制GPU0。

答案 2 :(得分:0)

要为每个任务完成一个 GPU,您需要使用 void change(list_t *e,const char *runstat) { char *str; // safety -- dup the string first to prevent [possible] use after free str = strdup(runstat); // free the old string free(e->runstat); // add in the new string e->runstat = str; } void change_running_status(list_t **list,pid_t pid,char *runstat) { // THe code I wrote with changing statuses in the list for programs. list_t *e; e = *list; if (e->next == NULL) change(e,runstat); else { for (; e != NULL; e = e->next) { if (pid == e->pid) { change(e,runstat); break; } } } } 命令的 --gpu-bind 开关。例如,如果我有 3 个节点,每个节点有 8 个 GPU,并且我希望每个节点运行 8 个任务,每个任务都绑定到一个唯一的 GPU,则以下命令可以解决问题:

srun