Message Passing Interface (MPI)

Transcription

Message Passing Interface (MPI)
MPI
Message Passing Interface
(MPI)
Présentation
z
Avantages de MPI
z
Background de MPI
z
Concept clé MPI
z
Programme simple
z
Programme complexe
1
Avantages
z
Fonctionne sur un très grand nombre de
configuration
z
Librairie complète pour le calcul parallèle
z
Débogage « facile » par rapport à du SMP
Background
z
z
z
La librairie est définie par un groupe incluant
des programmeurs, des compagnies de
matériel informatique et des utilisateurs
Disponible en C, Fortran pour toutes les
architectures système
Des centaines de routines prédéfinies
2
Implantations
z
z
MPICH :
http://www.unix.mcs.anl.gov/mpi/mpich/
LAM/MPI (OpenMPI)
http://www.lam-mpi.org/
z
MVAPICH
http://openib.org/
z
...
Concept clé de MPI
z
z
z
La division des tâches est choisie par le
programmeur
Un même programme est exécuté sur
plusieurs noeuds de calcul en même temps
Les noeuds communiquent par des librairies
pour interagir ensemble
3
Programme minimal
z
Initialisation (MPI_Init)
z
Identification des noeuds (MPI_comm_rank)
z
Nombre total de noeuds (MPI_comm_size)
z
Finalisation (MPI_Finalize)
Communicateur
z
z
z
z
z
Un paramètre pour les opérations MPI
Un groupe de noeuds oeuvrant sur une tâche
MPI_COMM_WORLD est par défaut le
communicateur incluant toutes les noeuds
Possible de diviser des communicateurs
Le groupe donne des rangs aux noeuds (de
0 à n)
4
Fonctions de base MPI
z
z
z
z
MPI_Send
Envoie à un autre noeud
MPI_Recv
Reçoie d'un autre noeud
MPI_Bcast
Envoie à tout le groupe
Les paramètres pour ces routines sont
différentes selon l'implantation de MPI
MatlabMPI
z
z
http://www.ll.mit.edu/MatlabMPI/
Fonctionnement de MatlabMPI pour du calcul
distribué
5
Exemple simple
z
Calcul de pi sur plusieurs noeuds
z
Intégrer de 1 à n la fonction
4
2
1 x
Exemple complexe
z
Solution 2D de la circulation d'océan en
différence finie
2
∂
∂ x2
2
∂
∂ y2
y
∂
= − sin
∂x
2 Ly
6
Initialisation
% variables globales
global ..........
% initialisation MPI
MPI_Init;
comm = MPI_COMM_WORLD;
numnodes = MPI_Comm_size(comm);
myid = MPI_Comm_rank(comm);
% noeud maitre
mpi_master = 0;
Stencil en différence finie
7
Code
% calcul des constantes et des coefficients
dx = lx/(nx+1);
dy = ly/(ny+1);
dx2 = dx*dx;
dy2 = dy*dy;
bottom = 2.0*(dx2+dy2);
%
a1 = (dy2/bottom)+(beta*dx2*dy2)/(2.0*gamma*dx*bottom);
a2 = (dy2/bottom)-(beta*dx2*dy2)/(2.0*gamma*dx*bottom);
a3 = dx2/bottom;
a4 = dx2/bottom;
a5 = dx2*dy2/(gamma*bottom);
a6 = pi/(ly);
Décomposition de domaine
Domaine séquentiel
Domaine parallèle
8
Noeuds fantômes
Pour calculer psi le noeud
#1 doit avoir la valeur de
psi qui est dans le
domaine du noeud #2
Décompostion
Domaine séquentiel
Domaine parallèle
9
Code décomposition
id = 1;
for j=1:nrow,
for i=1:ncol,
index(id,1) = i;
index(id,2) = (j-1)*ndivy;
index(id,3) = j*ndivy+1;
id=id+1;
end
end
id = 1;
for i=1:nrow,
for j=1:ncol,
index(id,4) = i;
index(id,5) = (j-1)*ndivx;
index(id,6) = j*ndivx+1;
id=id+1;
end
end
Communication des domaines
aux noeuds
if (myid == mpi_master),
for id=1:numnodes-1,
MPI_SEND(id,1,comm,index(id+1,1));
MPI_SEND(id,2,comm,index(id+1,2));
MPI_SEND(id,3,comm,index(id+1,3));
MPI_SEND(id,4,comm,index(id+1,4));
MPI_SEND(id,5,comm,index(id+1,5));
MPI_SEND(id,6,comm,index(id+1,6));
end
else
myrow = MPI_RECV(mpi_master,4,comm);
i1 = MPI_RECV(mpi_master,2,comm);
i2 = MPI_RECV(mpi_master,3,comm);
mycol = MPI_RECV(mpi_master,1,comm);
j1 = MPI_RECV(mpi_master,5,comm);
j2 = MPI_RECV(mpi_master,6,comm);
end
10
Voisins
% voisins pour le communicateur des noeuds fantomes
myleft = myid-1;
if (j1 == 1); myleft = -1; end
myright = myid+1;
if (j2 == nx); myright = -1; end
mybot = myid-ncol;
if (i1 == 1); mybot = -1; end
mytop = myid+ncol;
if (i2 == ny); mytop = -1; end
Résolution
z
z
z
Itérations de Jacobi
Communication des noeuds fantômes à
chaque itération
Éviter les « deadlock »
11
Code de communication
if isequal(mod(myrow,2),0)
if (myleft ~= -1),
% send to bot
MPI_SEND(myleft,100,comm,psi(:,2));
% rec from bot
psi(:,1) = MPI_RECV(myleft,100,comm);
end
if (myright ~= -1),
% rec from top
psi(:,j2-j1+1) = MPI_RECV(myright,100,comm);
% send to top
MPI_SEND(myright,100,comm,psi(:,j2-j1));
end
else % we are on an odd col processor
if (myright ~= -1),
% rec from top
psi(:,j2-j1+1) = MPI_RECV(myright,100,comm);
% send to top
MPI_SEND(myright,100,comm,psi(:,j2-j1));
end
if (myleft ~= -1),
% send to bot
MPI_SEND(myleft,100,comm,psi(:,2));
% rec from bot
psi(:,1) = MPI_RECV(myleft,100,comm);
end
end
12