Introduction à MPI

Hello World

#include <stdio.h>
#include <unistd.h>
#include "mpi.h"

int main(int argc, char **argv)
{  int rank, size;
   char hostname[100];

   MPI_Init(&argc, &argv);
   
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   gethostname(hostname, 100);
   
   printf("Hello from process %d of %d on host %s\n", rank, size, hostname);
   
   MPI_Finalize();
   return 0;
}

Compiler le programme en utilisant mpicc (les mêmes options que gcc). Exécuter en utilisant mpiexec.

La première fonction MPI utilisée dans un programme doit être MPI_Init. Chaque programme doit se terminer par MPI_Finalize.

Pour connaître le nombre total de processus, utilisez MPI_Comm_size. Chaque processus possède un numéro entre 0 et n - 1, où n est le nombre total de processus. Pour connaître le numéro du processus courant, utilisez MPI_Comm_rank.

Simple échange de messages

#include <stdio.h>
#include <string.h>
#include "mpi.h"

#define TAG 99

int main(int argc, char **argv)
{  int rank, size;
   int i;
   char msg[100];
   MPI_Status status;

   MPI_Init(&argc, &argv);
   
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   
   if (rank == 0)
   {  for (i = 1; i < size; i++)
      {  sprintf(msg, "Hello %d!", i);
         MPI_Send(msg, strlen(msg) + 1, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
      }
   }
   else
   {  MPI_Recv(msg, 100, MPI_CHAR, 0, TAG, MPI_COMM_WORLD, &status);
      printf("%d received %s\n", rank, msg);
   }
   
   MPI_Finalize();
   return 0;
}

Dans cet exemple le processus 0 envoie un message aux autres processus. Les autres processus reçoivent ce message.

Les primitives de communication les plus simples sont MPI_Send et MPI_Recv. Consulter la documentation de ces deux fonctions (ici).

Ping-pong

Anneau

On suppose que nous avons n processus en anneau. Le voisin gauche de processus p est p - 1 et son voisin droit est p + 1 (le voisin gauche de 0 est n - 1 et le voisin droit de n - 1 est 0). Faire passer par l'anneau un message de longueur k octets m fois (k et m sont paramètres de la ligne de commande). La communication est initié par processus 0, chaque processus reçoit le message de son voisin gauche et l'envoie à son voisin droit. Mesurer le temps nécessaire en utilisant MPI_Wtime.