美文网首页Python 并行计算
mpi4py 中的组间通信

mpi4py 中的组间通信

作者: 自可乐 | 来源:发表于2018-03-29 17:03 被阅读90次

    上一篇中我们介绍了 mpi4py 中的通信子管理 API, 下面我们将介绍组间通信相关方法。

    组间通信子对象在某些基于组内通信子对象的操作/访问函数中也可使用。

    访问函数

    MPI.Comm.Is_inter(self)
    

    判断当前通信子是否是组间通信子。

    MPI.Intercomm.Get_remote_size(self)
    

    返回远程组包含的进程数。

    MPI.Intercomm.Get_remote_group(self)
    

    取得当前组间通信子的远程组对象。

    构造与取消函数

    组间通信的构造函数均为阻塞操作,并且要求所有本地组和远程组都不相交,否则将导致死锁。

    MPI.Intracomm.Create_intercomm(self, int local_leader, Intracomm peer_comm, int remote_leader, int tag=0)
    

    将两个组内通信子对象合并为组间通信子对象。要求两个组内通信子的本地组和远程组交集为空。此外,还要求至少各组内选中的两个 leader 进程能够实现通信,即两个 leader 至少要共同通过一个第三方 peer 通信子知道彼此 —— 知道彼此在 peer 通信子内的 rank 值(leader 可以是物理上的同一个进程)。在静态进程实现的 MPI 环境中,MPI.COMM_WORLD 通常可作为这个第三方的 peer 通信子。最后还要求各组内其它进程都能够知道本组 leader 的信息。实际执行这个操作时,在本地组和远程组执行集合操作,再加上两个组 leader 之间的点到点通信,因此两个组内的进程必须分别提供完全相同的 local_commlocal_leader, 而对 remote_leaderlocal_leadertag 都不能使用通配符。注意local_leader 是选定的本地组的进程的 rank 编号,而 remote_leader 则是选定的远程组的进程在 peer_comm 中的 rank 编号。

    MPI.Intercomm.Merge(self, bool high=False)
    

    将两个组间通信子对象合并为组内通信子对象。要求各组内进程提供完全相同的 high 参数值。如果一个组内的所有进程指定的 high 为 True 而另一个组所有进程指定的 high 为 False,则在新的组内通信子内 True 组的进程排在 False 组的进程前面。如果两个组内进程指定的 high 值相同,则排列顺序不确定。

    下面给出组间通信的使用例程。

    # inter_comm.py
    
    import numpy as np
    from mpi4py import MPI
    
    
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    size = comm.Get_size()
    
    print 'Is MPI.COMM_WORLD a inter-communicator:', comm.Is_inter()
    
    # split comm into two new communicators according to `color`
    color = rank % 2
    comm_split = comm.Split(color=color, key=rank)
    
    if color == 0:
        # create an inter-communicator by using rank 0 of local_comm and rank 1 of MPI.COMM_WORLD
        comm_inter = comm_split.Create_intercomm(0, comm, 1, tag=12)
        if comm_inter.rank == 0:
            # rank 0 of local_comm sends a message to rank 1 of the remote_comm
            send_obj = {'a': 1}
            comm_inter.send(send_obj, dest=1, tag=1)
            print 'rank %d of comm_inter with color 0 sends %s...' % (comm_inter.rank, send_obj)
    elif color == 1:
        # create an inter-communicator by using rank 0 of local_comm and rank 0 of MPI.COMM_WORLD
        comm_inter = comm_split.Create_intercomm(0, comm, 0, tag=12)
        if comm_inter.rank == 1:
            # rank 1 of local_comm receives a message from rank 0 of the remote_comm
            recv_obj = comm_inter.recv(source=0, tag=1)
            print 'rank %d of comm_inter with color 1 receives %s...' % (comm_inter.rank, recv_obj)
    
    print 'Is comm_inter a inter_communicator:', comm_inter.Is_inter()
    
    # merge the two inter-communicators
    if color == 0:
        high = True
    elif color == 1:
        high = False
    comm_merge = comm_inter.Merge(high=high)
    print 'rank %d in MPI.COMM_WORLD -> rank %d in comm_merge' % (rank, comm_merge.rank)
    

    运行结果如下:

    $ mpiexec -n 4 python inter_comm.py
    Is MPI.COMM_WORLD a inter-communicator: False
    Is MPI.COMM_WORLD a inter-communicator: False
    Is MPI.COMM_WORLD a inter-communicator: False
    Is MPI.COMM_WORLD a inter-communicator: False
    Is comm_inter a inter_communicator: True
    rank 2 in MPI.COMM_WORLD -> rank 3 in comm_merge
    Is comm_inter a inter_communicator: True
    rank 1 in MPI.COMM_WORLD -> rank 0 in comm_merge
    rank 1 of comm_inter with color 1 receives {'a': 1}...
    Is comm_inter a inter_communicator: True
    rank 3 in MPI.COMM_WORLD -> rank 1 in comm_merge
    rank 0 of comm_inter with color 0 sends {'a': 1}...
    Is comm_inter a inter_communicator: True
    rank 0 in MPI.COMM_WORLD -> rank 2 in comm_merge
    

    上面我们介绍了 mpi4py 中的组间通信方法, 在下一篇中我们将对组及通信子做一个简短的小结。

    相关文章

      网友评论

        本文标题:mpi4py 中的组间通信

        本文链接:https://www.haomeiwen.com/subject/iqfvcftx.html