mpi Tutorial
Erste Schritte mit MPI
Suche…
Bemerkungen
MPI ist ein Standard für die Kommunikation zwischen einer Gruppe von verteilten (oder lokalen) Prozessen. Es enthält Routinen zum Senden und Empfangen von Daten, zum gemeinsamen Kommunizieren und für andere komplexere Aufgaben.
Der Standard bietet eine API für C und Fortran, es gibt jedoch auch Bindungen zu verschiedenen anderen Sprachen.
Versionen
Ausführung | Standard | Veröffentlichungsdatum |
---|---|---|
1 | mpi-report-1.3-2008-05-30.pdf | 1994-05-05 |
2,0 | mpi2-report.pdf | 2003-09-15 |
2.2 | mpi22-report.pdf | 2009-09-04 |
3,0 | mpi30-report.pdf | 2012-09-21 |
3.1 | mpi31-report.pdf | 2015-06-04 |
Rang und Größe
So ermitteln Sie die Größe eines Kommunikators (z. B. MPI_COMM_WORLD
) und den Rang des lokalen Prozesses darin:
int rank, size;
int res;
MPI_Comm communicator = MPI_COMM_WORLD;
res = MPI_Comm_rank (communicator, &rank);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Comm_rank failed\n");
exit (0);
}
res = MPI_Comm_size (communicator, &size);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Comm_size failed\n");
exit (0);
}
Init / Finalisieren
Bevor irgendwelche MPI-Befehle ausgeführt werden können, muss die Umgebung initialisiert und am Ende abgeschlossen werden:
int main(int argc, char** argv)
{
int res;
res = MPI_Init(&argc,&argv);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Init failed\n");
exit (0);
}
...
res = MPI_Finalize();
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Finalize failed\n");
exit (0);
}
}
Hallo Welt!
Drei Dinge sind normalerweise wichtig, wenn Sie mit der Verwendung von MPI beginnen möchten. Zuerst müssen Sie die Bibliothek initialisieren, wenn Sie bereit sind, sie zu verwenden (Sie müssen sie auch abschließen, wenn Sie fertig sind). Zweitens möchten Sie wissen, wie groß Ihr Communicator ist (das, was Sie zum Senden von Nachrichten an andere Prozesse verwenden). Drittens möchten Sie wissen, welchen Rang Sie innerhalb dieses Kommunikators haben (welche Prozessnummer sind Sie innerhalb dieses Kommunikators).
#include <mpi.h>
#include <stdio.h>
int main(int argc, char **argv) {
int size, rank;
int res;
res = MPI_Init(&argc, &argv);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Init failed\n");
exit (0);
}
res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Comm_size failed\n");
exit (0);
}
res = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Comm_rank failed\n");
exit (0);
}
fprintf(stdout, "Hello World from rank %d of %d~\n", rank, size);
res = MPI_Finalize();
if (res != MPI_SUCCESS)
{
fprintf (stderr, "MPI_Finalize failed\n");
exit (0);
}
}
Wenn Sie dieses Programm wie folgt ausführen:
mpiexec -n 2 ./hello
Sie würden erwarten, eine Ausgabe wie diese zu erhalten:
Hello World from rank 0 of 2!
Hello World from rank 1 of 2!
Sie können diese Ausgabe auch rückwärts erhalten (siehe http://stackoverflow.com/a/17571699/491687 ), um weitere Informationen dazu zu erhalten:
Hello World from rank 1 of 2!
Hello World from rank 0 of 2!
Rückgabewerte von MPI-Aufrufen
Fast jeder MPI-Aufruf gibt einen ganzzahligen Fehlercode zurück, der den Erfolg der Operation anzeigt. Wenn kein Fehler auftritt, lautet der Rückkehrcode MPI_SUCCESS
:
if (MPI_Some_op(...) != MPI_SUCCESS)
{
// Process error
}
Wenn ein Fehler auftritt, ruft MPI eine mit dem Communicator-, Fenster- oder Dateiobjekt verknüpfte Fehlerbehandlungsroutine auf, bevor er zum Benutzercode zurückkehrt. Es gibt zwei vordefinierte Fehlerhandler (der Benutzer kann zusätzliche Fehlerhandler definieren):
-
MPI_ERRORS_ARE_FATAL
- Fehler führen zum Abbruch des MPI-Programms -
MPI_ERRORS_RETURN
- Fehler führen dazu, dass der Fehlercode an den Benutzer zurückgegeben wird
Der Standardfehlerhandler für Kommunikatoren und Fenster ist MPI_ERRORS_ARE_FATAL
. für MPI_ERRORS_RETURN
ist es MPI_ERRORS_RETURN
. Der Fehlerhandler für MPI_COMM_WORLD
gilt auch für alle Operationen, die sich nicht speziell auf ein Objekt beziehen (z. B. MPI_Get_count
). Das Überprüfen des Rückgabewerts von Nicht-E / A-Vorgängen ohne Setzen des Fehlerbehandlungsprogramms auf MPI_ERRORS_RETURN
ist daher redundant, da fehlerhafte MPI-Aufrufe nicht zurückgegeben werden.
// The execution will not reach past the following line in case of error
int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
// The following code will never get executed
fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
exit(EXIT_FAILURE);
}
Um die Fehlerbehandlung durch Benutzer zu ermöglichen, muss zuerst der Fehlerbehandler von MPI_COMM_WORLD
:
MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
exit(EXIT_FAILURE);
}
Der MPI-Standard setzt nicht voraus, dass sich MPI-Implementierungen nach Fehlern beheben und die Programmausführung fortsetzen können.