首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Slurm中的GPU分配:-gres vs -GPU-每个任务,mpirun vs srun

Slurm中的GPU分配:-gres vs -GPU-每个任务,mpirun vs srun
EN

Stack Overflow用户
提问于 2021-04-14 11:41:33
回答 1查看 7.4K关注 0票数 5

在Slurm中有两种分配GPU的方法:一般的--gres=gpu:N参数,或者像--gpus-per-task=N这样的特定参数。在批处理脚本中启动MPI任务还有两种方法:要么使用srun,要么使用通常的mpirun (当使用Slurm支持编译OpenMPI时)。我发现这些方法在行为上有一些惊人的差异。

我使用sbatch提交了一个批处理作业,其中基本脚本如下:

代码语言:javascript
运行
复制
#!/bin/bash

#SBATCH --job-name=sim_1        # job name (default is the name of this file)
#SBATCH --output=log.%x.job_%j  # file name for stdout/stderr (%x will be replaced with the job name, %j with the jobid)
#SBATCH --time=1:00:00          # maximum wall time allocated for the job (D-H:MM:SS)
#SBATCH --partition=gpXY        # put the job into the gpu partition
#SBATCH --exclusive             # request exclusive allocation of resources
#SBATCH --mem=20G               # RAM per node
#SBATCH --threads-per-core=1    # do not use hyperthreads (i.e. CPUs = physical cores below)
#SBATCH --cpus-per-task=4       # number of CPUs per process

## nodes allocation
#SBATCH --nodes=2               # number of nodes
#SBATCH --ntasks-per-node=2     # MPI processes per node

## GPU allocation - variant A
#SBATCH --gres=gpu:2            # number of GPUs per node (gres=gpu:N)

## GPU allocation - variant B
## #SBATCH --gpus-per-task=1       # number of GPUs per process
## #SBATCH --gpu-bind=single:1     # bind each process to its own GPU (single:<tasks_per_gpu>)

# start the job in the directory it was submitted from
cd "$SLURM_SUBMIT_DIR"

# program execution - variant 1
mpirun ./sim

# program execution - variant 2
#srun ./sim

第一个块中的#SBATCH选项非常明显,也很乏味。接下来,当作业至少在两个节点上运行时,我将描述的行为是可以观察到的。我在每个节点运行2个任务,因为我们每个节点有2个GPU。最后,有两个变体的GPU分配(A和B)和两个变体的程序执行(1和2)。因此,总共有4个变体: A1、A2、B1、B2。

变量A1 (--gres=gpu:2,mpirun)

变量A2 (-gres=gpu:2,srun)

在两个变体A1和A2中,作业以最佳性能正确执行,日志中有以下输出:

代码语言:javascript
运行
复制
Rank 0: rank on node is 0, using GPU id 0 of 2, CUDA_VISIBLE_DEVICES=0,1
Rank 1: rank on node is 1, using GPU id 1 of 2, CUDA_VISIBLE_DEVICES=0,1
Rank 2: rank on node is 0, using GPU id 0 of 2, CUDA_VISIBLE_DEVICES=0,1
Rank 3: rank on node is 1, using GPU id 1 of 2, CUDA_VISIBLE_DEVICES=0,1

变体B1 (-gpus每个任务=1,mpirun)

由于第二个节点上的CUDA_VISIBLE_DEVICES=0,作业未正确执行,GPU未正确映射:

代码语言:javascript
运行
复制
Rank 0: rank on node is 0, using GPU id 0 of 2, CUDA_VISIBLE_DEVICES=0,1
Rank 1: rank on node is 1, using GPU id 1 of 2, CUDA_VISIBLE_DEVICES=0,1
Rank 2: rank on node is 0, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=0
Rank 3: rank on node is 1, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=0

请注意,这个变体的行为与不含--gpu-bind=single:1的情况相同。

变体B2 (--gpu-每个任务=1,-gpu=单:1,srun)

GPU被正确地映射(由于--gpu-bind=single:1,每个进程只看到一个GPU):

代码语言:javascript
运行
复制
Rank 0: rank on node is 0, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=0
Rank 1: rank on node is 1, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=1
Rank 2: rank on node is 0, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=0
Rank 3: rank on node is 1, using GPU id 0 of 1, CUDA_VISIBLE_DEVICES=1

但是,当级别开始通信时会出现MPI错误(对于每个级别重复一次类似的消息):

代码语言:javascript
运行
复制
--------------------------------------------------------------------------
The call to cuIpcOpenMemHandle failed. This is an unrecoverable error
and will cause the program to abort.
  Hostname:                         gp11
  cuIpcOpenMemHandle return value:  217
  address:                          0x7f40ee000000
Check the cuda.h file for what the return value means. A possible cause
for this is not enough free device memory.  Try to reduce the device
memory footprint of your application.
--------------------------------------------------------------------------

虽然它说“这是一个无法恢复的错误”,但执行似乎进行得很好,除非日志中到处都是这样的消息(假设每个MPI通信调用都有一条消息):

