如何让Slurm作业在任意指定依赖作业完成后启动?
Slurm 实现“任意一个依赖作业完成即启动”的需求
Slurm原生的afterany依赖模式确实容易误导人——它的“any”指的是依赖作业的任意状态(成功、失败、取消等),但要求所有依赖作业都完成后才会启动目标作业,和你想要的“任意一个依赖完成就启动”完全不是一回事。
目前Slurm没有直接支持这种需求的原生依赖参数,但可以通过两种方式实现:
方法一:监控脚本动态移除依赖
先提交目标作业,给它设置包含所有依赖作业的
afterany依赖:sbatch --dependency=afterany:JOB_ID1:JOB_ID2 your_target_job.sh记录下目标作业的ID(比如
TARGET_JOB_ID)。写一个监控脚本,实时检查每个依赖作业的状态,一旦发现有一个完成(无论状态),就移除目标作业的依赖,让它立即启动:
#!/bin/bash TARGET_JOB=$1 shift DEPENDENCY_JOBS=("$@") while true; do for job in "${DEPENDENCY_JOBS[@]}"; do # 获取作业当前状态,只取第一行的有效状态 STATE=$(sacct -j "$job" --format=State --noheader | head -n1 | xargs) # 判断作业是否已完成(包括成功、失败、取消、节点故障等) if [[ "$STATE" =~ ^(COMPLETED|FAILED|CANCELLED|NODE_FAIL)$ ]]; then echo "依赖作业 $job 已完成,解除目标作业 $TARGET_JOB 的依赖" scontrol update job="$TARGET_JOB" dependency=none exit 0 fi done sleep 30 # 每隔30秒检查一次,可根据需要调整 done运行脚本,传入目标作业ID和所有依赖作业ID:
./monitor_deps.sh TARGET_JOB_ID JOB_ID1 JOB_ID2
方法二:用中间转发作业触发启动
先提交目标作业,给它设置一个临时占位依赖(用不存在的作业ID,确保它不会自动启动):
sbatch --dependency=afterany:999999 your_target_job.sh TARGET_JOB=$(squeue -u "$USER" --format=%i --noheader | grep -E "^[0-9]+$" | tail -n1)为每个依赖作业创建“转发”脚本,比如针对
JOB_ID1的trigger_job1.sh:#!/bin/bash #SBATCH --dependency=afterany:JOB_ID1 #SBATCH --mem=100M #SBATCH --time=1:00 scontrol update job="$TARGET_JOB" dependency=none这个转发作业会在
JOB_ID1完成后执行,核心操作就是移除目标作业的依赖。为每个依赖作业提交对应的转发作业:
sbatch trigger_job1.sh sbatch trigger_job2.sh这样只要任意一个依赖作业完成,对应的转发作业就会触发目标作业启动,其他未完成的依赖作业不再产生影响。
内容的提问来源于stack exchange,提问作者Pheidippides
相关产品推荐
相关产品推荐

