【问题标题】:How to Consume an mpi4py application from a serial python script如何从串行 python 脚本中使用 mpi4py 应用程序
【发布时间】:2014-10-25 10:36:14
【问题描述】:

我尝试制作一个基于 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 中的程序,这些程序不一定被设计为完全并行运行。

【问题讨论】:

    标签: python parallel-processing mpi4py


    【解决方案1】:

    这确实是可能的,并且在 Dynamic Process Management 部分的 mpi4py 文档中。您需要的是所谓的Spawn 功能,MSMPI 不具备该功能(如果您使用的是 Windows)另请参阅Spawn not implemented in 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}')
    

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

    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)
    

    【讨论】:

      【解决方案2】:

      很遗憾,我认为这是不可能的,因为您必须专门使用 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 的方法将是一个不错的选择。

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

      【讨论】:

      • 谢谢,现在,如何在非MPI代码中调用子进程?你有什么想法或例子吗?
      • 更新答案以包含有关子流程的一些信息,但我觉得您将无法使用它制作可移植的东西。不过祝你好运。
      猜你喜欢
      • 2018-03-25
      • 2016-02-03
      • 2020-10-26
      • 2017-01-01
      • 2021-03-07
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 2014-03-23
      相关资源
      最近更新 更多