Introduction à MPI Références

Transcription

Introduction à MPI Références
Introduction à MPI
Daniel Etiemble
[email protected]
Références
• R. Rabenseifner, « Introduction to MPI, University of
Stuttgart, www.hlrs.de
• W. Gropp, E. Lusk, A. Skjellum, « Using MPI », The
MIT Press
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
2
1
Le paradigme « passage de messages »
• Chaque processeur travaille sur un programme
– Écrit dans un langage séquentiel (C/C++ ou Fortran)
– Typiquement le même sur chaque processeur (SPMD)
– Les variables de chaque processeur ont
• Le même nom
• Des emplacements mémoire (mémoire distribuée) et des données différentes
• Toutes les variables sont privées
– Communique via des routines d’envoi et de réception (passage de messages
Données
Programme
Données
Données
Données
Données
Données
Programme Programme Programme Programme Programme
Réseau d’interconnexion
Maîtrise Informatique 2003
3
D. Etiemble
Calcul parallèle
Distribution des données et du travail
• La valeur de myrank est fournie par une routine de bibliothèque
• Un programme d’initialisation MPI démarre le système de size
processus
• Les décisions de distribution sont basées sur myrank
myrank=0
Données
myrank=1
Données
myrank=2
Données
myrank=3
Données
Programme
Programme Programme Programme
myrank=
size -1
Données
Programme
Réseau d’interconnexion
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
4
2
Initialisation de MPI
#include <mpi.h>
Main (int argc, char **argv)
{
MPI_Init (&argc, &argv);
….
• Communicator MPI_COMM_WORLD
– Tous les processus d’un programme MPI sont combinés dans
MPI_COMM_WORLD (prédéfini dans mpi.h)
– Chaque processus a son rang dans un communicateur
• De 0
• À (size – 1)
– Fonctions
• Rang : identifie les différents processus
– Int MPI_Comm_rank (MPI_Comm comm, int *rank)
• Taille : nombre de processus dans un communicateur
– Int MPI_Comm_size (MPI_Comm comm, int *size)
Maîtrise Informatique 2003
5
D. Etiemble
Calcul parallèle
Messages
• Les messages sont des paquets de données entre programmes
• Information nécessaire
– Processus émetteur
• Adresse source
• Type de données source
• Taille des données source
– Processus récepteur
• Adresse destination
• Type de donnée destination
• Taille du tampon destination
Adresse Y
Réception Y, P, t
Envoi X, Q, t
Adresse X
Espace
d’adressage
local
Espace
d’adressage
local
Processus Q
Processus P
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
6
3
Messages
• Un message contient un certain nombre d’éléments d’un
certain type de données
– Type de données de base
– Type de données dérivés (des types de base et de types dérivés)
• Les types de données de base MPI
– MPI_CHAR
– MPI_SHORT, MPI_INT, MPI_LONG
– MPI_UNSIGNED_CHAR, MPI_UNSIGNED_SHORT,
MPI_UNSIGNED, MPI_UNSIGNED_LONG
– MPI_FLOAT, MPI_DOUBLE, MPI_LONG_DOUBLE
– MPI_BYTE
– MPI_PACKED
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
7
Communication point à point
• Forme la plus simple de passage de message
• Un processus envoie un message à un autre processus
• La communication a lieu à l’intérieur d’un
communicateur (MPI_COMM_WORLD)
• Les processus sont identifiés par leur rang dans le
communicateur
• Différent types de communication point à point
– Envoi synchrone
• L’émetteur obtient l’information que le message a été reçu
– Envoi asynchrone
• L’émetteur sait seulement que le message est parti.
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
8
4
Envoi – réception d’un message
• Envoi
– int MPI_Send (void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm
comm)
– buf est le début du message avec count éléments, chacun décrit avec un type de données
(datatype)
– dest est le rang du processus destination dans le communicateur comm
– tag est une information entière non négative transférée avec le message
• Réception
– int MPI_Recv (void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm
comm, MPI_Status *status)
– buf, count, datatype décrivent le tampon de réception
– Reçoit le message envoyé par le processus de source rank dans comm
– Information de réception est récupérée dans status
– Seuls les messages avec le bon tag sont reçus
• Contraintes
–
–
–
–
–
–
L’émetteur doit spécifier un rang de destination valide
Le récepteur doit spécifier un rang source valide
Le communicateur doit être le même
Les étiquettes doivent correspondre
Les types de données doivent correspondre
Le tampon de réception doit être assez grand.
Maîtrise Informatique 2003
Calcul parallèle
9
D. Etiemble
Exemple : ping pong
#include "mpi.h"
#define N 50000
/* N is the number of rounds */
#define B 5000
/* B is the buffer size for the message, in bytes */
main(int argc, char *argv[])
{
int myid, opponent, trips;
char ball[B];
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
opponent = (myid+1)%2;
/* Get rank */
if (myid==1)
MPI_Send(ball, B, MPI_CHAR, opponent, 0, MPI_COMM_WORLD);
for (trips=0; trips<N;++trips)
{ MPI_Recv(ball, B, MPI_CHAR, opponent, 0, MPI_COMM_WORLD, &stat)
MPI_Send(ball, B, MPI_CHAR, opponent, 0, MPI_COMM_WORLD);
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
10
5
Opérations bloquantes et non bloquantes
• Les opérations sont locales (envoi d’un message,
réception d’un message)
• Opérations bloquantes
– Les émissions d’envoi synchrone sont bloquantes jusqu’à réception d’un
accusé de réception
– Les réceptions bloquent jusqu’à ce que le message soit envoyé
– Concernent la fin d’une opération
– Les routines bloquantes rendent la main quand l’opération est terminée
• Opérations non bloquantes
– Rendent la main immédiatement et permettent au programme de
continuer
– Plus tard, le programme doit tester ou attendre la fin de l’opération non
bloquante
– Une opération non bloquante immédiatement suivie d’une attente est
équivalente à une opération bloquante
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
11
Modes de communication
• Emission
– MPI_SSEND
• Envoi synchrone : se termine quand la réception a commencé
– MPI_BSEND
• Envoi asynchrone (« buffered ») : se termine toujours (sauf erreur)
indépendamment du récepteur. Nécessite la définition d’un tampon (par
l’application) via MPI_BUFFR_ATTACH
– MPI_SEND
• Envoi standard, soit synchrone soit asynchrone (utilise un tampon interne)
– MPI_RSEND
• Envoi si le récepteur est prêt : démarre seulement si la réception
correspondante est déjà indiquée
– MPI_RECV
• Réception : se termine quand le message est arrivé
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
12
6
Communication non bloquantes
Envoi non bloquant
MPI_Isend (…)
Autre travail
MPI_Wait(…)
MPI_Issend (buf, count, datatype, dest, tag, comm, OUT &request_handle);
MPI_Wait (INOUT &request_handle, &status)
Réception non bloquante
MPI_Irecv (…)
Autre travail
MPI_Wait(…)
MPI_Irecv (buf, count, datatype, source, tag, comm, OUT &request_handle);
MPI_Wait (INOUT &request_handle, &status)
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
13
Les communications collectives
• Les routines de communication collective sont des routines de plus
haut niveau
• Plusieurs processus simultanés (tous les processus d’un
communicateur communiquent)
• Peuvent être construites à partir des communications point à point
• Toutes les opérations collectives sont bloquantes
• Pas d’étiquettes
• Les tampons de réception doivent avoir exactement la même taille
• Les principales communications collectives
–
–
–
–
Diffusion (broadcast) : un vers plusieurs
Dispersion (scatter)
Réductions : combinaison de plusieurs processus pour produire un résultat
Les barrières de synchronisation
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
14
7
Les communications collectives
• Diffusion
– Int MPI_Bcast (void *buf, int count, MPI_Datatype datatype, int root,
MPI_Comm comm)
• Dispersion
– Int MPI_Scatter (void *sendbuf, int sendcount, MPI_Datatype sendtype, void
*recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
• Réunion
– Int MPI_Gather (void *sendbuf, int sendcount, MPI_Datatype sendtype, void
*recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
• Réduction globale
– MPI_Reduce (&inbuf, &resultbuf, 1, MPI_Datatype, MPI_OP, root, MPI_Comm
comm) où MPI_OP =
• MPI_MAX, MPI_MIN, MPI_SUM, MPI_PROD
• MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR
• MPI_MAXLOC, MPI_MPI_MINLOC (Max/min et position du max/min)
– Variantes
• MPI_ALLREDUCE (résultat dans tous les processus)
• MPI_REDUCE_SCATTER
• MPI_SCAN
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
15
Mesure de temps d’exécution
• C
– Double MPI_Wtime (void);
– Temps en secondes
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
16
8
Autres caractéristiques (non traitées)
• Les types de données dérivées
• Les topologies virtuelles
Maîtrise Informatique 2003
Calcul parallèle
17
D. Etiemble
Exemple : Calcul de π
#include <mpi.h>
#include <math.h>
int main(argc, argv)
int argc; char *argv[];
{
int done=0, n=100000, myid, numprocs, i;
double mupi, pi, h, sum, x;
MPI_Init (&argc, &argv)
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Bcast(&n, 1,MPI_INT, 0, MPI_COMM_WORLD);
if (myid==0)
printf();
}
MPI_Finalize();
Return 0;
}
h=1.0/(double) n; sum=0.0;
for (i=myid+1;i<= n; i+=numprocs)
{
x = ((double)i-0.5)*h;
sum+ = 4.0/(1.0+x*x);
}
mypi = pas * sum;
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE,
MPI_SUM, 0, MPI_COMM_WORLD);
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
18
9
Multiplication
de matrices (1)
http://www.tcnj.edu/~crew/2000/reference/howto/mm_c.html
main(int argc, char **argv)
{
int numtasks,
/* number of tasks in partition */
taskid,
/* a task identifier */
numworkers,
/* number of worker tasks */
/*
source,
/* task id of message source */
#define NRA 8
number of rows in matrix A
dest,
/* task id of message destination */
#define NCA 5
number of columns in matrix A and rows in B
nbytes,
/* number of bytes in message */
#define NCB 3
number of columns in matrix B
mtype,
/* message type */
*/
intsize,
/* size of an integer in bytes */
dbsize,
/* size of a double float in bytes */
#define NRA 16
/* number of rows in matrix A */
rows,
/* rows of matrix A sent to each worker */
#define NCA 5
/* number of columns in matrix A and rows in B*/ averow, extra, offset, /* used to determine rows sent
#define NCB 4
/* number of columns in matrix B */
to each worker */
#define MASTER 0
/* taskid of first task */
i, j, k,
/* misc */
#define FROM_MASTER 1 /* setting a message type */
count;
#define FROM_WORKER 2 /* setting a message type */
double a[NRA][NCA], /* matrix A to be multiplied */
MPI_Status status;
b[NCA][NCB], /* matrix B to be multiplied */
c[NRA][NCB]; /* result matrix C */
#include <stdio.h>
#include "mpi.h"
intsize = sizeof(int);
dbsize = sizeof(double);
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
numworkers = numtasks-1;
Maîtrise Informatique 2003
Calcul parallèle
19
D. Etiemble
Multiplication
de matrices (2)
http://www.tcnj.edu/~crew/2000/reference/howto/mm_c.html
• Tâches du maîtres
– Initialiser les matrices
– Envoyer les données des matrices
aux esclaves
– Attendre les résultats
– Imprimer les résultats
/**************************** master task **********
if (taskid == MASTER) {
printf("Number of worker tasks = %d\n",numworkers);
• Tâches des esclaves
printf("\nMATRIX A\n");
for (i=0; i<NRA; i++)
{
for (j=0; j<NCA; j++)
{
a[i][j]= i+j;
printf(" %6.2f ", a[i][j]);
}
printf("\n");
}
printf("\nMATRIX B\n");
for (i=0; i<NCA; i++)
{
for (j=0; j<NCB; j++)
{
b[i][j]= i*j;
printf(" %6.2f ", b[i][j]);
}
printf("\n");
}
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
20
10
Multiplication
de matrices (3)
http://www.tcnj.edu/~crew/2000/reference/howto/mm_c.html
/* send matrix data to the worker tasks */
averow = NRA/numworkers;
extra = NRA%numworkers;
offset = 0;
mtype = FROM_MASTER;
for (dest=1; dest<=numworkers; dest++) {
rows = (dest <= extra) ? averow+1 : averow;
printf("****** sending %d rows to task %d\n",rows,dest);
MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
count = rows*NCA;
printf("buffer size for A is %d\n", count);
MPI_Send(&a[offset][0], count, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
count = NCA*NCB;
printf("buffer size for B is %d\n", count);
MPI_Send(&b, count, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
offset = offset + rows;
}
/* wait for results from all worker tasks */
mtype = FROM_WORKER;
for (i=1; i<=numworkers; i++) {
source = i;
MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
count = rows*NCB;
printf("*** receiving info for C\n");
MPI_Recv(&c[offset][0], count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD,
&status);
}
Maîtrise Informatique 2003
Calcul parallèle
/* print results */
printf("Here is the result matrix\n");
for (i=0; i<NRA; i++) {
printf("\n");
for (j=0; j<NCB; j++)
printf("%6.2f ", c[i][j]);
}
printf ("\n");
D. Etiemble
} /* end of master section */
21
Multiplication
de matrices (4)
http://www.tcnj.edu/~crew/2000/reference/howto/mm_c.html
/**************************** worker task ************************************/
if (taskid > MASTER) {
mtype = FROM_MASTER;
source = MASTER;
printf("**** within worker\n");
MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
count = rows*NCA;
MPI_Recv(&a, count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
count = NCA*NCB;
MPI_Recv(&b, count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
for (k=0; k<NCB; k++)
for (i=0; i<rows; i++) {
c[i][k] = 0.0;
for (j=0; j<NCA; j++)
c[i][k] = c[i][k] + a[i][j] * b[j][k];
printf(" result for Matrix C index[%d][%d] is %6.2f\n", i, j, c[i][k]);
}
mtype = FROM_WORKER;
MPI_Send(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
MPI_Send(&c, rows*NCB, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
} /* end of worker */
MPI_Finalize();
} /* of main */
Maîtrise Informatique 2003
Calcul parallèle
D. Etiemble
22
11