我正在尝试使用MPI(MPI4py)的Python实现从单个发送方向单个接收方发送单个复数。这是代码:
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()
和接收Comm::Irecv()
以及Request::Wait()
的原因。但是一般来说,对于for循环,每次迭代我会有一个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:消息被截断
意味着接收者的缓冲区不足以存储接收的数据,即复数,但我不明白为什么。
答案 0 :(得分:0)
以下是幕后发生的事情:
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
定义为复杂的矩阵