代码语言:javascript
运行
复制
[gp11:122211] Failed to register remote memory, rc=-1
[gp11:122212] Failed to register remote memory, rc=-1
[gp12:62725] Failed to register remote memory, rc=-1
[gp12:62724] Failed to register remote memory, rc=-1

显然,这是一个OpenMPI错误消息。我发现了一个关于这个错误的旧螺纹,它建议使用--mca btl_smcuda_use_cuda_ipc 0来禁用CUDA IPC。但是,由于在本例中使用srun启动程序,我不知道如何将这些参数传递给OpenMPI。

注意,在这个变体中,--gpu-bind=single:1只影响可见的GPU (CUDA_VISIBLE_DEVICES)。但是即使没有这个选项,每个任务仍然能够选择正确的GPU和错误仍然出现。

知道发生了什么以及如何解决变体B1和B2中的错误吗?理想情况下,我们希望使用--gpus-per-task,它比--gres=gpu:...更灵活(当我们更改--ntasks-per-node时,它可以更改的参数少了一个)。对我们来说,使用mpirunsrun并不重要。

我们有Slurm 20.11.5.1,OpenMPI 4.0.5 ( --with-cuda--with-slurm)和CUDA 11.2.2。操作系统是Arch。网络是10G以太网(没有InfiniBand或OmniPath)。如果我应该包括更多的信息,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2022-02-03 14:17:24

我有个相关的问题。同跑

代码语言:javascript
运行
复制
#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gres=gpu:1

将导致进程共享一个GPU。

代码语言:javascript
运行
复制
"PROCID=2: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360)"
"PROCID=1: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360)"
"PROCID=0: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360)"
"PROCID=3: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360)"

我想这是正确的。

同跑

代码语言:javascript
运行
复制
#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gpus-per-task=1

将只导致最后一个接收GPU的进程。

代码语言:javascript
运行
复制
"PROCID=2: No devices found."
"PROCID=3: No devices found."
"PROCID=0: No devices found."
"PROCID=1: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-02348a17-a825-300c-0336-48e33d0dadb2)"

注意连续运行中的不同ID。

代码语言:javascript
运行
复制
"PROCID=2: No devices found."
"PROCID=1: No devices found."
"PROCID=3: No devices found."
"PROCID=0: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360)"

同跑

代码语言:javascript
运行
复制
#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gres=gpu:4

将导致每个进程都可以访问所有4个GPU。

代码语言:javascript
运行
复制
"PROCID=3: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360) GPU 1: NVIDIA A100-SXM4-40GB (UUID: GPU-02348a17-a825-300c-0336-48e33d0dadb2) GPU 2: NVIDIA A100-SXM4-40GB (UUID: GPU-fbd9a227-e473-b993-215f-8f39b3574fd0) GPU 3: NVIDIA A100-SXM4-40GB (UUID: GPU-7843f55f-a15b-1d4c-229c-39b5c439bd5e)"
"PROCID=1: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360) GPU 1: NVIDIA A100-SXM4-40GB (UUID: GPU-02348a17-a825-300c-0336-48e33d0dadb2) GPU 2: NVIDIA A100-SXM4-40GB (UUID: GPU-fbd9a227-e473-b993-215f-8f39b3574fd0) GPU 3: NVIDIA A100-SXM4-40GB (UUID: GPU-7843f55f-a15b-1d4c-229c-39b5c439bd5e)"
"PROCID=2: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360) GPU 1: NVIDIA A100-SXM4-40GB (UUID: GPU-02348a17-a825-300c-0336-48e33d0dadb2) GPU 2: NVIDIA A100-SXM4-40GB (UUID: GPU-fbd9a227-e473-b993-215f-8f39b3574fd0) GPU 3: NVIDIA A100-SXM4-40GB (UUID: GPU-7843f55f-a15b-1d4c-229c-39b5c439bd5e)"
"PROCID=0: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-715daa1d-db6f-9e69-ab48-190158bd5360) GPU 1: NVIDIA A100-SXM4-40GB (UUID: GPU-02348a17-a825-300c-0336-48e33d0dadb2) GPU 2: NVIDIA A100-SXM4-40GB (UUID: GPU-fbd9a227-e473-b993-215f-8f39b3574fd0) GPU 3: NVIDIA A100-SXM4-40GB (UUID: GPU-7843f55f-a15b-1d4c-229c-39b5c439bd5e)"

同跑

代码语言:javascript
运行
复制
#SBATCH --ntasks=4
#SBATCH --gres=gpu:4
#SBATCH --gpu-bind=single:1

将再次导致最后一个接收GPU的进程。

代码语言:javascript
运行
复制
"PROCID=1: No devices found."
"PROCID=0: No devices found."
"PROCID=3: No devices found."
"PROCID=2: GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-fbd9a227-e473-b993-215f-8f39b3574fd0)"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67091056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档