在调用slurm sbatch之前为日志文件创建目录

时间:2019-01-25 17:32:58

标签: bash slurm

Slurm sbatch将stdout和stderr定向到-o-e标志指定的文件,但是如果文件路径包含不存在的目录,则无法这样做。有什么方法可以自动为我的日志文件创建目录?

  • 每次手动创建这些目录的效率都很低,因为我要运行每个批处理提交数十次。
  • 让作业名称的变化形式存在于文件名而不是目录中,这会导致大量混乱,组织混乱的日志,当我需要检查作业的执行情况时必须对其进行整理。

我发现执行此操作的唯一方法是将对sbatch的调用包装在bash脚本中,该脚本的时间比看起来这么小的事情所需要的时间长很多倍。我在下面提供了一个简化的示例。

#!/bin/bash
# Set up and run job array for my_script.py, which takes as positional
# arguments a config file (passed via $1) and an array index.

#SBATCH --array=1-100
#SBATCH -n 1
#SBATCH -t 12:00:00
#SBATCH -p short
#SBATCH -J sim_sumstats
#SBATCH --mem=1600

# Initialize variables used for script control flow
sub_or_main='sub'

# Parse options
while getopts ":A" opt; do
    case $opt in
        A)
            sub_or_main='main'
            ;;
        \?)
            # Capture invalid options
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done

shift $((OPTIND - 1))

# Either run the submit script or the main array
if [ $sub_or_main == 'sub' ]; then
    # Submit script creates folders for log files, then calls sbatch on this
    # script in main mode.
    now=$(date +"%y%m%d-%H%M")
    name=$(basename $1 .json)
    logpath="log/my_script_name/$name/$now"
    mkdir -p $logpath
    sbatch \
        -o $logpath/%a.out \
        -e $logpath/%a.out \
        $0 -A $1
else
    # Main loop. Just calls my_script.py with the array ID.
    python ./my_script.py $1 ${SLURM_ARRAY_TASK_ID}
fi

拥有一个像这样的脚本可以工作,但是似乎非常浪费:我已经将sbatch提交脚本的长度增加了一倍以上,仅仅是为了组织日志文件。此外,其中大多数是添加的代码,这些代码在其他作业的批处理提交脚本之间将是相似的,例如调用my_script2.py等,因此会导致很多代码重复。不禁认为必须有更好的方法。

1 个答案:

答案 0 :(得分:0)

您可以在提交脚本中自行重定向Python脚本的输出,或者选择丢弃Slurm日志,或将有关该作业的有趣信息写到Slurm日志中,以用于出处跟踪和可重复性目的。

您可以这样编写一个提交脚本:

#!/bin/bash
# Set up and run job array for my_script.py, which takes as positional
# arguments a config file (passed via $1) and an array index.

#SBATCH --array=1-100
#SBATCH -n 1
#SBATCH -t 12:00:00
#SBATCH -p short
#SBATCH -J sim_sumstats
#SBATCH --mem=1600

now=$(date +"%y%m%d-%H%M")
name=$(basename $1 .json)
logpath="log/my_script_name/$name/$now"
mkdir -p $logpath
logfile="$logpath/${SLURM_ARRAY_TASK_ID}.out"

echo "Writing to ${logfile}"
scontrol show -dd job $SLURM_JOB_ID
printenv

python ./my_script.py $1 ${SLURM_ARRAY_TASK_ID} > ${logfile}

这样,Python脚本的输出将在您需要的位置,并且在创建日志文件之前将创建父目录。

此外,您将拥有Slurm创建的标准输出文件,具有默认的命名方案,其中包含有关作业的信息(来自scontrol和来自环境的信息(带有printenv)。

但是,如果要防止Slurm尝试创建输出文件,请设置--output=/dev/null