2015-10-25 2 views
0

Я использовал коды MPI и имею некоторые основные идеи, но никогда не делал никаких разработок MPI. Я начинаю с распараллеливания некоторых моих кодов питона. Вот фрагменты того, что я пытаюсь сделать:mpi4py - Как избежать блока связи

IMPORT STUFF 
... 
comm = MPI.COMM_WORLD 
size = comm.Get_size() 
rank = comm.Get_rank() 
status = MPI.Status() 
comm.Barrier() 
## CREATE EMPTY ARRAYS 
if rank == 0: 
    t_start=MPI.Wtime() 
    tt =np.zeros(nt) 
    ezp=np.zeros(nt) 
    ezm=np.zeros(nt) 
## NUMBER CRUNCHING LOOP 
for it in range(rank,nt,comm.size): 
    ... 
    DO SOMETHING 
    ... 
## IF RANK == 0, POPULATE OWN PARTS OF ARRAY 
    if rank == 0: 
     tt[ it] = ltt 
     ezp[it] = lezp 
     ezm[it] = lezm 
    if rank > 0: 
    ## IF RANK != 0, SEND DATA TO PROC 0 
     snddata=[it,ltt,lezp,lezm] 
     comm.send(snddata, dest=0, tag=13) 
    else: 
# IF RANK == 0, RECEIEVE THE DATA FROM ALL PROCS AND POPULATE 
# CORRESPONDING ARRAY ELEMENTS 
     for src in range(1,comm.size): 
     rcvdata=comm.recv(source=src,tag=13,status=status) 
     tt[ rcvdata[0]] = rcvdata[1] 
     ezp[rcvdata[0]] = rcvdata[2] 
     ezm[rcvdata[0]] = rcvdata[3] 
comm.Barrier() 
... 
WRITE THE RESULTS tt[:], ezp[:], ezm[:] TO FILE 

Я бегу код с

mpirun -np 2 python mycode.py ARGUMENTS 

Проблема заключается в том, что несколько раз разложение цикла не дает равные размеры петель для проками , Например. если нт = 21 и я использую 2 проки, Proc 0 перебирает:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 

и Proc 1 перебирает:

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19] 

Следовательно для того, = 20, Proc 0 продолжает ждать, чтобы услышать от прока 1 который ничего не делает. Очевидно, что для любой комбинации nt и np, которая не имеет nt% np = 0, я получаю эту проблему.

Что было бы хорошим способом установления связи в таком случае?

Спасибо!

ответ

0

Первый подход, который приходит на ум, - отправить все данные одним (или, возможно, двумя) вызовами.

  • если есть «наиболее возможное» состояние, тогда получите максимально возможное. Отправитель отправит то, что у него есть, но можно получить меньше, чем требуется.

  • Если это невозможно, используйте два сообщения: одна передача/получение пара обменяет int - количество ожидаемых значений в следующем сообщении. Затем следующее сообщение имеет много значений.

Вы явно не спрашивали об этом, но ваш код заканчивается словами «записывать результаты в файл». Возможно, вы можете избежать отправки/получения все вместе? Если все, что вы делаете, это сбор ответов на ранг 0, возможно, вы хотите изучить подходы MPI-IO и каждый процесс записывать непосредственно в файл.