2013-02-24 6 views
20

Jaka jest główna różnica między funkcjami MPI_Allgather i MPI_Alltoall w MPI?Różnica między funkcjami MPI_Allgather i MPI_Alltoall?

To znaczy, czy ktoś może mi podać przykłady, gdzie MPI_Allgather będzie pomocny, a MPI_Alltoall nie będzie? i wzajemnie.

Nie jestem w stanie zrozumieć głównej różnicy? Wygląda na to, że w obu przypadkach wszystkie procesy wysyłają elementy send_cnt do każdego innego procesu uczestniczącego w komunikatorze i odbiera je?

Thank You

+0

Czy przeczytałeś standard MPI przed zadaniem tego pytania? Daje bardzo jasne wyjaśnienia, a nawet ma graficzne reprezentacje wielu kolektywów. – Jeff

Odpowiedz

51

Obraz mówi więcej niż tysiąc słów, więc o kilka ASCII zdjęcia:

rank send buf      recv buf 
---- --------      -------- 
0  a,b,c   MPI_Allgather  a,b,c,A,B,C,#,@,% 
1  A,B,C  ----------------> a,b,c,A,B,C,#,@,% 
2  #,@,%       a,b,c,A,B,C,#,@,% 

to dopiero regularne MPI_Gather, tylko w tym przypadku wszystkie procesy odbierania kawałki danych, czyli operacji jest pozbawiony roota.

rank send buf      recv buf 
---- --------      -------- 
0  a,b,c   MPI_Alltoall  a,A,# 
1  A,B,C  ----------------> b,B,@ 
2  #,@,%       c,C,% 

(a more elaborate case with two elements per process) 

rank send buf      recv buf 
---- --------      -------- 
0  a,b,c,d,e,f MPI_Alltoall  a,b,A,B,#,@ 
1  A,B,C,D,E,F ----------------> c,d,C,D,%,$ 
2  #,@,%,$,&,*      e,f,E,F,&,* 

(wygląda lepiej, jeśli każdy element jest zabarwiona rangi, który wysyła go, ale ...)

MPI_Alltoall pracuje jako połączonego MPI_Scatter i MPI_Gather - bufora wysłać każdy proces jest podzielony jak w MPI_Scatter i następnie każda kolumna porcji jest zbierana przez odpowiedni proces, którego pozycja jest zgodna z numerem kolumny porcji. MPI_Alltoall może być również postrzegana jako globalna operacja transpozycji, działająca na porcjach danych.

Czy jest przypadek, gdy dwie operacje są wymienne?Aby właściwie odpowiedzieć na to pytanie, trzeba po prostu analizować rozmiary danych w buforze wysyłania i danych w buforze odbioru:

operation  send buf size  recv buf size 
---------  -------------  ------------- 
MPI_Allgather sendcnt   n_procs * sendcnt 
MPI_Alltoall n_procs * sendcnt n_procs * sendcnt 

Rozmiar bufora otrzymać faktycznie n_procs * recvcnt, ale mandaty MPI, że liczba Przesłane podstawowe elementy powinny być równe liczbie otrzymanych podstawowych elementów, a więc jeśli ten sam typ danych MPI jest używany w częściach nadawczych i odbiorczych MPI_All..., wówczas recvcnt musi być równy sendcnt.

Od razu widać, że dla tego samego rozmiaru otrzymanych danych ilość danych wysyłanych przez każdy proces jest różna. Aby te dwie operacje były równe, koniecznym warunkiem jest to, że rozmiary wysłanych buforów w obu przypadkach są równe, tj. n_procs * sendcnt == sendcnt, co jest możliwe tylko jeśli n_procs == 1, tj. Jeśli jest tylko jeden proces lub sendcnt == 0, tj. Brak danych jest w ogóle wysyłany. W związku z tym nie ma praktycznie wykonalnego przypadku, w którym obie operacje są naprawdę wymienne. Ale można symulować MPI_Allgather z MPI_Alltoall przez powtórzenie n_procs razy tych samych danych w buforze wysyłania (jak to już zauważył Tyler Gill). Oto działanie MPI_Allgather z jednoelementowych wysyłają buforów:

rank send buf      recv buf 
---- --------      -------- 
0  a    MPI_Allgather  a,A,# 
1  A   ----------------> a,A,# 
2  #        a,A,# 

A tu taka sama realizowane z MPI_Alltoall:

rank send buf      recv buf 
---- --------      -------- 
0  a,a,a   MPI_Alltoall  a,A,# 
1  A,A,A  ----------------> a,A,# 
2  #,#,#       a,A,# 

odwrotna jest niemożliwa - nie można symulować działanie MPI_Alltoall z MPI_Allgather w ogólnym przypadku.

+2

Bardzo dobra odpowiedź. Zwłaszcza w przypadku ilustracji i zdjęć koncepcja jest bardzo jasna. Dziękuję Hristo Iliev –

2

Chociaż te dwie metody są rzeczywiście bardzo podobne, nie wydaje się być jedna zasadnicza różnica między nimi.

MPI_Allgather kończy się z każdym procesem mającym dokładnie te same dane w swoim buforze odbiorczym, a każdy proces wnosi pojedynczą wartość do całej tablicy. Na przykład, jeśli każdy z zestawu procesów potrzebnych do dzielenia się pojedynczą wartością o swoim stanie ze wszystkimi innymi, każdy z nich dostarczyłby ich pojedynczą wartość. Wartości te będą następnie wysyłane do wszystkich, więc każdy będzie miał kopię tej samej struktury.

MPI_Alltoall nie wysyła tych samych wartości do siebie nawzajem. Zamiast podawania pojedynczej wartości, która powinna być współużytkowana ze sobą, każdy proces określa jedną wartość, którą należy nadać sobie nawzajem. Innymi słowy, przy n procesach, każdy musi podać n wartości do współdzielenia. Następnie, dla każdego procesora j, jego wartość k'th zostanie wysłana do przetworzenia indeksu j'th k w buforze odbiorczym. Jest to przydatne, jeśli każdy proces ma jeden, niepowtarzalny komunikat dla każdego innego procesu.

Ostatecznie, wyniki działania allgather i alltoall byłyby takie same w przypadku, gdy każdy proces wypełniłby swój bufor wysyłkowy tą samą wartością. Jedyna różnica polegałaby na tym, że członek społeczności byłby o wiele bardziej wydajny.

+0

Dziękuję bardzo –

6

Te dwa screenshoty mieć szybkie wyjaśnienie:

MPI_Allgatherv

MPI_Allgatherv

MPI_Alltoallv

MPI_Alltoallv

Mimo to na Compa rison między MPI_Allgatherv i MPI_Alltoallv, ale wyjaśnia również, jak MPI_Allgather różni się od MPI_Alltoall.