在irecv中将对象作为缓冲区传递-TypeError:预期为可写缓冲区对象

时间:2019-07-18 16:43:13

标签: python mpi mpi4py

我正在为一个项目使用MPI。我需要以非阻塞模式将数据包从一个节点传输到另一个节点。我正在使用包含有关我的通信逻辑的相关信息的类来组织此程序包。

我正在使用功能@babel/plugin-syntax-dynamic-import进行一些测试,以获取我的通讯和缓冲区的请求,还使用irecv()进行测试以验证是否有消息到达。

MPI缺少Python的文档,因此我正在检查source code以获得更多信息,我在使用什么功能。

源代码声明irecv如下:

test()

我了解到,如果我想将数据放入缓冲区中,则需要设置可选参数“ buf”以及我希望将接收到的消息存储的位置。

我尝试了以下测试以了解其工作原理:

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

我期望以下行为:

  1. 等级为0的节点将数据包作为对象发送到等级为1的节点

  2. 排名1的节点开始无阻塞接收,并且当接收完成时,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) 返回test()时会发生什么,我可以打印True

问题是,当我运行时,data.msg发生以下错误:

TypeError:应为可写缓冲区对象

如何正确使用buf传输/接收对象?

1 个答案:

答案 0 :(得分:1)

mpi4py中,MPI之上有两种接口。来回通信缓冲区的低级接口(以大写字母表示,Isend),和通信python对象的高级别接口(即isend)。

高级接口通过pickle序列化对象。对于非阻塞操作,这需要一个用户提供的缓冲区,并且需要足够大。另一方面,test函数返回一个found, object元组。因此,使用高级界面,您的代码接收器如下所示:

buf = bytearray(b" " * 256)
req = comm.irecv(buf=buf, source=0, tag=11)
while True:
    found, data = req.test()
    if found:
        break
    time.sleep(0.1)
print(1, data.msg)

请注意,您的发件人代码缺少邮件的填写内容。但是,您send还是isend数据都没关系。

在任何情况下,您都必须以某种方式为接收缓冲区确定足够的缓冲区大小,这可能实际上是不可能做到的。如果缓冲区太小,您将收到MPI.Exception

您还可以使用低级界面。例如,您可以轻松地发送numpy数组:

if rank == 0:
    data = np.array([1, 2, 3], dtype=float)
    comm.Send(data, dest=1, tag=11)
elif rank == 1:
    data = np.zeros(3, dtype=float)
    req = comm.Irecv(buf=data, source=0, tag=11)
    while True:
        found = req.Test()
        if found:
            break
        time.sleep(0.1)
    print(1, data)

shapedtype必须匹配才能理解。