首页 > 解决方案 > 通过 MPI [MPI4py] 发送复数时的 MPI_ERR_TRUNCATE

问题描述

我正在尝试使用 MPI 的 Python 实现(MPI4py)将单个复数从单个发送者发送到单个接收者。这是代码:

from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD

if comm.rank == 0:

    print("I am sender")

    a = np.matrix('5+1j')

    req = [None]
    #Send message with a predefined tag, like 15, to rank 1
    req = comm.Isend([a, MPI.COMPLEX], dest=1, tag=15)

    MPI.Request.Wait(req)

    print("Sender sent:  ")
    print(a[0])

else:

    print("I am receiver")

    A = np.empty_like(np.matrix([[0]*(1) for i in range(1)]))

    print("point 1")

    #Receive message with tag 15 from rank 0
    rA = comm.Irecv(A, source=0, tag=15)

    rA.wait()

    print("Receiver received:  ")
    print(A)

请注意,上面的示例是我的目标的简化版本,它是将许多复杂条目的numpy数组(或numpy矩阵)从一个发送者发送到多个接收者。这就是为什么我在这个例子中使用非阻塞发送Comm::Isend()和接收。但是,一般来说,对于一个 for 循环和一个请求向量的每次迭代,我都会有一个,通常每个接收器都有一个。Comm::Irecv()Request::Wait()Comm::Isend()Request::Waitall()

对于上述程序,创建的 MPI 进程只有两个,一个发送者和一个接收者。我的 MPI4py 安装也是 3.0.0。并使用 Python 2.7.14 和 Open MPI 2.1.2 的内核。

现在,程序在

rA.wait()

出现以下错误

mpi4py.MPI.Exception:MPI_ERR_TRUNCATE:消息被截断

这基于在线搜索意味着接收器的缓冲区不足以存储接收到的数据,即复数,但我不明白为什么。

标签: pythonbuffermpicomplex-numbersmpi4py

解决方案


这是引擎盖下发生的事情:

  • MPI_Isend(..., datatype=MPI_COMPLEX, ...)
  • MPI_Irecv(..., datatype=MPI_LONG, ...)

所以问题来自你如何初始化接收缓冲区

A = np.empty_like(np.matrix([[0]*(1) for i in range(1)]))

可能的修复是

A = np.empty(shape(1,1), dtype=complex)

或者

A = np.matrix('-1-1j')

为了A定义为一个复杂的矩阵


推荐阅读