我有一个脚本,用于使用 qsub 向我们的集群提交多个作业。qsub 通常采用以下形式提交作业
qsub [qsub options] job
在我的工作中,作业通常是一个 bash (.sh) 或 python 脚本 (.py),它实际调用要在每个节点上运行的程序或代码。如果我想提交一个名为“test_job.sh”的作业,并且最长挂载时间,我会这样做
qsub -l walltime=72:00:00 test_job.sh
这相当于以下python代码
from subprocess import call
qsub_call = "qsub -l walltime=72:00:00 %s"
call(qsub_call % "test_job.sh", shell=True)
或者,如果您的 bash 脚本看起来像
#!/bin/bash
filename="your_filename_here"
ifort -openmp ran_numbers.f90 $filename ompscmf.f90 -o scmf.o
然后通过提交qsub job.sh
?
编辑:老实说,最佳作业排队方案因集群而异。简化作业提交脚本的一种简单方法是找出每个节点上可用的 CPU 数量。一些较新的排队系统允许您提交许多单 CPU 作业,它们将在尽可能少的节点上一起提交这些作业;但是,一些较旧的集群不会这样做,并且不赞成提交许多单独的作业。
假设集群中的每个节点都有 8 个 CPU。你可以写你的脚本
#!/bin/bash
#PBS -l nodes=1;ppn=8
for ((i=0; i<8; i++))
do
./myjob.sh filename_${i} &
done
wait
这将做的是一次在一个节点上提交 8 个作业(&
意味着在后台执行)并等待所有 8 个作业完成。这对于每个节点有很多 CPU 的集群可能是最佳的(例如,我使用的一个集群每个节点有 48 个 CPU)。
或者,如果提交许多单核作业是最佳的并且您上面的提交代码不起作用,您可以使用 python 生成 bash 脚本以传递给 qsub。
#!/usr/bin/env python
import os
from subprocess import call
bash_lines = ['#!/bin/bash\n', '#PBS -l nodes=1;ppn=1\n']
bash_name = 'myjob_%i.sh'
job_call = 'ifort -openmp ran_numbers.f90 %s ompscmf.f90 -o scmf.o &\n'
qsub_call = 'qsub myjob_%i.sh'
filenames = [os.path.join(root, f) for root, _, files in os.walk(directory)
for f in files if f.endswith('.txt')]
for i, filename in enumerate(filenames):
with open(bash_name%i, 'w') as bash_file:
bash_file.writelines(bash_lines + [job_call%filename, 'wait\n'])
call(qsub_call%i, shell=True)