2013-02-24 8 views
20

Was ist der Hauptunterschied zwischen den Funktionen MPI_Allgather und MPI_Alltoall in MPI?Unterschied zwischen MPI_Allgather und MPI_Alltoall Funktionen?

Ich meine, kann jemand mir Beispiele geben, wo MPI_Allgather hilfreich sein wird und MPI_Alltoall wird nicht? und umgekehrt.

Ich bin nicht in der Lage, den Hauptunterschied zu verstehen? Es sieht so aus, als ob in beiden Fällen alle Prozesse send_cnt-Elemente an jeden anderen Prozess senden, der am Communicator teilnimmt und diese empfängt?

Danke

+0

Haben Sie den MPI-Standard gelesen, bevor Sie diese Frage gestellt haben? Es gibt sehr klare Erklärungen und sogar grafische Darstellungen vieler Kollektive. – Jeff

Antwort

51

Ein Bild sagt mehr als tausend Worte, so dass hier mehrere ASCII-Art-Bilder sind:

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

Dies ist nur der reguläre MPI_Gather, nur in diesem Fall werden alle Prozesse der Datenabschnitte, dh die Operation erhalten ist wurzellos.

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,&,* 

(sieht besser aus, wenn jedes Element durch den Rang gefärbt wird, die es aber ... sendet)

MPI_Alltoall Werke als kombinierte MPI_Scatter und MPI_Gather - der Sendepuffer in jedem Prozess aufgeteilt wie in MPI_Scatter und dann wird jede Spalte von Chunks durch den jeweiligen Prozess gesammelt, dessen Rang mit der Nummer der Chunk-Spalte übereinstimmt. MPI_Alltoall kann auch als eine globale Transpositionsoperation betrachtet werden, die auf Datenbrocken wirkt.

Gibt es einen Fall, wenn die beiden Operationen austauschbar sind?Um richtig diese Frage zu beantworten, muss man einfach die Größe der Daten im Sendepuffer analysiert und die Daten im Empfangspuffer:

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

Die Empfangspuffergröße tatsächlich n_procs * recvcnt, aber MPI legt fest, dass die Zahl der gesendeten Basiselemente sollte gleich der Anzahl der empfangenen Basiselemente sein. Wenn also der gleiche MPI-Datentyp in Sende- und Empfangsteilen von MPI_All... verwendet wird, muss recvcnt gleich sendcnt sein.

Es ist sofort offensichtlich, dass für die gleiche Größe der empfangenen Daten die Menge der von jedem Prozess gesendeten Daten unterschiedlich ist. Damit beide Operationen gleich sind, ist eine Bedingung, dass die Größe der gesendeten Puffer in beiden Fällen gleich ist, dh n_procs * sendcnt == sendcnt, was nur möglich ist, wenn n_procs == 1, dh wenn es nur einen Prozess gibt, oder sendcnt == 0, dh keine Daten wird überhaupt gesendet. Daher gibt es keinen praktisch durchführbaren Fall, in dem beide Vorgänge wirklich austauschbar sind. Aber man kann MPI_Allgather mit MPI_Alltoall simulieren, indem man n_procs mal die gleichen Daten im Sendepuffer wiederholt (wie bereits von Tyler Gill notiert). Hier ist die Wirkung von MPI_Allgather mit einem Element senden Puffer:

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

Und hier das gleiche umgesetzt mit MPI_Alltoall:

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

Die Rückseite ist nicht möglich - man nicht die Wirkung von MPI_Alltoall mit MPI_Allgather simulieren im allgemeinen Fall.

+2

Eine sehr gute Antwort. Besonders bei Illustrationen und Bildern ist das Konzept sehr klar. Danke, Hristo Iliev –

2

Während diese beiden Methoden in der Tat sehr ähnlich sind, gibt es zwischen den beiden von ihnen einen entscheidenden Unterschied zu sein scheint.

MPI_Allgather endet mit jedem Prozess, der genau die gleichen Daten in seinem Empfangspuffer hat, und jeder Prozess trägt einen einzelnen Wert zum gesamten Array bei. Wenn zum Beispiel jeder von einer Reihe von Prozessen benötigt wird, um einen einzelnen Wert über ihren Zustand mit allen anderen zu teilen, würde jeder seinen einzelnen Wert bereitstellen. Diese Werte würden dann an alle gesendet werden, so dass jeder eine Kopie der gleichen Struktur haben würde.

MPI_Alloall sendet nicht die gleichen Werte an jeden anderen Prozess. Anstatt einen einzelnen Wert bereitzustellen, der mit jedem anderen Prozess geteilt werden soll, gibt jeder Prozess einen Wert an, der jedem anderen Prozess gegeben wird. Mit anderen Worten, bei n Prozessen muss jeder n Werte angeben, die geteilt werden sollen. Dann wird für jeden Prozessor j sein k-ter Wert gesendet, um den j-ten Index von k im Empfangspuffer zu verarbeiten. Dies ist nützlich, wenn jeder Prozess eine einzige eindeutige Nachricht für jeden anderen Prozess enthält.

Als letzte Anmerkung wären die Ergebnisse von allgather und alltoall in dem Fall identisch, in dem jeder Prozess seinen Sendepuffer mit demselben Wert füllte. Der einzige Unterschied wäre, dass alle Mitglieder wahrscheinlich viel effizienter wären.

+0

Vielen Dank –

6

Diese beiden Screenshots haben eine kurze Erklärung:

MPI_Allgatherv

MPI_Allgatherv

MPI_Alltoallv

MPI_Alltoallv

dies zwar ein Compa Rison zwischen MPI_Allgatherv und MPI_Alloall, aber es erklärt auch, wie sich MPI_Allgather von MPI_Alltoall unterscheidet.

Verwandte Themen