Różnica między funkcjami MPI Allgather i MPI Alltoall?

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

Chodzi mi o to czy ktos moze mi podac przyklady gdzie mpi_allgather bedzie pomocny a MPI_Alltoall nie? i vice versa.

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 otrzymują je?

Thank You

 23
mpi
Author: Kranthi Kumar, 2013-02-24

3 answers

Obraz mówi więcej niż tysiąc słów, więc oto kilka obrazów sztuki ASCII:

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,#,@,%

Jest to zwykły MPI_Gather, tylko w tym przypadku wszystkie procesy otrzymują kawałki danych, tzn. operacja jest bez 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 kolorowany przez rangę, która go wysyła, ale...)

MPI_Alltoall działa jak połączone MPI_Scatter i MPI_Gather - bufor wysyłania w każdym procesie jest dzielony jak w MPI_Scatter, a następnie każda kolumna fragmentów jest gromadzona przez odpowiedni proces, którego ranga odpowiada numerowi kolumny fragmentu. MPI_Alltoall może być również postrzegana jako globalna operacja transpozycji, działająca na fragmentach danych.

Czy jest przypadek, gdy obie operacje są wymienne? Aby poprawnie odpowiedzieć na to pytanie, należy po prostu przeanalizować 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 odbierającego jest w rzeczywistości n_procs * recvcnt, ale MPI nakazuje, aby liczba wysłanych podstawowych elementów jest równa liczbie odebranych podstawowych elementów, stąd Jeśli ten sam typ danych MPI jest używany zarówno w części wysyłania, jak i odbierania MPI_All..., to recvcnt musi być równy sendcnt.

Jest od razu oczywiste, że dla tej samej wielkości odebranych danych, ilość danych wysyłanych przez każdy proces jest inna. Aby obie operacje były równe, jednym koniecznym warunkiem jest to, że rozmiary wysyłanych buforów w obu przypadkach są równe, tzn. n_procs * sendcnt == sendcnt, co jest możliwe tylko wtedy, gdy n_procs == 1, tzn. gdy istnieje tylko jeden proces, lub jeśli sendcnt == 0, tzn. żadne dane nie są wysyłane w ogóle. W związku z tym nie ma praktycznie realnego przypadku, w którym obie operacje są naprawdę wymienne. Ale można symulować MPI_Allgather z MPI_Alltoall powtarzając n_procs razy te same dane w buforze wysyłania (jak już zauważył Tyler Gill). Oto działanie MPI_Allgather z jednoelementowymi buforami wysyłania:

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

I tu to samo zaimplementowane 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,#

Odwrotność nie jest możliwa - nie można symulować działania MPI_Alltoall z MPI_Allgather w ogólnym przypadku.

 59
Author: Hristo Iliev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-24 15:40:02

Te dwa screeny mają szybkie wyjaśnienie:

MPI_Allgatherv

MPI_Allgatherv

MPI_Alltoallv

MPI_Alltoallv

Chociaż jest to porównanie między MPI_Allgatherv i MPI_Alltoallv, ale wyjaśnia również, czym mpi_allgather różni się od MPI_Alltoall.

 10
Author: Tong Zhou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-06 02:49:02

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

Mpi_allgather kończy się tym, że każdy proces ma dokładnie te same dane w swoim buforze odbiorczym, a każdy proces wnosi jedną wartość do ogólnej tablicy. Na przykład, jeśli każdy z zestawów procesów potrzebował udostępnić jakąś pojedynczą wartość o swoim stanie wszystkim innym, każdy z nich dostarczyłby swoją pojedynczą wartość. Wartości te będą następnie wysyłane do wszystkich, więc każdy miał kopię tej samej struktury.

MPI_Alltoall nie wysyła do siebie tych samych wartości. Zamiast dostarczania jednej wartości, która powinna być współdzielona z innym procesem, każdy proces określa jedną wartość, która ma zostać przekazana innemu procesowi. Innymi słowy, w przypadku n procesów każdy musi określić n wartości, które mają być współdzielone. Następnie, dla każdego procesora J, jego wartość k 'TH zostanie wysłana do indeksu J' TH procesu k w buforze odbioru. Jest to przydatne, jeśli każdy proces ma jeden, unikalny wiadomość dla siebie procesu.

Na koniec, wyniki uruchomienia allgather i alltoall byłyby takie same w przypadku, gdy każdy proces wypełnił swój bufor wysyłania tą samą wartością. Jedyną różnicą byłoby to, że allgather prawdopodobnie byłby znacznie bardziej wydajny.

 4
Author: Tyler Gill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-24 07:34:47