Dimensionen, Koordinaten und Reihenfolge von Prozessen in einem 2D-MPI-Raster verstehen

8

Ich habe 3 Fragen, alle bezogen auf MPI (in C). Ich denke, die ersten 2 haben die gleiche Antwort, aber ich bin nicht positiv.

Frage 1

Bei Verwendung von MPI_Dims_create zum Erstellen eines 2D-Gitters ist die Dimension der zurückgegebenen Dimensionen X und Y?

Zum Beispiel:

%Vor%

Sollte es sein:

%Vor%

Oder das:

%Vor%

Ich habe versucht, dies mit einer Anzahl von Prozessen auszuführen, die so aussahen, als würden sie mir die Antwort geben (z. B. 6). Bei 6 Prozessen sollte MPI_Dims_create entweder ein Raster mit 3 Zeilen und 2 Spalten oder 2 Zeilen und 3 Spalten erstellen (sofern ich die Dokumentation nicht missverstanden habe). Für Prozess 3 (von 6) habe ich size[0] = 1 und size[1] = 0 gefunden (ich glaube, das entspricht x = 0, y = 1). Dies scheint mir anzuzeigen, dass MPI_Dims_create ein Gitter mit 3 Zeilen und 2 Spalten erstellt (da es 2 Zeilen und 3 Spalten war, sollte Prozess 2 (von 6) x = 2, y = 0 haben). Jede Bestätigung, die jemand dazu geben könnte, wäre sehr willkommen.

Frage 2

Bei Verwendung von MPI_Cart_coords in einem kartesischen 2D-Raster ist die zurückgegebene Dimension X und Y?

Zum Beispiel:

%Vor%

Ähnlich wie bei Frage 1 lautet meine Frage: Soll es so sein?

%Vor%

oder wie das

%Vor%

Ich habe die Dokumentation und die vorherigen Fragen hier durchsucht, aber ich kann keine direkte Antwort auf diese Frage finden.

Die Dokumentation scheint darauf hinzuweisen, dass der erste der beiden Ansätze der richtige ist, aber nicht definitiv.

Frage 3

Die grundlegende Frage hinter den ersten beiden Fragen ist, dass ich versuche, das 2D-Gitter in Zeilen und Spalten aufzuteilen. Wenn ich jedoch MPI_Comm_rank verwende, um die Zeilen- und Spalten-IDs jedes Prozesses nach dem Vorgang zu überprüfen, erhalte ich die bestellten Prozesse in einer Reihenfolge, die nicht mit meinen Antworten auf die obigen Fragen übereinstimmt.

Ich gehe davon aus, dass die Prozesse wie folgt geordnet sind:

%Vor%

Allerdings, mit diesem Code (der nach dem obigen Code in meinem Programm kommt, so dass alle oben genannten Code von ihm zugänglich ist: Ich versuche, meinen Code zu trennen, um es einfacher zu machen, meine Fragen zu isolieren):

%Vor%

Ich sehe Folgendes gedruckt:

%Vor%

scheint der folgenden Reihenfolge der Prozesse zu entsprechen:

%Vor%

was ist die entgegengesetzte Matrix Dimensionen (2 Zeilen, 3 Spalten) von dem, was ich von MPI_Dims_create erwartet hatte.

Angenommen, mein Verständnis für die ersten beiden Fragen ist korrekt (dh, dass Y die erste von diesen Funktionen zurückgegebene Dimension ist), warum werden die Prozesse (scheinbar) in diesem Schritt in einer anderen Reihenfolge angeordnet?

    
Matt Sinclair 08.12.2012, 22:43
quelle

1 Antwort

5

Q1 und Q2. Solche Dimensionen wie Dimension X und Dimension Y gibt es in MPI nicht - das sind Bezeichnungen, die Sie den im Standard verwendeten abstrakten Dimensionen geben. MPI arbeitet mit nummerierten Dimensionen und folgt der C-Zeilen-Nummerierung der Ränge, dh in 2x3 Cartesian topology (0,0) maps to rank 0 , (0,1) maps to rank 1 , (0,2) maps to rank 2 , (1,0) mappt auf rank 3 und so weiter.

Beachten Sie, dass die Dimension 0 dem Element ganz rechts im Koordinatentupel entspricht. Dies ist in reverse zu der Nummerierung von Elementen in C-Arrays und oft eine Quelle der Verwirrung. Um eine topologische Topologie mit 2x3 zu erstellen, müsste das Array size wie folgt initialisiert werden:

%Vor%

Es liegt an Ihnen, die abstrakten nummerierten Dimensionen Ihrem Problem zuzuordnen. Sie können die Dimension 0 als X wählen oder Sie können die Dimension 1 wählen - es spielt keine Rolle.

