MPI_ERR_TRUNCATE при отправке комплексного числа через MPI [MPI4py]

Я пытаюсь отправить одно комплексное число, используя реализацию Python MPI (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() и получение Comm::Irecv() вместе с Request::Wait() в этом примере. Однако в целом у меня будет один Comm::Isend() на итерацию цикла for и Request::Waitall() на вектор запросов, по одному на каждого получателя в целом.

Для вышеуказанной программы создано всего два процесса MPI: один отправитель и один получатель. Также моя установка MPI4py — 3.0.0. и использует Python 2.7.14 и ядро ​​Open MPI 2.1.2.

Теперь программа вылетает на

rA.wait()

со следующей ошибкой

mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: сообщение усечено

что на основе поиска в Интернете означает, что буфера приемника недостаточно для хранения полученных данных, то есть комплексного числа, но я не понимаю, почему.


person mgus    schedule 22.05.2018    source источник


Ответы (1)


Вот что происходит под капотом:

  • 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)

or

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

для того, чтобы A было определено как матрица сложных

person Gilles Gouaillardet    schedule 22.05.2018
comment
Это нормально для операндов 1 на 1, но полученные матрицы обычно имеют размер n на n. Как бы вы инициализировали в этом случае? Требует ли MPI, чтобы полученный буфер был заранее инициализирован для всей матрицы? - person mgus; 22.05.2018
comment
другой вариант — A = np.zeros(shape(1,1),dtype=complex) - person Gilles Gouaillardet; 22.05.2018
comment
MPI требует, чтобы буфер был выделен (инициализация не требуется) до MPI_Irecv(). mpi4py может проделать дополнительную магию и выделить буфер для вас, но, честно говоря, я не знаю. - person Gilles Gouaillardet; 22.05.2018
comment
Чтобы выделить без инициализации, вы можете A = np.empty(shape(1,1), dtype=complex) - person Gilles Gouaillardet; 22.05.2018