首页 > 解决方案 > 如何使用一个 slurm 批处理脚本并行运行作业?

问题描述

我正在尝试与一个 Slurm 批处理脚本并行运行多个 python 脚本。看看下面的例子:

#!/bin/bash
#
#SBATCH --job-name=test
#SBATCH --output=/dev/null
#SBATCH --error=/dev/null
#SBATCH --ntasks=2
#SBATCH --cpus-per-task=1
#SBATCH --mem-per-cpu=1G
#SBATCH --partition=All
#SBATCH --time=5:00

srun sleep 60
srun sleep 60
wait

如何调整脚本以使执行仅需 60 秒(而不是 120 秒)?将脚本拆分为两个脚本不是一种选择。

标签: parallel-processingslurm

解决方案


如所写,该脚本正在并行sleep运行两个命令,连续两次

每个srun命令都会启动一个step,并且由于您设置了--ntasks=2每个 step 都会实例化两个任务(这里是sleep命令)。

如果你想并行运行两个 1-task 步骤,你应该这样写:

srun --exclusive -n 1 -c 1 sleep 60 &
srun --exclusive -n 1 -c 1 sleep 60 &
wait

然后每一步只实例化一个任务,并以&分隔符为背景,意味着下一步srun可以立即开始。该wait命令确保脚本仅在两个步骤都完成时终止。

在这种情况下, xargs命令GNU 并行命令对于避免编写多个相同srun的行或避免for-循环很有用。

例如,如果您有多个文件,则需要运行脚本:

find /path/to/data/*.csv -print0 | xargs -0 -n1 -P $SLURM_NTASKS srun -n1 --exclusive python my_python_script.py

这相当于写了很多

srun -n 1 -c 1 --exclusive python my_python_script.py /path/to/data/file1.csv &
srun -n 1 -c 1 --exclusive python my_python_script.py /path/to/data/file1.csv &
srun -n 1 -c 1 --exclusive python my_python_script.py /path/to/data/file1.csv &
[...]

GNU 并行对于迭代参数值很有用:

parallel -P $SLURM_NTASKS srun  -n1 --exclusive python my_python_script.py ::: {1..1000}

会跑

python my_python_script.py 1
python my_python_script.py 2
python my_python_script.py 3
...
python my_python_script.py 1000

另一种方法是运行

srun python my_python_script.py

并且,在 Python 脚本中,查找SLURM_PROCID环境变量并根据其值拆分工作。该srun命令将启动脚本的多个实例,每个实例将“看到”不同的SLURM_PROCID.

import os
print(os.environ['SLURM_PROCID'])

推荐阅读