抱歉,这个问题需要大量的积累,但总而言之,它是关于许多并行实例的条件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
将empty.
我的期望实现了:
% 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
将被评估after“指定工作”,即“指定工作”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.sh
与prog-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
Like 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 行,以及empty 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
is not空的。事实上,它包含一个日期:
% 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 是否保证prog-2-stdout.txt
包含指定任务生成的输出的文件(即打印日期的文件)stdout
)不会被破坏时>prog-2-stdout.txt
重定向由非指定任务之一评估?