【问题标题】:Calling a subprocess within a script using mpi4py使用 mpi4py 在脚本中调用子进程
【发布时间】:2014-12-31 14:39:38
【问题描述】:

我无法从我的 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()

不幸的是,除了它是启用 MPI 的 C++ 应用程序之外,我无法提供有关外部可执行文件 EXTERNAL_PROGRAM 的更多详细信息。正如下面评论部分所写,我怀疑这就是我的外部程序调用基本上被忽略的原因(或其中一个原因)。

请注意,我知道在这种情况下,没有人可以重现我的确切情况。不过,我仍然希望这里有人已经遇到过类似的问题,并且可能能够提供帮助。

为了完整起见,操作系统是 Ubuntu 14.04,我使用的是 OpenMPI 1.6.5。

【问题讨论】:

  • 为什么要使用mpirun 来运行不支持mpi 的python 脚本?
  • 在我寻找一个最小的工作示例时,我可能做得过火了。但是,给定的示例仍然说明了我的问题的要点:我无法从在 MPI 环境中运行的 python 脚本调用特定的外部程序。我还没有提到的是这个外部程序本身是启用 MPI 的,所以这可能解释了我在上述子流程调用中遇到的不同行为。
  • 代码示例不完整,见how to create a minimal complete code example。我(或其他任何人)如何重现您的问题? (提供具体步骤)我没看到mpi4py用在哪里。你的环境是什么(操作系统、什么 mpi 实现、版本等)?
  • 由于这篇评论可能太长了,我已经编辑了我的原始帖子。
  • 具体问题是什么?代码如何失败?用文字来描述:你期望发生什么,而不发生什么?如果将 EXTERNAL_PROGRAM 替换为 echo abc 或 hello world mpi 程序会怎样?您的示例不是最小的,删除不需要重现问题的代码。

标签: python subprocess mpi4py


【解决方案1】:

在您的第一个示例中,您可能可以这样做:

#!/usr/bin/env python
import subprocess

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

python 脚本只是促进 MPI 调用。您也可以使用命令“EXTERNAL_PROGRAM && echo test”编写一个 bash 脚本,然后运行 ​​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)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-16
    • 2011-11-01
    • 2015-07-16
    • 1970-01-01
    • 2013-12-23
    • 2012-07-31
    • 2014-10-25
    • 1970-01-01
    相关资源
    最近更新 更多