Chapitre 3 MPI2
Chapitre 3 MPI2
Chapitre 3 MPI2
MPI est une bibliothèque contenant plus de 120 fonctions, mais seules quelques-unes (moins
d’une dizaine) sont nécessaires pour un programme simple.
Pour utiliser MPI, un programme doit inclure le header de MPI : #include "mpi.h"
Ensuite, MPI_Init(argc, argv) doit être appelé avant toute autre fonction de la
bibliothèque MPI, et MPI_Finalize(void) doit être appelé à la fin de l’exécution du logiciel
pour libérer les ressources.
Les communications dans un programme MPI sont organisées par groupes de
communication. Cette fonctionnalité peut s’avérer très utile pour des programmes un peu
complexes, mais, dans notre cas, nous nous contenterons du groupe de communication
MPI_COMM_WORLD qui contient tous les nœuds.
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 2/12
A noter qu‘on peut aussi utiliser MPI_ANY_TAG pour accepter des messages quel que soit
leur tag. Il est de plus possible d’envoyer une donnée à tous les nœuds, en utilisant int
MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) :
selon que le nœud en question envoie (son rang est alors égal à la valeur de root) ou reçoit,
buffer contient la valeur à envoyer ou est l’endroit où sera écrite la valeur ; Par exemple :
Pour récupérer sur un nœud une valeur de chacun des nœuds, il convient d’utiliser int
MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int
recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm). Les noms des arguments
sont assez explicites. Voici un exemple d’utilisation :
int size;
int rank;
double *sum_buf = NULL;
double sum = 0;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if ( rank == 0 )
sum_buf = malloc(sizeof(double)
* size);
MPI_Gather((void *)&sum, 1,
MPI_DOUBLE, sum_buf, 1,
MPI_DOUBLE, 0,
MPI_COMM_WORLD);
p processus : P0 à Pp�1
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 3/12
#include <stdio.h>
#include "mpi.h"
main(int argc, char *argv[]) {
int my_rank; /* Rang du processus */
int p; /* Nombre de processus */
int source; /* Rang de l’emetteur */
int dest; /* Rang du recepteur */
int tag = 50; /* Tag des messages */
char message[100]; /* Allocation du message */
MPI_Status status; /* Valeur de retour pour le recepteur */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 4/12
Une communication dite point à point a lieu entre deux processus, l’un appelé processus
émetteur et l’autre processus récepteur (ou destinataire).
Exemple :
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 5/12
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 6/12
MPI Sendrecv() utilise un ordre MPI Send() suivi d’un ordre MPI Recv(). En effet,
chacun des deux processus attendrait un ordre de réception qui ne viendrait jamais,
puisque les deux envois resteraient en suspens.
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 8/12
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI 9/12
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI
10/12
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI
11/12
.
Calcul Parallèle. Chapitre 3. Message Passing Interface MPI
12/12