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