4

我试图制作一个基于 mpi4py 的库,但我想在串行 python 代码中使用它。

$ python serial_source.py

但在serial_source.py内部存在一些名为parallel_bar的函数

from foo import parallel_bar
# Can I to make this with mpi4py like a common python source code?
result = parallel_bar(num_proc = 5)

这个问题的动机是找到正确的方法来使用 mpi4py 来优化 python 中的程序,这些程序不一定设计为完全并行运行。

4

2 回答 2

6

这确实是可能的,并且在动态流程管理部分的 mpi4py 文档中。Spawn您需要的是不可用的所谓功能MSMPI(如果您使用的是 Windows),另请参阅Spawn not 在 MSMPI 中实现

例子

第一个文件为您的函数提供了一种包装器来隐藏所有 MPI 内容,我猜这是您的意图。在内部,它在 4 个新生成的进程中调用包含并行代码的“实际”脚本。

最后,您可以打开一个 python 终端并调用:

from my_prog import parallel_fun

parallel_fun()
# Hi from 0/4
# Hi from 3/4
# Hi from 1/4
# Hi from 2/4
# We got the magic number 6

my_prog.py

import sys
import numpy as np
from mpi4py import MPI

    def parallel_fun():
        comm = MPI.COMM_SELF.Spawn(
            sys.executable,
            args = ['child.py'],
            maxprocs=4)

        N = np.array(0, dtype='i')

        comm.Reduce(None, [N, MPI.INT], op=MPI.SUM, root=MPI.ROOT)

        print(f'We got the magic number {N}')

这里是带有并行代码的子文件:

孩子.py

from mpi4py import MPI
import numpy as np


comm = MPI.Comm.Get_parent()

print(f'Hi from {comm.Get_rank()}/{comm.Get_size()}')
N = np.array(comm.Get_rank(), dtype='i')

comm.Reduce([N, MPI.INT], None, op=MPI.SUM, root=0)
于 2018-04-25T12:21:06.473 回答
0

不幸的是,我认为这是不可能的,因为您必须专门使用 mpirun 运行 MPI 代码。

您可以做的最好的事情是编写可以由 MPI 进程或普通 python 进程调用的通用代码块。

唯一的其他解决方案是将代码的整个 MPI 部分包装到外部调用中,并在非 MPI 代码中使用 subprocess 调用它,但这将与您的系统配置密切相关,并且不是真正的可移植性。

子进程在这个线程Using python with subprocess Popen中有详细的说明,值得一看,这里的复杂性是首先进行正确的调用,即

command = "/your/instance/of/mpirun /your/instance/of/python your_script.py -arguments"

然后将结果返回到您的单线程代码中,这取决于大小有很多方法,但是如果您必须传回大数组数据,则类似并行 hdf5 的东西将是一个不错的选择。

对不起,我不能给你一个简单的解决方案。

于 2014-09-19T16:37:05.430 回答