我有一个程序,它接受一个描述一系列初始条件的输入文件并输出一系列最终条件。我还有一个批处理脚本,它通过将输入文件中的初始条件范围分解成更小的块并将它们提供给程序的独立实例来“并行化”程序。只要我只尝试在一个节点上运行批处理脚本,这似乎就可以正常工作,但是如果我请求多个节点,则程序的每个实例都会在每个节点上复制。
这是我正在使用的批处理脚本的一个非常简化的版本,它重复了这个问题:
---my_job_splitter.sh---
#!/bin/env bash
#SBATCH --job-name Test
#SBATCH --output=%x_%j_%t.csv
#SBATCH --error=log.err
#SBATCH --mail-type=END,FAIL
#SBATCH --nodes=4
#Read the command line input
if [ "$#" -ge 4 ]; then
numtasks=${1}
inptrangestart=${2}
inptrangeend=${3}
inptrangenum=${4}
fi
#Calculate the size of the chunks to break the range into
chunksize=$((inptrangenum/numtasks))
#Run a separate instance my_program to process each smaller chunk of the input range
for ((ii=0;ii<numtasks;ii++)); do
stp=`echo "scale=4;($inptrangeend-$inptrangestart)/($inptrangenum-1)" | bc`
a=`echo "$chunksize*$stp*$ii" | bc`
b=`echo "$a+($chunksize-1)*$stp" | bc`
srun my_program.sh $a $b $chunksize &
done
wait
出于说明目的,my_program
它只是一个 bash 脚本,它接受输入范围并将其stdout
作为 csv 行写入:
---my_program.sh---
#!/bin/env bash
echo "$1,$2,$3"
如果一切都在做我想要的,如果我运行命令
sbatch my_job_splitter 32 0 1000 4000
,输出文件应该是一个包含 32 个条目的 CSV 文件,每个条目的范围为 0:1000 的 1/32,但是我得到一个包含 96 个条目和每个范围的 CSV 文件块被复制了 3 次。我想我明白发生了什么——每次我运行 srun 时,它都会看到我分配了 3 个节点并假设我想要每个节点有 1 个任务,所以它只是复制任务,直到它为每个节点分配了 1 个任务——但我不知道如何解决它,或者这是否是一种愚蠢的做法。
我尝试过的其他事情:
- 使用
--exclusive
on 标志srun
:这只会导致srun
只使用一个节点而忽略其他分配的节点 - 根本不使用
srun
:这似乎与使用相同的效果srun --exclusive