SLURM 中两个作业数组之间的一对一依赖关系
one-to-one dependency between two job arrays in SLURM
服务器刚刚从 CONDOR 切换到 SLURM,所以我正在学习并尝试将我的提交脚本转换为 SLURM。
我的问题如下,我有两个作业数组。第二个依赖于第一个。目前,我是这样的
events1=$(sbatch --job-name=events --array=1-3 --output=z-events-%a.stdout myfirst.sh)
jobid_events1=`echo ${events1} | sed -n -e 's/^.*job //p' `
echo "The job ID of the events is "${jobid_events1}
postevents1=$(sbatch --job-name=postevents --dependency=afterany:${jobid_events1} --array=1-3 mysecond.sh)
jobid_postevents1=`echo ${postevents-cftables1} | sed -n -e 's/^.*job //p' `
echo "The job ID post-event calculations is "${jobid_postevents1}
此处第二个作业数组 postevents1 仅在第一个作业数组 events1 中的每个元素完成后才开始。但是,我确实想要的是第二个作业数组的第 i 个元素仅取决于第一个作业的第 i 个元素数组(实际上,两个数组的大小总是相同的)。我知道这可以通过在 CONDOR 的情况下使用 DAG 来完成。
我意识到我可以手动打破第二个作业数组并单独进行匹配。但是,由于我必须打破第二个作业数组,如果第三个作业依赖于第二个作业数组的所有元素,这对我来说会变得越来越不方便。
编辑:根据damienfrancois的回答,关键字aftercorr是我正在寻找。我有一个后续问题。
尽管乍一看,"complete successfully" 确实很有道理。但是,如果其中一个任务(在第一个作业数组中)没有成功完成,是否必须手动删除第二个数组中的相应任务?如果是这样,使它变得复杂的是,如果第一个作业数组中的任何任务失败,则依赖于部分完成第二个作业数组的任务的任何进一步作业都将挂在那里(这在我的实践中很常见).在这种情况下,如何实现 "afterany" 选项?
非常感谢!
从版本 16.05 开始,Slurm 有一个选项 --dependency=aftercorr:job_id[:jobid...]
A task of this job array can begin execution after the corresponding
task ID in the specified job has completed successfully (ran to
completion with an exit code of zero).
它满足您的需求。
但是它有你描述的缺点;如果第一个数组中的相应作业崩溃,第二个数组中的作业将无限期地等待。你有几个行动方案,none 其中最完美的是:
如果可以从提交脚本中检测到作业崩溃,并且崩溃是随机的,您可以简单地使用 scontrol requeue $SLURM_JOB_ID
重新排队作业,以便它再次运行。
否则,您可以在第二个数组中的作业末尾添加一段 Bash 代码,用于检查第一个数组中的作业是否仍在排队,如果没有,则取消第二个数组中的所有剩余作业;像这样的东西(未经测试)
[[ $(squeue --noheader --name events | wc -l) == 0 ]] && scancel $SLURM_JOB_ID
最后,最后一个选择是使用成熟的工作流系统。有关简短介绍和指示,请参阅 this。
服务器刚刚从 CONDOR 切换到 SLURM,所以我正在学习并尝试将我的提交脚本转换为 SLURM。
我的问题如下,我有两个作业数组。第二个依赖于第一个。目前,我是这样的
events1=$(sbatch --job-name=events --array=1-3 --output=z-events-%a.stdout myfirst.sh)
jobid_events1=`echo ${events1} | sed -n -e 's/^.*job //p' `
echo "The job ID of the events is "${jobid_events1}
postevents1=$(sbatch --job-name=postevents --dependency=afterany:${jobid_events1} --array=1-3 mysecond.sh)
jobid_postevents1=`echo ${postevents-cftables1} | sed -n -e 's/^.*job //p' `
echo "The job ID post-event calculations is "${jobid_postevents1}
此处第二个作业数组 postevents1 仅在第一个作业数组 events1 中的每个元素完成后才开始。但是,我确实想要的是第二个作业数组的第 i 个元素仅取决于第一个作业的第 i 个元素数组(实际上,两个数组的大小总是相同的)。我知道这可以通过在 CONDOR 的情况下使用 DAG 来完成。
我意识到我可以手动打破第二个作业数组并单独进行匹配。但是,由于我必须打破第二个作业数组,如果第三个作业依赖于第二个作业数组的所有元素,这对我来说会变得越来越不方便。
编辑:根据damienfrancois的回答,关键字aftercorr是我正在寻找。我有一个后续问题。
尽管乍一看,"complete successfully" 确实很有道理。但是,如果其中一个任务(在第一个作业数组中)没有成功完成,是否必须手动删除第二个数组中的相应任务?如果是这样,使它变得复杂的是,如果第一个作业数组中的任何任务失败,则依赖于部分完成第二个作业数组的任务的任何进一步作业都将挂在那里(这在我的实践中很常见).在这种情况下,如何实现 "afterany" 选项?
非常感谢!
从版本 16.05 开始,Slurm 有一个选项 --dependency=aftercorr:job_id[:jobid...]
A task of this job array can begin execution after the corresponding task ID in the specified job has completed successfully (ran to completion with an exit code of zero).
它满足您的需求。
但是它有你描述的缺点;如果第一个数组中的相应作业崩溃,第二个数组中的作业将无限期地等待。你有几个行动方案,none 其中最完美的是:
如果可以从提交脚本中检测到作业崩溃,并且崩溃是随机的,您可以简单地使用
scontrol requeue $SLURM_JOB_ID
重新排队作业,以便它再次运行。否则,您可以在第二个数组中的作业末尾添加一段 Bash 代码,用于检查第一个数组中的作业是否仍在排队,如果没有,则取消第二个数组中的所有剩余作业;像这样的东西(未经测试)
[[ $(squeue --noheader --name events | wc -l) == 0 ]] && scancel $SLURM_JOB_ID
最后,最后一个选择是使用成熟的工作流系统。有关简短介绍和指示,请参阅 this。