mpiAan de slag met mpi


Opmerkingen

MPI is een standaard voor communicatie tussen een groep gedistribueerde (of lokale) processen. Het omvat routines om gegevens te verzenden en ontvangen, collectief te communiceren en andere meer complexe taken.

De standaard biedt een API voor C en Fortran, maar bindingen met verschillende andere talen bestaan ook.

versies

Versie Standaard Publicatiedatum
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

Hallo Wereld!

Drie dingen zijn meestal belangrijk wanneer u MPI begint te leren gebruiken. Eerst moet u de bibliotheek initialiseren wanneer u klaar bent om deze te gebruiken (u moet deze ook voltooien als u klaar bent). Ten tweede wilt u de grootte van uw communicator weten (het ding dat u gebruikt om berichten naar andere processen te verzenden). Ten derde wilt u uw positie binnen die communicator weten (welk procesnummer bent u binnen die communicator).

#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);
    }
}
 

Als u dit programma als volgt uitvoert:

mpiexec -n 2 ./hello
 

Je zou verwachten output als volgt te krijgen:

Hello World from rank 0 of 2!
Hello World from rank 1 of 2!
 

U kunt die uitvoer ook terugdraaien (zie http://stackoverflow.com/a/17571699/491687 ) voor meer informatie hierover:

Hello World from rank 1 of 2!
Hello World from rank 0 of 2!
 

Init / Finalize

Voordat MPI-opdrachten kunnen worden uitgevoerd, moet de omgeving worden geïnitialiseerd en uiteindelijk worden voltooid:

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);
    }
}
 

Rang en grootte

Om de grootte van een communicator (bijvoorbeeld MPI_COMM_WORLD ) en de rangorde van het lokale proces erin te krijgen:

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);
}
 

Retourwaarden van MPI-oproepen

Bijna elke MPI-aanroep retourneert een integer-foutcode die het succes van de bewerking aangeeft. Als er geen fout optreedt, is de retourcode MPI_SUCCESS :

if (MPI_Some_op(...) != MPI_SUCCESS)
{
   // Process error
}
 

Als er een fout optreedt, roept MPI een foutafhandelaar op die is gekoppeld aan de communicator, het venster of het bestandsobject voordat de gebruiker terugkeert naar de gebruikerscode. Er zijn twee vooraf gedefinieerde foutafhandelaars (de gebruiker kan extra foutafhandelaars definiëren):

  • MPI_ERRORS_ARE_FATAL - fouten leiden tot beëindiging van het MPI-programma
  • MPI_ERRORS_RETURN - fouten leiden ertoe dat de foutcode wordt teruggegeven aan de gebruiker

De standaardfouthandler voor communicators en Windows is MPI_ERRORS_ARE_FATAL ; voor bestandsobjecten is dit MPI_ERRORS_RETURN . De foutafhandelaar voor MPI_COMM_WORLD ook van toepassing op alle bewerkingen die niet specifiek betrekking hebben op een object (bijvoorbeeld MPI_Get_count ). Dus is het controleren van de retourwaarde van niet-I / O-bewerkingen zonder de foutafhandelaar in te stellen op MPI_ERRORS_RETURN overbodig omdat foutieve MPI-oproepen niet terugkeren.

// 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);
}
 

Om de verwerking van gebruikersfouten mogelijk te maken, moet eerst de foutafhandelaar van 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);
}
 

De MPI-standaard vereist niet dat MPI-implementaties fouten kunnen herstellen en de uitvoering van het programma kunnen voortzetten.