Search code examples
pythonbuffermpicomplex-numbersmpi4py

MPI_ERR_TRUNCATE when sending complex number over MPI [MPI4py]


I am trying to send a single complex number using Python implementation of MPI (MPI4py) from a single sender to a single receiver. Here is the code:

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)

Please note that the above example is a simplified version of my goal which is to send a numpy array (or numpy matrix) of many complex entries from one sender to multiple receivers. That's why I am using nonblocking send Comm::Isend() and receive Comm::Irecv(), along with Request::Wait() in this example. However in general, I would have one Comm::Isend() per iteration of a for loop and Request::Waitall() for a vector of requests, one for each receiver in general.

For the above program the MPI processes created are just two, one sender and one receiver. Also my MPI4py installation is 3.0.0. and uses Python 2.7.14 and the kernel of Open MPI 2.1.2.

Now, the program crashes at the

rA.wait()

with the following error

mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: message truncated

which based on a search online means that the receiver's buffer is insufficient to store the received data i.e. the complex number, but I don't understand why.


Solution

  • Here is what happens under the hood :

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

    So the issue comes from how you initialized the receive buffer

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

    Possible fixes are

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

    or

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

    in order to have A defined as a matrix of complex