Ich habe 3 Fragen, alle bezogen auf MPI (in C). Ich denke, die ersten 2 haben die gleiche Antwort, aber ich bin nicht positiv.
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.
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.
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?
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:
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, wirddims[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:
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
:
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
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:
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.