You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Slurm数组添加例外:仅在全部任务完成后执行单次命令

Slurm数组任务完成后仅执行一次删除命令的解决方案

给你两种可行的方案,能把删除命令整合到同一个脚本里,避免每个数组任务都执行删除:

方案一:嵌套提交依赖清理任务(推荐)

思路是让脚本自己判断运行状态:如果是首次执行(不是数组任务),就先提交整个数组任务,再提交一个依赖于数组全部成功完成的清理任务;如果是数组任务,就执行原本的处理逻辑。

修改后的完整脚本:

#!/bin/bash

# 数组任务的Slurm配置(只有用sbatch提交时才生效)
#SBATCH -A XXX-CPU
#SBATCH --mail-type=BEGIN,END,FAIL
#SBATCH -p cclake
#SBATCH -D analyses/
#SBATCH -c 12
#SBATCH -t 01:00:00
#SBATCH --mem=10G
#SBATCH -J splitBAM
#SBATCH -a 1-12
#SBATCH -o analyses/splitBAM_%a.log

# 如果当前是数组任务,执行原有处理逻辑
if [ -n "$SLURM_ARRAY_TASK_ID" ]; then
    sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands1.csv | bash
    sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands2.csv | bash
    sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands3.csv | bash
else
    # 首次执行脚本,提交数组任务并获取Job ID
    ARRAY_JOB_ID=$(sbatch --parsable "$0")
    echo "数组任务已提交,Job ID: $ARRAY_JOB_ID"
    
    # 提交依赖于数组全部成功完成的清理任务
    sbatch --dependency=afterok:$ARRAY_JOB_ID \
           -A XXX-CPU \
           -p cclake \
           -D analyses/ \
           -c 1 \
           -t 00:05:00 \
           --mem=1G \
           -J cleanup_splitBAM \
           -o analyses/cleanup_splitBAM.log \
           << 'EOF'
#!/bin/bash
rm file1 file2 file3
EOF
fi

使用方式:直接在终端运行这个脚本(不用加sbatch),它会自动提交数组任务和后续的清理任务。清理任务会在所有数组任务成功完成后才执行。

方案二:用任务标记文件触发清理

思路是每个数组任务完成后创建一个标记文件,最后由某个任务检查所有标记文件是否存在,只有全部存在时才执行删除。注意:这种方法依赖文件系统一致性,适合简单场景,可靠性不如方案一。

修改后的脚本:

#!/bin/bash

#SBATCH -A XXX-CPU
#SBATCH --mail-type=BEGIN,END,FAIL
#SBATCH -p cclake
#SBATCH -D analyses/
#SBATCH -c 12
#SBATCH -t 01:00:00
#SBATCH --mem=10G
#SBATCH -J splitBAM
#SBATCH -a 1-12
#SBATCH -o analyses/splitBAM_%a.log

# 执行原有数组任务逻辑
sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands1.csv | bash
sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands2.csv | bash
sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands3.csv | bash

# 创建当前任务完成的标记文件
touch ".task_${SLURM_ARRAY_TASK_ID}_done"

# 检查所有任务的标记文件是否都存在
TOTAL_TASKS=12
ALL_FINISHED=1
for i in $(seq 1 $TOTAL_TASKS); do
    if [ ! -f ".task_${i}_done" ]; then
        ALL_FINISHED=0
        break
    fi
done

# 如果所有任务都完成,执行删除并清理标记文件
if [ $ALL_FINISHED -eq 1 ]; then
    rm file1 file2 file3
    rm .task_*.done
fi

使用方式:直接用sbatch提交这个脚本即可。如果某个数组任务失败,对应的标记文件不会创建,删除操作就不会执行,符合你原本依赖afterok的需求。


内容的提问来源于stack exchange,提问作者justinian482

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:45:42