如何在嵌套Slurm脚本中设置包含父子脚本名的作业名称?
解决方案
1. 父脚本主动传递作业名给子脚本
父脚本run.sh提交子脚本时,通过环境变量把自身作业名直接传给子脚本,避开子脚本读取$SLURM_JOB_NAME时拿到临时脚本名的问题:
# run.sh 内容 YEAR=2018 PARENT_JOB_NAME="run_${YEAR}" # 提交step1.sh,传递父作业名作为环境变量 sbatch --job-name="${PARENT_JOB_NAME}" --export=PARENT_JOB_NAME="${PARENT_JOB_NAME}" step1.sh # 同理提交step2.sh sbatch --job-name="${PARENT_JOB_NAME}" --export=PARENT_JOB_NAME="${PARENT_JOB_NAME}" step2.sh
2. 子脚本生成带父作业名的子作业名
在子脚本(比如step1.sh)里,用父脚本传递的环境变量结合自身脚本名生成子作业名,同时读取外部配置的Slurm选项:
# step1.sh 内容 # 加载未追踪的Slurm配置文件 source ./slurm_configs.sh # 获取当前子脚本的真实文件名 SCRIPT_NAME=$(basename "$0") # 拼接生成子作业名 CHILD_JOB_NAME="${PARENT_JOB_NAME}_${SCRIPT_NAME}" # 从配置文件读取对应Slurm选项,提交实际任务 sbatch ${STEP1_SLURM_OPTS} --job-name="${CHILD_JOB_NAME}" your_task_script.sh
3. 用未追踪配置文件统一管理Slurm选项
创建slurm_configs.sh,将其加入.gitignore(避免被Git追踪),在里面统一定义各子脚本的Slurm参数:
# slurm_configs.sh 内容 # step1.sh对应的Slurm选项 STEP1_SLURM_OPTS="--partition=compute --nodes=1 --ntasks=8 --mem=32G" # step2.sh对应的Slurm选项 STEP2_SLURM_OPTS="--partition=gpu --nodes=1 --gres=gpu:1 --mem=64G"
核心优势
- 父脚本通过
--export传递作业名,子脚本无需依赖不可靠的$SLURM_JOB_NAME环境变量; - 子脚本用
basename "$0"获取真实文件名,不会被Slurm临时脚本干扰; - 所有Slurm选项集中在未追踪的配置文件里,不用在子脚本硬编码,也不会被Git提交。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

