如何从串行Python脚本中调用mpi4py应用程序

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程序,这些程序未必完全设计为并行运行。
2个回答

7

这是确实可能的,mpi4py文档中有关于动态进程管理的说明。你需要的是所谓的Spawn功能,在使用Windows时,MSMPI不支持该功能,请参见MSMPI未实现Spawn

示例

第一个文件提供了一种包装器,以隐藏所有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}')

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

child.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)

0

很遗憾,我认为这是不可能的,因为你必须使用mpirun特定地运行MPI代码。

最好的办法是编写通用的代码块,在MPI进程或普通python进程中都可以调用它们。

唯一的其他解决方案是将您的整个MPI代码封装成外部调用,并在非MPI代码中使用子进程调用它,但这将与您的系统配置紧密耦合,而且并不是那么易于移植。

本主题详细介绍了子进程 Using python with subprocess Popen,值得一看,复杂性在于首先进行正确的调用,即

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

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

很抱歉我不能给您一个简单的解决方案。


谢谢,现在,如何在非MPI代码中调用子进程?你有什么想法或例子吗? - ljofre
更新答案,包括一些关于子进程的信息,但我觉得你可能无法使用它制作出可移植的东西。祝你好运。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接