如何让HTCondor作业利用机器全部CPU并行运行?
解决方案
针对你的需求,最直接可行的方法是通过拆分提交文件+DAGMan分组串行执行来实现,既满足单台4CPU机器并行跑4个作业,又能按组串行执行控制成本,具体步骤如下:
1. 拆分原提交文件为25个分组提交文件
因为你的提交文件是自动生成的100个独立作业,先写个简单的bash脚本把它按每4个作业一组拆分:
#!/bin/bash INPUT="my_file.sub" GROUP_SIZE=4 GROUP_COUNT=0 CURRENT_GROUP="group_${GROUP_COUNT}.sub" > "$CURRENT_GROUP" JOB_COUNT=0 while read -r LINE; do echo "$LINE" >> "$CURRENT_GROUP" if [[ "$LINE" == "queue" ]]; then ((JOB_COUNT++)) if (( JOB_COUNT % GROUP_SIZE == 0 )); then ((GROUP_COUNT++)) CURRENT_GROUP="group_${GROUP_COUNT}.sub" > "$CURRENT_GROUP" fi fi done < "$INPUT" # 删掉最后可能生成的空文件 rm -f "group_${GROUP_COUNT}.sub"
运行这个脚本后,会得到group_0.sub到group_24.sub共25个文件,每个文件包含4个作业的完整配置。
2. 给每个分组添加同机绑定配置
为了让同组的4个作业都分配到同一台4CPU机器,给每个分组文件开头加一段配置。同样用脚本批量处理:
#!/bin/bash for GROUP in group_*.sub; do # 提取分组编号 GROUP_NUM=$(echo "$GROUP" | sed 's/group_\([0-9]*\).sub/\1/') # 在文件开头插入配置 sed -i "1i +JobGroup = \"group_${GROUP_NUM}\"\nmachine_rank = (TARGET.JobGroup == MY.JobGroup)\nrequirements = (TARGET.Cpus >= 4)" "$GROUP" done
这段配置的作用:
+JobGroup标记作业所属分组machine_rank让HTCondor优先把同组作业调度到已经有同组作业的机器requirements确保只调度到至少有4个CPU的机器
3. 生成DAG文件实现分组串行
用DAGMan控制分组的执行顺序,让上一组全部完成后再启动下一组。写个脚本生成DAG文件:
#!/bin/bash DAG="run_groups.dag" > "$DAG" # 添加所有分组节点 for GROUP in group_*.sub; do GROUP_ID=$(echo "$GROUP" | sed 's/group_\([0-9]*\).sub/G\1/') echo "JOB ${GROUP_ID} ${GROUP}" >> "$DAG" done # 添加串行依赖关系 for i in {0..23}; do CURRENT="G${i}" NEXT="G$((i+1))" echo "PARENT ${CURRENT} CHILD ${NEXT}" >> "$DAG" done
4. 提交DAG作业
最后用DAGMan提交整个任务流:
condor_submit_dag run_groups.dag
备选方案(无需拆分文件)
如果你不想拆分原文件,可以用脚本给每4个作业块添加相同的+BatchID标记,然后在提交文件里添加:
MAX_JOBS_PER_BATCH = 4 BATCH_CONSTRAINT = (TARGET.BatchID == MY.BatchID)
但这种方法需要修改原文件的每4个作业块,工作量和拆分差不多,而且DAGMan的方式更直观可控。
内容的提问来源于stack exchange,提问作者kerzhy
相关产品推荐
相关产品推荐

