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

时间:2017-10-04 21:37:10

标签: slurm

很抱歉,这个问题需要大量的积累,但总的来说,它是关于srun ... >output_file的许多并行实例将会或者不会导致破坏的条件某些其他流程/任务产生的输出的某些流程/任务。

案例0:仅限bash(无SLURM)

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

#!/bin/bash

hostname >&2

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

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

"驱动程序"下面显示的脚本case-0.sh会生成$NJOBS个进程,所有内容都写入prog-0-stdout.txt

#!/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进行评估 "指定的作业"后,JOB_INDEX 0 {以及唯一一个将输出发送到stdout的人)已将日期写入stdout因此,这将破坏之前被指定工作重定向的任何输出"到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

这里是相应的"驱动程序"脚本,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行(按预期方式),但让我惊讶,{ {1}} 为空。实际上,它包含一个日期:

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 比预期更好的事实(即prog-2-stdout.txt以正确的输出结束)只是巧合,与并发事件的相对时间。

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

问: SLURM是否保证包含指定任务生成的输出的case-2.sh文件(即将日期打印到prog-2-stdout.txt的文件)不会当stdout重定向被其中一个非指定任务评估时,它会被破坏?

1 个答案:

答案 0 :(得分:3)

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

srun ./prog-1.sh >prog-1-stdout.txt相当于:

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

CASE 2不同,因为您有超过1个任务。在这种情况下,srun -l ./prog-2.sh >prog-2-stdout.txt仅评估一次,而srun将负责产生10 * 10个任务。 srun会将所有任务的输出重定向到作业的主节点,并且它将写入prog-2-stdout.txt

因此,您可以确定在这种情况下,输出文件不会被删除,因为它只被评估一次。