关于并行任务的 `srun ... >output_file` 的语义

On the semantics of `srun ... >output_file` for parallel tasks

抱歉,这个问题需要大量的积累,但总而言之,它是关于 srun ... >output_file 的许多并行实例会或不会导致某些 process/task 其他 process/task.

产生的输出

案例 0:仅 bash(无 SLURM)

假设prog-0.sh是下面的玩具脚本:

#!/bin/bash

hostname >&2

if [[ $JOB_INDEX = 0 ]]
then
    date
fi

此脚本将一些输出打印到 stderr,并可能将当前日期打印到 stdout

下面显示的 "driver" 脚本 case-0.sh 生成 $NJOBS 个进程,全部写入 [​​=30=]:

#!/bin/bash

for i in $( seq 0 $(( NJOBS - 1 )) )
do  
    JOB_INDEX=$i ./prog-0.sh >prog-0-stdout.txt &
done

宁运行后

% NJOBS=100 ./case-0.sh 2>prog-0-stderr.txt

...我的期望是 prog-0-stderr.txt 将包含 100 行,而 prog-0-stdout.txt 将是 .

我的期望实现了:

 % wc prog-0-std*.txt
  100  100 3000 prog-0-stderr.txt
    0    0    0 prog-0-stdout.txt
  100  100 3000 total

对这些结果的解释是,当 NJOBS 足够大时,对于某些足够高的 $i 值,可能会评估重定向 >prog-0-stdout.txt "designated job" 之后,JOB_INDEX 0(也是唯一一个将输出发送到 stdout 的)已将日期写入 stdout,因此这将破坏先前由 "designated job" 重定向到 prog-0-stdout.txt.

的任何输出

顺便说一句,NJOBS 的值需要足够高才能使结果如我刚才所述。例如,如果我使用 NJOBS=2:

% NJOBS=2 ./case-0.sh 2>prog-0-stderr.txt

...然后不仅 prog-0-stderr.txt 只包含 2 行(不足为奇),而且 prog-0-stdout.txt 将包含一个日期:

% cat prog-0-stdout.txt
Wed Oct  4 15:02:49 EDT 2017

在这种情况下,所有 >prog-0-stdout.txt 重定向都在指定作业将日期打印到 prog-0-stdout.txt 之前进行了评估。


案例 1:SLURM 作业数组

现在,考虑一个非常相似的场景,但改用 SLURM。脚本 prog-1.shprog-0.sh 相同,只是它检查不同的变量来决定是否将日期打印到 stdout:

#!/bin/bash

hostname >&2

if [[ $SLURM_ARRAY_TASK_ID = 0 ]]
then
    date
fi

这是相应的 "driver" 脚本,case-1.sh:

#!/bin/bash
#SBATCH -t 1
#SBATCH -p test

#SBATCH -e prog-1-%02a-stderr.txt
#SBATCH -n 1
#SBATCH -a 0-99

srun ./prog-1.sh >prog-1-stdout.txt

case-0.sh 一样,此脚本将其主要步骤的输出重定向到单个文件 ./prog-1-stdout.txt.

重要的是,此作业的所有 运行 ./prog-1.sh 节点都可以看到同一个文件。

如果我现在运行

sbatch case-1.sh

...我得到 100 个文件 prog-1-00-stderr.txt ... prog-1-99-stderr.txt,每个文件包含 1 行,还有一个 prog-1-stdout.txt。我假设前面的解释也解释了为什么 prog-1-stdout.txt 是空的。

到目前为止一切顺利。


案例 2:SLURM 任务

最后,再考虑一个基于 SLURM 的案例,这次使用核心脚本 prog-2.sh 和驱动程序脚本 case-2.sh。同样,prog-2.sh 中唯一的变化是它检查的变量,以确定是否将日期打印到 stdout:

#!/bin/bash

hostname >&2

if [[ $SLURM_PROCID = 1 ]]
then
    date
fi

这里是 case-2.sh:

#!/bin/bash
#SBATCH -t 1
#SBATCH -p test

#SBATCH -e prog-2-stderr.txt
#SBATCH -N 10
#SBATCH --tasks-per-node=10

srun -l ./prog-2.sh >prog-2-stdout.txt

和以前一样,prog-2-stdout.txt 对所有处理作业的节点可见。

现在,如果我 运行 sbatch case-2.sh 并等待批处理作业完成,那么 prog-2-stderr.txt 包含 100 行(如预期的那样),但是 我的惊喜prog-2-stdout.txt不是空的。实际上,它包含一个日期:

% cat prog-2-stdout.txt
01: Wed Oct  4 15:21:17 EDT 2017

我能想到的唯一解释类似于我之前对 运行

时得到的结果给出的解释
% NJOBS=2 ./case-0.sh 2>prog-0-stderr.txt

如果这个解释是正确的,我担心 case-2.sh 比预期效果更好(即 prog-2-stdout.txt 最终得到正确的输出)只是巧合,有与并发事件的相对时间有关。


现在,终于,我的问题是:

Q: SLURM gua运行tee prog-2-stdout.txt 文件包含指定任务生成的输出(即打印date to stdout) 当 >prog-2-stdout.txt 重定向被非指定任务之一评估时不会被破坏?

您对 srun 的工作原理有误解。在案例 1 中,srun 的使用无关紧要,因为它在批处理脚本中用于启动并行作业。在案例 1 中你只有一项任务,所以

srun ./prog-1.sh >prog-1-stdout.txt 等同于:

./prog-1.sh >prog-1-stdout.txt

案例 2 不同,因为您有不止一项任务。在这种情况下,srun -l ./prog-2.sh >prog-2-stdout.txt 只计算一次,srun 将负责产生 10*10 个任务。 srun会将所有task的输出重定向到job的master节点,它会写入prog-2-stdout.txt.

因此您可以确定在这种情况下不会破坏输出文件,因为它只被计算一次。