繁体   English   中英

Slurm 中的 GPU 分配:--gres 与 --gpus-per-task,以及 mpirun 与 srun

[英]GPU allocation in Slurm: --gres vs --gpus-per-task, and mpirun vs srun

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

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

#!/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 个任务,因为我们每个节点有 2 个 GPU。 最后,还有 GPU 分配的两种变体(A 和 B)和程序执行的两种变体(1 和 2)。 因此,总共有 4 个变体:A1、A2、B1、B2。

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

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

在变体 A1 和 A2 中,作业以最佳性能正确执行,我们在日志中有以下 output:

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-per-task=1, mpirun)

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

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 (--gpus-per-task=1, --gpu-bind=single:1, srun)

GPU 映射正确(现在每个进程只看到一个 GPU 因为--gpu-bind=single:1 ):

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 错误(每个排名重复一次类似的消息):

--------------------------------------------------------------------------
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 通信调用一条消息):

[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 )。 但是即使没有这个选项,每个任务仍然可以 select 正确的 GPU 并且错误仍然出现。


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

我们有 Slurm 20.11.5.1、OpenMPI 4.0.5(使用--with-cuda--with-slurm )和 CUDA 11.2.2。 操作系统是 Arch Linux。 网络是 10G 以太网(没有 InfiniBand 或 OmniPath)。 让我知道我是否应该包含更多信息。

我有一个相关的问题。 与运行

#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gres=gpu:1

将导致进程共享单个 GPU

"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)"

我认为这是正确的。

与运行

#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gpus-per-task=1

将导致只有最后一个进程收到 GPU

"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

"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)"

与运行

#SBATCH --nodes=1
#SBATCH --ntasks=4
#SBATCH --gres=gpu:4

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

"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)"

与运行

#SBATCH --ntasks=4
#SBATCH --gres=gpu:4
#SBATCH --gpu-bind=single:1

将再次导致仅最后一个进程收到 GPU

"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)"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM