2016-05-11 3 views
0

Я закодированный следующий код, чтобы экспериментировать с AllGather():Почему AllGather() не работает для циклов с разными значениями итерации?

from mpi4py import MPI 

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

a = None 
if rank == 0: 
    a = 2 
if rank == 1: 
    a = 3 
z = 2 
for i in range(0, a): 
    z = comm.allgather(z) 

print(z, rank) 
comm.barrier() 

Я запустить его следующим образом:

Mpiexec -n 2 python3 allgather.py

Я получаю следующий результат:

[[2, 2], [2, 2]] 0

2-й процессор застревает, и программа не завершается.

Вывод должен быть:

[[2, 2], [2, 2]] 0

[[2, 2], [2, 2], [2, 2 ]] 1

Я не понимаю, почему второй процессор застревает. Он работает правильно, если я устанавливаю a = 2 в обоих процессорах. Что я делаю не так?

ответ

1

Второй процесс застрял, потому что он пытается собрать из всех процессов, второй процесс ждет, когда первый присоединится к нему в операции allgather() и будет ждать бесконечно, чтобы это произошло.

Очень сложно сказать вам хороший способ исправить это, не зная практического применения. Но в целом все процессы должны будут участвовать в операции сбора, простое исправление только пусть процесс 0 вкушать без использования результата:

from mpi4py import MPI 

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

a = None 
if rank == 0: 
    a = 2 
if rank == 1: 
    a = 3 
z = 2 
old_z = None 
for i in range(0, a): 
    if i == a-1: 
     old_z = z 
    z = comm.allgather(z) 

if rank == 0: 
    comm.allgather(old_z) 

print(z, rank) 
comm.barrier() 

Это не очень элегантное решение, но это действительно обеспечивает ваш желаемый результат , Обратите внимание, что мне нужно было сохранить значение z из предыдущей итерации процессов, чтобы получить что-нибудь близкое к вашему желаемому поведению.

Если мы не будем хранить предыдущее значение г мы получаем следующий результат:

[[2, 2], [2, 2]] 0

[[[2, 2], [2, 2]], [[2, 2], [2, 2]]] 1

+0

А, я вижу это сейчас! Я также попробовал z = comm.gather (z, root = rank), но он также не работает. Есть идеи по этому поводу? – SpiderRico

+0

. «' Gather'' выполняет только сбор данных из всех процессов в одном, что означает, что вам все равно нужно отправлять их, но есть только один получатель. Я знаю, что именование немного запутанно. К сожалению, у mpi4py точно нет хорошей документации, посмотрите: http://mpi4py.readthedocs.io/en/stable/overview.html Если это то, что вы ищете, там не задокументировано, посмотрите на C-API для MPI. – H2O