mpi4py - MPI_ERR_TRUNCATE: сообщение усечено

Я преобразовал код ring_c.c из примеров OPENMPI на python, чтобы поэкспериментировать с mpi4py. Вот мой код.

from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size

tag = 2
message = 10

if 0 == rank:
    comm.send(message, dest=next_proc, tag=tag)

while(1):
    message = comm.recv(message, source=prev_proc, tag=tag)  
    comm.Recv_init

    if 0 == rank:
        message = message - 1
        print "Process %d decremented value: %d\n" %(rank, message)

    comm.send(message, dest=next_proc, tag=tag)

    if 0 == message:
        print "Process %d exiting\n" %(rank)
        break;

if 0 == rank:
    message = comm.recv(message, source=prev_proc, tag=tag)

Когда я запускаю его через mpiexec для любого количества процессов, например

mpiexec -n 10 python ring_py.py

Это дает следующий вывод и ошибку:

Process 0 decremented value: 9

Process 0 decremented value: 8

Process 0 decremented value: 7

Process 0 decremented value: 6

Process 0 decremented value: 5

Process 0 decremented value: 4

Traceback (most recent call last):
  File "ring_py.py", line 20, in <module>
    message = comm.recv(message, source=prev_proc, tag=tag)  
  File "MPI/Comm.pyx", line 1192, in mpi4py.MPI.Comm.recv (src/mpi4py.MPI.c:106889)
  File "MPI/msgpickle.pxi", line 287, in mpi4py.MPI.PyMPI_recv (src/mpi4py.MPI.c:42965)
mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: message truncated

Пара наблюдений

  • Если я изменю сообщение на 6 или 50, оно всегда выдает одну и ту же ошибку в уменьшенном значении процесса 0: 4
  • Если я изменю значение сообщения на 4 или меньше, оно выдаст ту же ошибку, ничего больше не делая.
  • Количество процессов не влияет на вывод кода, кроме времени выполнения.

Немного подробностей о моей системе.

  • Я использую модель MacBook Air 2012 года с macOS Sierra и процессором Intel i7.
  • Я установил mpi4py через PIP в python 2.7, а его версия 2.0.0.

Может кто-нибудь, пожалуйста, помогите мне понять, что происходит с моим кодом.

Спасибо, Джаянт.


person Jayant Sahewal    schedule 15.10.2016    source источник


Ответы (2)


Я попробовал ваш код и получил ошибку:

message = comm.recv(message, source=prev_proc, tag=tag) 

Заявление:

TypeError: ожидается доступный для записи объект буфера

Следуя руководству по mpi4py или MPI4Py вызывает ошибку при отправке/получении , я успешно попытался:

message = comm.recv( source=prev_proc, tag=tag) 
person francis    schedule 15.10.2016

Благодаря Фрэнсису я смог разгадать тайну. Я знаю, что Python чувствителен к регистру, даже тогда, когда я упустил тот факт, что есть два разных набора функций для отправки и получения сообщений. Send/Recv использует массив Numpy, а send/recv использует рассол под капотом.

Итак, первая версия, т.е. версия Numpy, может быть:

from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = np.array([0,])
message[0] = 10
if 0 == rank:
    print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
    comm.Send([message, MPI.INT], dest=next_proc, tag=tag)

while(1):
    comm.Recv([message, MPI.INT], source=prev_proc, tag=tag)

    if 0 == rank:
        message = message - 1
        print "Process %d decremented value: %d\n" %(rank, message)

    comm.Send([message, MPI.INT], dest=next_proc, tag=tag)

    if 0 == message[0]:
        print "Process %d exiting\n" %(rank)
        break;

Вторая версия, т.е. версия рассола, может быть:

from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size

tag = 2
message = 10

if 0 == rank:
    print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
    comm.send(message, dest=next_proc, tag=tag)        

while(1):
    message = comm.recv(source=prev_proc, tag=tag)

    if 0 == rank:
        message = message - 1
        print "Process %d decremented value: %d\n" %(rank, message)

    comm.send(message, dest=next_proc, tag=tag)

    if 0 == message:
        print "Process %d exiting\n" %(rank)
        break;

Обе версии дадут одинаковый результат. Разница будет заключаться во времени их выполнения в соответствии с руководством по MPI, в котором говорится, что версия Numpy будет быстрее.

person Jayant Sahewal    schedule 15.10.2016