我编写了一个基于MPI的C代码,用于并行执行数值模拟。由于我的设计很差,我在代码(数组结构,MPI-IO)中内置了一些固有的MPI依赖项。这意味着如果我想以串行方式运行我的代码,我必须调用
OUTER APPLY
主要问题 我在Python工作流程中使用我的C代码,该工作流程在下面的循环中进行了简化。
mpiexec -n 1 c_exe
Python工作流主要用于管理,并调用执行数字密集型工作的C代码。
Python for循环中的任务是独立的,因此我想采用一种令人尴尬的并行方案来并行化循环事件。基准测试表明,并行化事件的循环将比具有并行MPI调用的串行循环更快。此外,我在PBS-Torque集群上运行它。
我对如何有效地做到这一点感到茫然。由于MPI调用我的C代码和分配多个MPI任务,似乎出现了复杂情况。
我尝试过某种形式的事情
pbsdsh的封装 - 导致处理器分配出现问题。
MPMD与mpiexec - 理论上做了我想要的但失败了因为所有进程似乎共享MPI_COMM_WORLD。我的C代码为基于域的并行性建立了一个笛卡尔拓扑;这里出现了冲突。
有没有人建议我如何以令人尴尬的平行方式实现部署?理想情况下,我想提交工作申请
import os
import subprocess
homedir = os.getenv('PBS_O_WORKDIR')
nevents = 100
for ievent in range(nevents):
perform_workflow_management()
os.chdir(ievent)
subprocess.call('mpiexec -n 1 c_exe', Shell=True)
os.chdir(homedir)
其中N是处理器的数量。在每个进程中,我希望能够向我的C代码提交独立的mpiexec调用。
我知道问题的一部分归咎于设计缺陷,但如果我能找到一个解决方案而不必重构大部分代码,那将是有利的。
答案 0 :(得分:2)
首先,使用任何体面的MPI实现,您不必使用mpiexec
来启动单例MPI作业 - 只需运行可执行文件(MPI标准,§10.5.2Singleton MPI_INIT)。它至少适用于Open MPI和MPICH系列。
其次,任何体面的DRM(分布式资源管理器,a.k.a。批处理排队系统)都支持阵列作业。这些是DRM相当于SPMD - 具有相同作业文件的多个作业。
要使用Torque获取阵列作业,请在命令行或作业脚本中传递qsub
-t from-to
选项:
#PBS -t 1-100
...
然后,在Python脚本中获取PBS_ARRAYID
环境变量的值,并使用它来区分不同的实例:
import os
import subprocess
homedir = os.getenv('PBS_O_WORKDIR')
ievent = os.getenv('PBS_ARRAYID')
perform_workflow_management()
os.chdir(ievent)
subprocess.call('./c_exe', Shell=True)
os.chdir(homedir)
正如@Zulan已经提到的,这允许作业调度程序通过回填更好地利用集群的资源(如果您的Torque实例与Maui或类似的高级调度程序配对)。
阵列作业的优势在于,虽然从您的角度来看,它们看起来和工作(大多数情况下)就像一个作业,但调度程序仍然将它们视为单独的作业并单独安排它们。
这种方法的一个可能的缺点是,如果作业是专门安排的,即没有两个作业可以共享一个计算节点,那么利用率将非常低,除非您的集群节点每个只有一个单核CPU(非常不可能)现今)。