Wie für MPI_DIMS_CREATE lautet der Standard:

  

Die Dimensionen sind so nahe wie möglich zueinander angeordnet, wobei ein geeigneter Divisibilitätsalgorithmus verwendet wird.

     

Für dims[i] , das durch den Aufruf festgelegt wurde, wird dims[i] in nicht aufsteigender Reihenfolge angeordnet.

Diese Operation gibt einfach ein Array von Elementen dims[i] mit den folgenden Eigenschaften zurück (außer die Größe einer oder mehrerer Dimensionen wird durch Setzen eines Werts ungleich null in dims[] vor dem Aufruf von MPI_DIMS_CREATE festgelegt) :

  • dims[0] >= dims[1] >= dims[2] >= ...
  • dims[0] * dims[1] * dims[2] == nprocs , wobei nprocs die Anzahl der Prozesse ist, die in MPI_DIMS_CREATE angegeben sind.

Dies bedeutet, dass as MPI_DIMS_CREATE den Satz von nprocs in ein multidimensionales Gitter zerlegt, den größten Multiplikator der Größe der Dimension 0 , den nächsten der Größe der Dimension 1 und bald. Als 6 Faktoren wie 2*3 , dann würde MPI_DIMS_CREATE { 3, 2 } zurückgeben. Wenn Sie MPI_CART_CREATE direkt mit dem Ergebnis von MPI_DIMS_CREATE aufrufen, wird eine 2x3 -Topologie mit Koordinaten und Rängen erstellt:

%Vor%

Q3. MPI bietet eine spezielle Routine zur Partitionierung von kartesischen Topologien - MPI_CART_SUB . Es benötigt ein Array von logischen Flags (Ganzzahlen in C) mit dem Namen remain_dims im Standard. Jedes remain_dims[i] ungleich Null bedeutet, dass diese Dimension i in der resultierenden Partitionierung beibehalten werden sollte, während separate Unterkommunikatoren für jede mögliche Kombination der nicht beibehaltenen Dimensionen erstellt würden. Zum Beispiel mit der Topologie 2x3 :

  • remain_dims[] = { 1, 0 } behält die Dimension 0 und führt zu 2 nicht überlappenden 1-d-Kommunikatoren mit jeweils 3 Prozessen;
  • remain_dims[] = { 0, 1 } behält die Dimension 1 in 3 nicht überlappenden 1-d-Kommunikatoren mit je 2 Prozessen bei;
  • remain_dims[] = { 0, 0 } behält keine der beiden Dimensionen bei und führt zu 6 nicht überlappenden nulldimensionalen Communicators mit jeweils einem einzigen Prozess.

Welche Partitionierung Sie zeilenweise aufrufen würden und welche Sie eine spaltenweise Partitionierung nennen würden, hängt von Ihnen und Ihrer Beschriftung der kartesischen Dimensionen ab.

Es ist zu beachten, dass häufig MPI-Codes auf Systemen ausgeführt werden, die aus vernetzten SMP- oder NUMA-Multicore-Knoten bestehen. In diesem Fall wäre ein geeignetes 2D-Gitter nodes x cores . Wenn die Anzahl der Kerne bekannt ist, kann man sie leicht im Aufruf von MPI_DIMS_CREATE :

korrigieren %Vor%

Dies ist praktischer als die Aufteilung von numProcs nach ncores und die Prüfung auf Teilbarkeit, da MPI_DIMS_CREATE einen Fehler anzeigen würde, wenn ncores numProcs nicht teilt. Dann eine Partitionierung, die die Dimension 0 enthält, d. H. Eins mit

%Vor%

würde Subcommunicators erstellen, die Prozesse auf demselben Knoten enthalten, während

%Vor%

würde Subcommunicators erstellen, die keine zwei Prozesse vom selben Knoten enthalten.

Beachten Sie, dass Sie in Ihrem Code einen Wert von 1 (true) für den Parameter reorder in MPI_CART_CREATE angegeben haben. Dies kann zu Prozessen mit unterschiedlichen Rängen in MPI_COMM_WORLD und im kartesischen Kommunikator führen. Daher gibt es keine Garantie, dass die folgenden Codezeilen das tun, was Sie von ihnen erwarten:

%Vor%

myProcID wurde von MPI_COMM_WORLD erhalten und könnte tatsächlich vom neuen Rang in cart_comm abweichen. Daher sollte es nicht dazu verwendet werden, die Prozesskoordinaten zu erhalten und die Splits durchzuführen.

    
Hristo Iliev 09.12.2012, 00:13
quelle

Tags und Links