SLURM sbatch 多个并行调用可执行文件

7

我有一个可执行文件,需要多个选项和多个文件输入才能运行。该可执行文件可以用可变数量的核来调用。

例如:executable -a -b -c -file fileA --file fileB ... --file fileZ --cores X

我想创建一个sbatch文件,使我能够使用不同的输入对该可执行文件进行多次调用。每次调用都应该分配在不同的节点中(与其余节点并行),并使用X个核。核级别的并行化由可执行文件处理,而节点级别的并行化由SLURM处理。

我尝试过使用ntasks和多个sruns,但第一个srun被多次调用。

另一种方法是在扩展名之前将文件重命名,并使用SLURM进程或节点编号作为文件名,但这并不实用。

对此有什么见解吗?


它必须是单个脚本还是可以是多个sbatch脚本? - Carles Fenoy
我认为一个单一的脚本会最有用。 - IVy
4个回答

2
我通常使用bash脚本来完成这些任务,通过sbatch命令运行。最简单的方法是在sbatch脚本中使用循环,在可执行文件下使用srun指定相应节点名字以及作业步骤。您也可以阅读Slurm数组作业的文档(如果更适合您)。或者,您还可以将所有参数组合存储在文件中,然后使用脚本循环遍历它们,或查看“数组作业”手册页面。
也许下面的脚本(我刚刚包装好)可以帮助您了解我的想法(希望这正是您需要的)。它没有经过测试,所以不要只是复制粘贴!
#!/bin/bash

parameter=(10 5 2)
node_names=(node1 node2 node3)


# lets run one job per node each time taking one parameter

for parameter in ${parameter[*]}
    # asign parameter to node
    #script some if else condition here to specify parameters
    # -w specifies the name of the node to use
    # -N specifies the amount of nodes
    JOBNAME="jmyjob$node-$parameter"
    # asign the first job to the node
    $node=${node_names[0]}
    #delete first node from list
    unset node_names[0];
    #reinstantiate list
    node_names=("${Unix[@]}")
    srun -N1 -w$node -psomepartition -JJOBNAME executable.sh model_parameter &

done;

您会遇到这样的问题,需要强制sbatch脚本等待最后一个作业步骤完成。在这种情况下,以下额外的while循环可能会有所帮助。
# Wait for the last job step to complete
while true;
do
    # wait for last job to finish use the state of sacct for that
    echo "waiting for last job to finish"
    sleep 10
    # sacct shows your jobs, -R only running steps
    sacct -s R,gPD|grep "myjob*" #your job name indicator
    # check the status code of grep (1 if nothing found)
    if [ "$?" == "1" ];
    then
    echo "found no running jobs anymore"
    sacct -s R |grep "myjob*"
    echo "stopping loop"
    break;
    fi
done;

账户-s R,gPD未被识别。这是一个打字错误还是另一个版本?我已经删除了",gPD",但脚本并没有结束,仍然占用所有节点。 - IVy
是的,您需要找到一个grep表达式,以查找正在运行的作业的待处理作业步骤或类似内容。 - PlagTag
仅仅在srun命令后面加上一个简单的等待不够吗?就像这里所示:http://geco.mines.edu/scripts/notes.pdf - 第62页。 - IVy
@IVy,好问题!我记得很久以前用过它。但应该很容易测试。下次我写批处理作业时会测试一下。顺便说一句,在这里研究数组作业可能也是值得的。 - PlagTag

1
我找到了一个可能的解决方案,现在将其发布供参考:
我声明了与可执行文件调用次数相同的任务、节点和每个调用所需的CPU数量。
然后对于每个调用单独使用srun命令,声明每次调用的节点和任务数。所有的srun命令都用&符号连接:
srun -n 1 -N 1 --exclusive executable -a1 -b1 -c1 -file fileA1 --file fileB1 ... --file fileZ1 --cores X1 &
srun -n 1 -N 1 --exclusive executable -a2 -b2 -c2 -file fileA2 --file fileB2 ... --file fileZ2 --cores X2 &

....

srun -n 1 -N 1 --exclusive 可执行文件名 -aN -bN -cN -file 文件名AN --file 文件名BN ... --file 文件名ZN --cores XN

--编辑:经过一些测试(如我在下面的评论中提到的),如果最后一个srun的进程在其余进程之前结束,它似乎会结束整个作业,使其余部分无法完成。

--根据Carles Fenoy的评论进行了编辑


您可以使用GNU Parallel与srun一起轻松生成命令参数。 - damienfrancois
我在最后一个srun命令中遇到了问题。如果它是第一个结束的,它会杀死所有剩余的进程。即使我在每个srun调用中添加了nokill和-k选项。有任何想法吗? - IVy
1
@IVy,你可以使用wait作为最后一个命令。 - akraf

0

0
编写一个bash脚本来填充多个xyz.slurm文件,并使用sbatch提交每个文件。以下脚本执行嵌套的for循环以创建8个文件。然后遍历这些文件,替换其中的字符串,最后进行批处理。您可能需要修改脚本以适应您的需求。
#!/usr/bin/env bash
#Path Where you want to create slurm files
slurmpath=~/Desktop/slurms
rm -rf $slurmpath
mkdir -p $slurmpath/sbatchop
mkdir -p /exports/home/schatterjee/reports
echo "Folder /slurms and /reports created"

declare -a threads=("1" "2" "4" "8")
declare -a chunks=("1000" "32000")
declare -a modes=("server" "client")

## now loop through the above array
for i in "${threads[@]}"
{
    for j in "${chunks[@]}"
    {
#following are the content of each slurm file
cat <<EOF >$slurmpath/net-$i-$j.slurm
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --output=$slurmpath/sbatchop/net-$i-$j.out
#SBATCH --wait-all-nodes=1
echo \$SLURM_JOB_NODELIST

cd /exports/home/schatterjee/cs553-pa1

srun ./MyNETBench-TCP placeholder1 $i $j
EOF
    #Now schedule them
      for m in "${modes[@]}"
      {
        for value in {1..5}
        do
        #Following command replaces placeholder1 with the value of m
        sed -i -e 's/placeholder1/'"$m"'/g' $slurmpath/net-$i-$j.slurm
        sbatch $slurmpath/net-$i-$j.slurm
        done
      }
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接