我无法从我的python脚本调用外部程序,我想在其中使用mpi4py在不同处理器之间分配工作负载。
基本上,我想使用我的脚本,以便每个核心准备一些输入文件以便在单独的文件夹中进行计算,然后在此文件夹中启动外部程序,等待输出,然后最后读取结果并收集它们
但是,我根本无法让外部程序调用工作。在我寻找这个问题的解决方案时,我发现我遇到的问题似乎是非常根本的。以下简单示例清楚地表明了这一点:
#!/usr/bin/env python
import subprocess
subprocess.call(“EXTERNAL_PROGRAM”, shell=True)
subprocess.call(“echo test”, shell=True)
./script.py
工作正常(两次调用均有效),而mpirun -np 1 ./script.py
仅输出test
。这种情况有没有解决方法?该程序肯定在我的PATH中,但如果我使用该通道的绝对路径,它也会失败。
This SO question seems to be related, sadly there are no answers...
修改
在我的问题的原始版本中,我没有包含使用mpi4py的任何代码,即使我在标题中提到了这个模块。所以这里是一个更详细的代码示例:
#!/usr/bin/env python
import os
import subprocess
from mpi4py import MPI
def worker(parameter=None):
"""Make new folder, cd into it, prepare the config files and execute the
external program."""
cwd = os.getcwd()
dir = "_calculation_" + parameter
dir = os.path.join(cwd, dir)
os.makedirs(dir)
os.chdir(dir)
# Write input for simulation & execute
subprocess.call("echo {} > input.cfg".format(parameter), shell=True)
subprocess.call("EXTERNAL_PROGRAM", shell=True)
# After the program is finished, do something here with the output files
# and return the data. I'm using the input parameter as a dummy variable
# for the processed output.
data = parameter
os.chdir(cwd)
return data
def run_parallel():
"""Iterate over job_args in parallel."""
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
# Here should normally be a list with many more entries, subdivided
# among all the available cores. I'll keep it simple here, so one has
# to run this script with mpirun -np 2 ./script.py
job_args = ["a", "b"]
else:
job_args = None
job_arg = comm.scatter(job_args, root=0)
res = worker(parameter=job_arg)
results = comm.gather(res, root=0)
print res
print results
if __name__ == '__main__':
run_parallel()
不幸的是,我不能提供外部可执行文件EXTERNAL_PROGRAM的更多细节,除了它是一个启用了MPI的C ++应用程序。如下面的评论部分所述,我怀疑这是为什么我的外部程序调用基本上被忽略的原因(或其中一个原因)。
请注意,我知道在这种情况下,没有人可以重现我的确切情况。但是,我仍然希望有人在这里遇到过类似的问题并且可以提供帮助。
为完整起见,操作系统是Ubuntu 14.04,我使用的是OpenMPI 1.6.5。
答案 0 :(得分:1)
在您的第一个示例中,您可以这样做:
#!/usr/bin/env python
import subprocess
subprocess.call(“EXTERNAL_PROGRAM && echo test”, shell=True)
python脚本只是为了方便MPI调用。您也可以使用命令“EXTERNAL_PROGRAM&& amp; echo test“和mpirun bash脚本;它等同于mpirunning python脚本。
如果EXTERNAL_PROGRAM启用了MPI,则第二个示例将不起作用。使用mpi4py时,它将初始化MPI。一旦以这种方式初始化MPI环境,就无法生成另一个MPI程序。您可以使用MPI_Comm_spawn或MPI_Comm_spawn_multiple和-up选项生成mpirun。对于mpi4py,请参考Compute PI example进行生成(使用MPI.COMM_SELF.Spawn)。