Cluster computing 使用多个节点运行slurm脚本,使用1个任务启动作业步骤

Cluster computing 使用多个节点运行slurm脚本,使用1个任务启动作业步骤,cluster-computing,slurm,Cluster Computing,Slurm,我正在尝试使用批处理脚本启动大量作业步骤。不同的步骤可以是完全不同的程序,并且每个步骤只需要一个CPU。首先,我尝试使用--multi-prog参数对srun执行此操作。不幸的是,当以这种方式使用分配给我的工作的所有CPU时,性能会大幅下降。运行时间几乎增加到其序列化值。通过认购不足,我可以稍微改善这一点。我在网上找不到关于这个问题的任何信息,所以我假设这是我正在使用的集群的配置问题 所以我试着走另一条路。我实现了以下脚本(通过sbatch my_script.slurm启动): 我知道,--e

我正在尝试使用批处理脚本启动大量作业步骤。不同的步骤可以是完全不同的程序,并且每个步骤只需要一个CPU。首先,我尝试使用
--multi-prog
参数对
srun
执行此操作。不幸的是,当以这种方式使用分配给我的工作的所有CPU时,性能会大幅下降。运行时间几乎增加到其序列化值。通过认购不足,我可以稍微改善这一点。我在网上找不到关于这个问题的任何信息,所以我假设这是我正在使用的集群的配置问题

所以我试着走另一条路。我实现了以下脚本(通过
sbatch my_script.slurm启动):

我知道,
--exclusive
参数在我的案例中并不真正需要。调用的shell脚本包含不同的二进制文件及其参数。我的脚本的其余部分依赖于所有进程都已完成这一事实,因此执行
等待
。我改变了电话线,使之成为一个最小的工作示例

起初,这似乎是解决办法。不幸的是,当增加作业分配中使用的节点数时(例如,通过将
--ntasks
增加到大于集群中每个节点的CPU数),脚本不再按预期工作,返回

srun: Warning: can't run 1 processes on 2 nodes, setting nnodes to 1
并且继续只使用一个节点(在我的例子中是48个CPU,它们以与以前一样快的速度完成作业步骤,其他节点上的所有进程随后被终止)

这似乎是预期的行为,但我真的无法理解。为什么给定分配中的每个作业步骤都需要包含与分配中包含的节点数相等的最小任务数。我通常根本不关心分配中使用的节点数


如何实现批处理脚本,使其能够可靠地在多个节点上使用?

找到了它!术语和许多命令行选项使我感到困惑。解决方案如下所示:

#!/bin/bash
#SBATCH -o $HOME/slurm/slurm_out/%j.%N.out
#SBATCH --error=$HOME/slurm/slurm_out/%j.%N.err_out
#SBATCH --get-user-env
#SBATCH -J test
#SBATCH -D $HOME/slurm
#SBATCH --export=NONE
#SBATCH --ntasks=48

NR_PROCS=$(($SLURM_NTASKS))
for PROC in $(seq 0 $(($NR_PROCS-1)));
do
    #My call looks like this:
    #srun --exclusive -N1 -n1 bash $PROJECT/call_shells/call_"$PROC".sh &
    srun --exclusive -N1 -n1 hostname &
    pids[${PROC}]=$!    #Save PID of this background process
done
for pid in ${pids[*]};
do
    wait ${pid} #Wait on all PIDs, this returns 0 if ANY process fails
done

这指定仅在包含单个任务的一个节点上运行作业。

因此,您的解决方案是显式请求一个节点(-N1)?是的,确切地说,(我的配置)slurm似乎总是希望为每个节点分配一些工作,如果我没有具体地只请求一个节点。
#!/bin/bash
#SBATCH -o $HOME/slurm/slurm_out/%j.%N.out
#SBATCH --error=$HOME/slurm/slurm_out/%j.%N.err_out
#SBATCH --get-user-env
#SBATCH -J test
#SBATCH -D $HOME/slurm
#SBATCH --export=NONE
#SBATCH --ntasks=48

NR_PROCS=$(($SLURM_NTASKS))
for PROC in $(seq 0 $(($NR_PROCS-1)));
do
    #My call looks like this:
    #srun --exclusive -N1 -n1 bash $PROJECT/call_shells/call_"$PROC".sh &
    srun --exclusive -N1 -n1 hostname &
    pids[${PROC}]=$!    #Save PID of this background process
done
for pid in ${pids[*]};
do
    wait ${pid} #Wait on all PIDs, this returns 0 if ANY process fails
done