设置分布式ipython / ipyparallel MPI群集

时间:2015-11-09 16:51:46

标签: python ipython mpi

我很难理解如何使用ipython / ipyparallel设置分布式MPI群集。我没有强大的MPI背景。

我已按照ipyparallel docs (Using ipcluster in mpiexec/mpirun mode)中的以下说明进行操作,这适用于在单个节点计算机上分配计算。因此,创建mpi配置文件,按照上述说明进行配置,然后启动集群

$ ipython profile create --parallel --profile=mpi
$ vim ~/.ipython/profile_mpi/ipcluster_config.py

然后在主机 A 上启动控制器和4个MPI引擎:

$ ipcontroller --ip='*' --profile=mpi    
$ ipcluster engines --n=4 --profile=mpi

运行以下代码段:

from ipyparallel import Client
from mpi4py import MPI

c = Client(profile='mpi')
view = c[:]

print("Client MPI.COMM_WORLD.Get_size()=%s" % MPI.COMM_WORLD.Get_size())
print("Client engine ids %s" % c.ids)

def _get_rank():
    from mpi4py import MPI
    return MPI.COMM_WORLD.Get_rank()

def _get_size():
    from mpi4py import MPI
    return MPI.COMM_WORLD.Get_size()

print("Remote COMM_WORLD ranks %s" % view.apply_sync(_get_rank))
print("Remote COMM_WORLD size %s" % view.apply_sync(_get_size))

产量

Client MPI.COMM_WORLD.Get_size()=1
Client engine ids [0, 1, 2, 3]
Remote COMM_WORLD ranks [1, 0, 2, 3]
Remote COMM_WORLD size [4, 4, 4, 4]

然后在主机 B 上启动4个MPI引擎。我再次运行代码片段,产生

Client MPI.COMM_WORLD.Get_size()=1
Client engine ids [0, 1, 2, 3, 4, 5, 6, 7]
Remote COMM_WORLD ranks [1, 0, 2, 3, 2, 3, 0, 1]
Remote COMM_WORLD size [4, 4, 4, 4, 4, 4, 4, 4]

似乎每个ipcluster命令的引擎被分组为单独的通信器或大小4,因此重复排名。并且客户只有一个MPI流程。

问题:

  1. ipython / ipyparallel似乎没有在主机之间建立MPI连接。 ipyparallel应该处理MPI设置,还是应该作为用户创建MPI设置,"IPython MPI with a Machinefile"建议?我想我的假设是ipyparallel会自动处理事情,但事实并非如此。
  2. 是否有关于如何使用ipyparallel设置分布式MPI的文档?我已经四处搜索,但没有发现任何明显的事情。
  3. 根据以上所述,ipython / ipyparallel是否仅设计用于处理本地MPI连接,以避免控制器和引擎之间的数据传输?
  4. 修改

    1. 第一个问题的答案似乎是所有MPI节点必须立即启动。这是因为:

      • Dynamic Nodes in OpenMPI表示无法在启动后添加节点。
      • MPI - Add/remove node while program is running表明了这一点 子节点可以通过 MPI_Comm_spawn 添加。但是,根据MPI_Comm_spawn

          

        MPI_Comm_spawn尝试启动maxprocs命令指定的MPI程序的相同副本,与它们建立通信并返回一个内部通信器。产生的过程称为子过程。孩子们有自己的MPI_COMM_WORLD,与父母的分开

        快速浏览ipyparallel代码表明此功能尚未使用。

    2. 第二个问题的部分答案是需要使用机器文件,以便MPI知道它可以在哪些远程机器上创建进程。

      这里的含义是每个遥控器上的设置是 homogenous ,由Torque / SLURM等集群系统提供。否则,如果一个人试图使用随机遥控器,那么就是必须做的工作是确保mpiexec正在执行的环境是同质的。

    3. 第三个问题的部分答案是否定的,ipyparallel可能适用于远程MPI进程,但每个MPI进程需要创建一个ipyparall引擎。

1 个答案:

答案 0 :(得分:3)

当您在IPython并行启动MPI引擎时,它最终归结为一次调用:

mpiexec [-n N] ipengine

没有配置MPI。如果您在不同的主机上启动多组引擎,则每个组都将位于其自己的MPI Universe中,这就是您所看到的。首先要做的是确保在将IPython并行之前,只需调用一次mpiexec就可以正常工作。

IPython parallel with a machine file中所述,要使用多主机MPI,通常需要一个机器文件来指定在多个主机上启动多个引擎。例如:

# ~/mpi_hosts
machine1 slots=4
machine2 slots=4

您可以使用简单的测试脚本进行诊断:

# test_mpi.py
import os
import socket
from mpi4py import MPI

MPI = MPI.COMM_WORLD

print("{host}[{pid}]: {rank}/{size}".format(
    host=socket.gethostname(),
    pid=os.getpid(),
    rank=MPI.rank,
    size=MPI.size,
))

运行它:

$ mpiexec -machinefile ~/mpi_hosts -n 8 python test_mpi.py 
machine1[32292]: 0/8
machine1[32293]: 1/8
machine1[32294]: 2/8
machine1[32295]: 3/8
machine2[32296]: 4/8
machine2[32297]: 5/8
machine2[32298]: 6/8
machine2[32299]: 7/8

一旦按预期工作,您可以添加

c.MPILauncher.mpi_args = ["-machinefile", "~/mpi_hosts"]

~/.ipython/profile_default/ipcluster_config.py并使用

启动引擎
ipcluster start -n 8