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.
Czy przeczytałeś standard MPI przed zadaniem tego pytania? Daje bardzo jasne wyjaśnienia, a nawet ma graficzne reprezentacje wielu kolektywów. – Jeff