mpiIniziare con mpi


Osservazioni

MPI è uno standard per la comunicazione tra un gruppo di processi distribuiti (o locali). Include routine per inviare e ricevere dati, comunicare collettivamente e altre attività più complesse.

Lo standard fornisce un'API per C e Fortran, ma esistono anche collegamenti a vari altri linguaggi.

Versioni

Versione Standard Data di rilascio
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

Ciao mondo!

Di solito, tre cose sono importanti quando si inizia a imparare a usare MPI. Innanzitutto, devi inizializzare la libreria quando sei pronto per usarla (devi anche finalizzarla quando hai finito). In secondo luogo, vorrai conoscere la dimensione del tuo comunicatore (la cosa che usi per inviare messaggi ad altri processi). In terzo luogo, vorrai conoscere il tuo grado all'interno di quel comunicatore (quale numero di processo sei all'interno di quel comunicatore).

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

Se si esegue questo programma in questo modo:

mpiexec -n 2 ./hello
 

Ci si aspetterebbe di ottenere un risultato come questo:

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

Puoi anche ottenere quell'output all'indietro (vedi http://stackoverflow.com/a/17571699/491687 ) per ulteriori discussioni su questo:

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

Init / Finalizzazione

Prima di poter eseguire qualsiasi comando MPI, l'ambiente deve essere inizializzato e finalizzato alla fine:

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

Classifica e taglia

Per ottenere la dimensione di un comunicatore (ad es. MPI_COMM_WORLD ) e il processo locale 'classifica al suo interno:

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

Restituisce i valori delle chiamate MPI

Quasi tutte le chiamate MPI restituiscono un intero codice di errore, che indica il successo dell'operazione. Se non si verifica alcun errore, il codice di ritorno è MPI_SUCCESS :

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

Se si verifica un errore, MPI chiama un gestore di errori associato al communicator, alla finestra o all'oggetto file prima di tornare al codice utente. Esistono due gestori di errori predefiniti (l'utente può definire gestori di errori aggiuntivi):

  • MPI_ERRORS_ARE_FATAL - gli errori provocano la chiusura del programma MPI
  • MPI_ERRORS_RETURN - gli errori provocano il ritorno del codice di errore all'utente

Il gestore errori predefinito per communicator e windows è MPI_ERRORS_ARE_FATAL ; per gli oggetti file è MPI_ERRORS_RETURN . Il gestore degli errori per MPI_COMM_WORLD si applica anche a tutte le operazioni che non sono specificamente correlate a un oggetto (ad esempio, MPI_Get_count ). Pertanto, il controllo del valore restituito delle operazioni non I / O senza impostare il gestore errori su MPI_ERRORS_RETURN è ridondante poiché le chiamate MPI errate non verranno restituite.

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

Per abilitare l'elaborazione degli errori degli utenti, è necessario prima modificare il gestore degli errori di 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);
}
 

Lo standard MPI non richiede che le implementazioni MPI siano in grado di recuperare da errori e continuare l'esecuzione del programma.