在irecv TypeError中将对象作为缓冲区传递:应为可写缓冲区obj

2024-09-25 00:34:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我在为一个项目使用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)

我以为会有以下行为:

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

  2. 秩为1的节点开始非阻塞接收,当它完成接收时,test()返回True时会发生什么,我可以打印data.msg

问题是,当我运行时,以下错误发生在buf

TypeError:应为可写缓冲区对象

如何正确使用irecv()发送/接收对象?你知道吗


Tags: testpackagesourcedata节点requesttag缓冲区
1条回答
网友
1楼 · 发布于 2024-09-25 00:34:54

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必须匹配才能理解它。你知道吗

相关问题 更多 >