我在为一个项目使用MPI。我需要以非阻塞模式将包从一个节点传输到另一个节点。我用一个类来组织这个包,这个类包含我的通信逻辑的相关信息。你知道吗
我正在使用函数irecv()
进行一些测试,以获取通信请求和缓冲区,并test()
验证是否有消息到达。你知道吗
MPI缺少Python的文档,因此我检查了source code以了解更多信息,我使用的函数在哪里。你知道吗
源代码声明irecv如下:
def irecv(self, buf=None, int source=ANY_SOURCE, int tag=ANY_TAG):
"""Nonblocking receive"""
cdef MPI_Comm comm = self.ob_mpi
cdef Request request = <Request>Request.__new__(Request)
request.ob_buf = PyMPI_irecv(buf, source, tag, comm, &request.ob_mpi)
return request
我知道,如果我想把数据放在一个缓冲区,我需要设置可选参数“buf”来存储我收到的消息。你知道吗
我尝试了以下测试来了解它的工作原理:
from mpi4py import MPI
import time
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
class Package(object):
msg = [[0,1,0,1,0,1],
[0,1,0,1,0,1],
[0,1,0,1,0,1],
[0,1,0,1,0,1],
[0,1,0,1,0,1]]
gotMessage = False
destination = -1
if rank == 0:
data = Package()
comm.isend(data, dest=1, tag=11)
elif rank == 1:
data = Package()
req = comm.irecv(buf=data, source=0, tag=11)
while not req.test():
sleep(0.1)
print(rank, data.msg)
我以为会有以下行为:
秩为0的节点将数据包作为对象发送到秩为1的节点
秩为1的节点开始非阻塞接收,当它完成接收时,test()
返回True
时会发生什么,我可以打印data.msg
。
问题是,当我运行时,以下错误发生在buf
:
TypeError:应为可写缓冲区对象
如何正确使用irecv()
发送/接收对象?你知道吗
在
mpi4py
中,在MPI之上有两种接口。在缓冲区之间来回通信的低级接口(用大写字母表示,即Isend
),以及通信python对象的高级接口(即isend
)。你知道吗高级接口通过pickle序列化对象。对于非阻塞操作,这需要用户提供的缓冲区,并且需要足够大。另一方面,
test
函数返回一个found, object
元组。因此,使用高级接口,您的代码接收器看起来像:请注意,您的发件人代码缺少邮件的完整性。但是不管你是
send
还是isend
这些数据。你知道吗在任何情况下,您都必须以某种方式为接收缓冲区确定足够的缓冲区大小,这可能是不可能做到真正干净的。如果缓冲区太小,您将收到
MPI.Exception
。你知道吗也可以使用低级接口。例如,您可以轻松地发送numpy阵列:
shape
和dtype
必须匹配才能理解它。你知道吗相关问题 更多 >
编程相关推荐