问题
Sorry, this question requires a lot of build-up, but in summary, it's about the conditions under which many parallel instances of srun ... >output_file
will or won't lead to the clobbering by some process/task of the output produced by some other process/task.
CASE 0: bash only (no SLURM)
Suppose that prog-0.sh
is the following toy script:
#!/bin/bash
hostname >&2
if [[ $JOB_INDEX = 0 ]]
then
date
fi
This script prints some output to stderr
, and possibly prints the current date to stdout
.
The "driver" script case-0.sh
shown below spawns $NJOBS
processes, all writing to 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
After running
% NJOBS=100 ./case-0.sh 2>prog-0-stderr.txt
...my expectation is that prog-0-stderr.txt
will contain 100 lines, and that prog-0-stdout.txt
will be empty.
My expectation pans out:
% wc prog-0-std*.txt
100 100 3000 prog-0-stderr.txt
0 0 0 prog-0-stdout.txt
100 100 3000 total
The explanation for these results is that, when NJOBS
is sufficiently large, it is likely that, for some sufficiently high value of $i
, the redirection >prog-0-stdout.txt
will be evaluated after the "designated job", the one JOB_INDEX
0 (and the only one that sends output to stdout
) has written the date to stdout
, and this will therefore clobber whatever output was earlier redirected by the "designated job" to prog-0-stdout.txt
.
BTW, the value of NJOBS
needs to be high enough for the results to be as I've just described. For example, if I use NJOBS=2
:
% NJOBS=2 ./case-0.sh 2>prog-0-stderr.txt
...then not only will prog-0-stderr.txt
contain only 2 lines (not surprisingly), but prog-0-stdout.txt
will contain a date:
% cat prog-0-stdout.txt
Wed Oct 4 15:02:49 EDT 2017
In this case, all the >prog-0-stdout.txt
redirections have been evaluated before the designated job prints the date to prog-0-stdout.txt
.
CASE 1: SLURM job arrays
Now, consider a very similar scenario, but using SLURM instead. The script prog-1.sh
is identical to prog-0.sh
, except that it examines a different variable to decide whether or not to print the date to stdout
:
#!/bin/bash
hostname >&2
if [[ $SLURM_ARRAY_TASK_ID = 0 ]]
then
date
fi
And here's the corresponding "driver" script, 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
, this script redirects the output of its main step to a single file ./prog-1-stdout.txt
.
Importantly, this same file will be seen by all the nodes that run ./prog-1.sh
for this job.
If I now run
sbatch case-1.sh
...I get 100 files prog-1-00-stderr.txt
... prog-1-99-stderr.txt
, containing 1 line each, and an empty prog-1-stdout.txt
. I assume that the earlier explanation also explains why prog-1-stdout.txt
is empty.
So far so good.
CASE 2: SLURM tasks
Finally, consider one more SLURM-based case, this time using the core script prog-2.sh
and the driver script case-2.sh
. Again, the only change in prog-2.sh
is the variable it examines to decide whether or not to print the date to stdout
:
#!/bin/bash
hostname >&2
if [[ $SLURM_PROCID = 1 ]]
then
date
fi
And here is 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
As before, prog-2-stdout.txt
is visible by all the nodes handling the job.
Now, if I run sbatch case-2.sh
and wait for the batch job to finish, then prog-2-stderr.txt
contains 100 lines (as expected), but, to my surprise, prog-2-stdout.txt
is not empty. In fact, it contains a date:
% cat prog-2-stdout.txt
01: Wed Oct 4 15:21:17 EDT 2017
The only explanation I can come up with is analogous to the one I gave earlier for the results I got when I ran
% NJOBS=2 ./case-0.sh 2>prog-0-stderr.txt
If this explanation is correct, my concern is that the fact case-2.sh
worked better than expected (i.e. prog-2-stdout.txt ends up with the right output) is just a coincidence, having to do with the relative timing of concurrent events.
Now, at long last, my question is:
Q: does SLURM guarantee that a prog-2-stdout.txt
file that contains the output generated by the designated task (i.e. the one that prints the date to stdout
) will not be clobbered when the >prog-2-stdout.txt
redirection gets evaluated by one of the non-designated tasks?
回答1:
You have a misconception on how srun works. In CASE 1 the usage of srun is irrelevant as it's used in batch scripts to start parallel jobs. In CASE 1 you only have one task, so
srun ./prog-1.sh >prog-1-stdout.txt
is equivalent to:
./prog-1.sh >prog-1-stdout.txt
CASE 2 is different, as you have more than 1 task. In that case, srun -l ./prog-2.sh >prog-2-stdout.txt
is only evaluated once, and srun will take care of spawning 10*10 tasks. srun will redirect the output of all the tasks to the master node of the job, and it will be the one writing to prog-2-stdout.txt
.
So you can be sure that in this case there will be no clobbering of the output file as it is evaluated only once.
来源:https://stackoverflow.com/questions/46574606/on-the-semantics-of-srun-output-file-for-parallel-tasks