mpi4py 中的全发散操作

本文详细介绍了mpi4py中的全发散操作,包括方法接口和例程。全发散操作分为对组内和组间通信子的操作,涉及alltoall、Alltoall、Alltoallv和Alltoallw等方法,支持不同长度和类型的数据传输。通过设置缓冲区、计数、偏移和数据类型,实现灵活的数据交换。

本文从本人简书博客同步过来

上一篇中我们介绍了 mpi4py 中的规约发散操作方法,下面我们将介绍全发散操作。

对组内通信子上的全发散操作,组内所有进程都会执行散发操作,并从所有进程接收数据。

对组间通信子上的全发散操作,假定相关联的组为 group A 和 group B,group A 中的所有进程都会向 group B的各个进程散发消息,同时 group B 的各个进程也会向 group A 的各个进程散发消息。要求 group A 中进程 i 发送缓冲区的第 j 个位置,必须与 group B 中进程 j 接收缓冲区的第 i 个位置匹配;反之亦然。从 group A 到 group B 两个方向上传输的数据可以不对称,甚至在一个方向上传输的数据可以为 0。

方法接口

mpi4py 中的全发散操作的方法(MPI.Comm 类的方法)接口为:

alltoall(self, sendobj)

Alltoall(self, sendbuf, recvbuf)
Alltoallv(self, sendbuf, recvbuf)
Alltoallw(self, sendbuf, recvbuf)

以小写字母开头的 alltoall 可以全发散一系列可被 pickle 系列化的 Python 对象 sendobj注意:对组内通信子上的该操作,系列长度是组内的进程数 size,而对组间通信子上的该操作,系列长度应是另一组的进程数目,以保证散发的消息可被顺利接收。

以大写字母开头的 Alltoall 只能全发散具有单段缓冲区接口的类数组对象,如 numpy 数组。参数 sendbuf/recvbuf 可以是一个长度为2或3的 list 或 tuple,类似于 [data, MPI.DOUBLE],或者 [data, count, MPI.DOUBLE],以指明发送/接收数据缓冲区,数据计数以及数据类型。当 count 省略时会利用 data 的字节长度和数据类型计算出对应的 count。对 numpy 数组,其计数和数据类型可以自动推断出来,因此可以直接以 data 作为参数传给 sendbuf/recvbuf

Alltoall 只能散发长度相同的数据量,而 Alltoallv 则可散发不同长度的数据量,为此需要设置发散缓冲区的偏移索引和发送数量数组,以及接收缓冲区的偏移索引和接收数量数组。具体来说,sendbuf/recvbuf 要设置成类似于 [data, count, displ, MPI.DOUBLE], 其中 countdispl 都是一个整数系列,count 指明各个进程发送/接收的数据个数,displ 指明各个进程的数据段在发送/接收数据缓冲区中的起始偏离。因为要求进程 i 发送缓冲区的第 j 个位置必须与进程 j 接收缓冲区的第 i 个位置匹配,反之亦然,所以发送缓冲区的计数排列成的矩阵与接收缓冲区的计数排列成的矩阵应该互为转置矩阵。

Alltoallw 是对 Alltoallv 的进一步扩展,不仅可以发送不同长度的数据,还可以发送不同类型的数据,为此,它的参数 send_buf/recv_buf 需要分别指定发送/接收数据缓冲区,通信数据量数组,偏移信息数组和数据类型数组。注意:与 Alltoallv 不同的是,它的发送/接收数据偏移以字节为单位指定。因为要求进程 i 发送缓冲区的第 j 个位置必须与进程 j 接收缓冲区的第 i 个位置匹配,反之亦然,所以发送缓冲区的计数排列成的矩阵与接收缓冲区的计数排列成的矩阵应该互为转置矩阵,同时发送缓冲区的数据类型排列成的矩阵与接收缓冲区的数据类型排列成的矩阵应该互为转置矩阵。

对组内通信子对象的 Alltoall,Alltoallv 和 Alltoallw,可以将其 sendbuf 参数设置成 MPI.IN_PLACE,此时 recvbuf 将既作为发送缓冲区,又作为接收缓冲区。因为要求进程 i 发送缓冲区的第 j 个位置必须与进程 j 接收缓冲区的第 i 个位置匹配,反之亦然,所以缓冲区的计数排列成的矩阵以及数据类型排列成的矩阵都应该是对称的。

例程

下面给出全发散操作的使用例程。

# alltoall.py

"""
Demonstrates the usage of alltoall, Alltoall, Alltoallv, Alltoallw.

Run this with 4 processes like:
$ mpiexec -n 4 python alltoall.py
"""

import numpy as np
from mpi4py import MPI


comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# ------------------------------------------------------------------------------
# alltoall
send_obj = [1.2, 'xy', {
  
  'a': 1}, (2,)]
recv_obj = comm.alltoall(send_obj)
print 'alltoall: rank %d has %s' % (rank, recv_obj)


# ------------------------------------------------------------------------------
# Alltoall
send_buf = np.arange(4, dtype='i')
recv_buf = np.empty(4, dtype='i')
comm.Alltoall(send_buf, recv_buf)
print 'Alltoall: rank %d has %s' % (rank, recv_buf)


# ------------------------------------------------------------------------------
# Alltoall with MPI.IN_PLACE
recv_buf = np.arange(4, dtype='i')
comm.Alltoall(MPI.IN_PLACE, recv_buf)
print 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值