简体   繁体   English

使用mpi4py在脚本内调用子进程

[英]Calling a subprocess within a script using mpi4py

I'm having trouble calling an external program from my python script in which I want to use mpi4py to distribute the workload among different processors. 我无法从python脚本调用外部程序,在该脚本中我想使用mpi4py在不同处理器之间分配工作负载。

Basically, I want to use my script such that each core prepares some input files for calculations in separate folders, then starts an external program in this folder, waits for the output, and then, finally, reads the results and collects them. 基本上,我想使用我的脚本,以便每个内核在单独的文件夹中准备一些输入文件以进行计算,然后在此文件夹中启动一个外部程序,等待输出,最后读取结果并收集它们。

However, I simply cannot get the external program call to work. 但是,我根本无法使外部程序调用正常工作。 On my search for a solution to this problem I've found that the problems I'm facing seem to be quite fundamental. 在寻找该问题的解决方案时,我发现我所面临的问题似乎非常根本。 The following simple example makes this clear: 以下简单示例清楚地表明了这一点:

#!/usr/bin/env python
import subprocess

subprocess.call(“EXTERNAL_PROGRAM”, shell=True)
subprocess.call(“echo test”, shell=True)

./script.py works fine (both calls work), while mpirun -np 1 ./script.py only outputs test . ./script.py可以正常工作(两个调用都可以),而mpirun -np 1 ./script.py仅输出test Is there any workaround for this situation? 有这种情况的解决方法吗? The program is definitely in my PATH, but it also fails if I use the abolute path for the call. 该程序肯定在我的PATH中,但是如果我使用abolute路径进行调用,它也会失败。

This SO question seems to be related, sadly there are no answers... 这个问题似乎有关,可惜没有答案...

EDIT: 编辑:

In the original version of my question I've not included any code using mpi4py, even though I mention this module in the title. 在我的问题的原始版本中,即使我在标题中提到了此模块,我也没有使用mpi4py包含任何代码。 So here is a more elaborate example of the code: 因此,这是一个更详细的代码示例:

#!/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()

Unfortunately I cannot provide more details of the external executable EXTERNAL_PROGRAM other than that it is a C++ application which is MPI enabled. 不幸的是,除了它是启用了MPI的C ++应用程序之外,我无法提供外部可执行文件EXTERNAL_PROGRAM的更多详细信息。 As written in the comment section below, I suspect that this is the reason (or one of the resons) why my external program call is basically ignored. 如下面注释部分所述,我怀疑这是基本上忽略我的外部程序调用的原因(或原因之一)。

Please note that I'm aware of the fact that in this situation, nobody can reproduce my exact situation. 请注意,我知道在这种情况下没有人能够重现我的确切情况。 Still, however, I was hoping that someone here already ran into similar problems and might be able to help. 但是,我仍然希望这里的某个人已经遇到类似的问题,并且可能能够提供帮助。

For completeness, the OS is Ubuntu 14.04 and I'm using OpenMPI 1.6.5. 为了完整起见,该操作系统为Ubuntu 14.04,我使用的是OpenMPI 1.6.5。

In your first example you might be able to do this: 在第一个示例中,您可以执行以下操作:

#!/usr/bin/env python
import subprocess

subprocess.call(“EXTERNAL_PROGRAM && echo test”, shell=True)

The python script is only facilitating the MPI call. python脚本仅用于MPI调用。 You could just as well write a bash script with command “EXTERNAL_PROGRAM && echo test” and mpirun the bash script; 您也可以使用命令“ EXTERNAL_PROGRAM && echo test”编写一个bash脚本,然后mpirun bash脚本; it would be equivalent to mpirunning the python script. 相当于mpirunning python脚本。

The second example will not work if EXTERNAL_PROGRAM is MPI enabled. 如果启用了EXTERNAL_PROGRAM,则第二个示例将不起作用。 When using mpi4py it will initialize the MPI. 使用mpi4py时,它将初始化MPI。 You cannot spawn another MPI program once you initialized the MPI environment in such a manner. 一旦以这种方式初始化MPI环境,就无法生成另一个MPI程序。 You could spawn using MPI_Comm_spawn or MPI_Comm_spawn_multiple and -up option to mpirun. 您可以使用MPIrun的MPI_Comm_spawn或MPI_Comm_spawn_multiple和-up选项生成。 For mpi4py refer to Compute PI example for spawning (use MPI.COMM_SELF.Spawn). 对于mpi4py,请参阅Compute PI示例以生成(使用MPI.COMM_SELF.Spawn)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM