很抱歉,这个问题需要大量的积累,但总的来说,它是关于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.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
与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
重定向被其中一个非指定任务评估时,它会被破坏?
答案 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
。
因此,您可以确定在这种情况下,输出文件不会被删除,因为它只被评估一次。