Vous êtes sur la page 1sur 46

Introduction au calcul parallle avec la bibliothque MPI (Message Passing Interface)

Stphanie DELAGE SANTACREU, Ple Calcul Scientique de lUPPA (http : //sinum.univ pau.f r), CRI rue Jules Ferry, PAU. Novembre 2008

Table des matires


1 Introduction 2 Environnement MPI 2.1 description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Du programme source lexcution : . . . . . . . . . . . . . . 3 4 4 5

3 Communications 8 3.1 Communications point point . . . . . . . . . . . . . . . . . . 8 3.2 Communications collectives . . . . . . . . . . . . . . . . . . . 11 3.2.1 Diusion gnrale : MPI_BCAST() . . . . . . . . . 11 3.2.2 Diusion slective de donnes rparties : MPI_SCATTER 12 3.2.3 Collecte de donnes rparties : MPI_GATHER() . . 12 3.2.4 Collecte gnrale : MPI_ALLGATHER() . . . . . . 13 3.2.5 Synchronisation globale : MPI_BARRIER . . . . . 14 3.3 Oprations de rduction et communications collectives . . . . 14 4 Optimisation dun programme parallle 4.1 Modes denvoi des messages avec MP I . . . . 4.2 Communications bloquantes et non-bloquantes 4.2.1 Communications bloquantes . . . . . . 4.2.2 Communications non-bloquantes . . . . 4.3 Synthse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 17 18 18 18 19 21 21 21 22 23 24 25 25 28 31 31 31 32 34 35 35

5 Types de donnes drivs 5.1 Types de donnes drivs homognes . . . . . . . . . . . . . . 5.1.1 Donnes contiges . . . . . . . . . . . . . . . . . . . . 5.1.2 Donnes non contiges avec un pas constant . . . . . . 5.1.3 Donnes non contiges avec un pas variable . . . . . . 5.2 Types drivs htrognes . . . . . . . . . . . . . . . . . . . . 5.3 Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Exemples sur des types de donnes drivs homognes . 5.3.2 Exemples sur des types drivs htrognes . . . . . . . 6 Topologies 6.1 Topologies de type cartsien . . . . . . . . . . . 6.1.1 Cration dune topologie cartsienne . . 6.1.2 Quelques fonctions utiles . . . . . . . . . 6.1.3 Exemple . . . . . . . . . . . . . . . . . . 6.2 Topologies de type graphe . . . . . . . . . . . . 6.2.1 Cration dune topologie de type graphe 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6.2.2 6.2.3

Quelques fonctions utiles . . . . . . . . . . . . . . . . . 36 Exemple de lIdris : propagation dun feu de fort . . . 37 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 39 39 40 42 45

7 Communicateurs 7.1 Introduction . . . . . . . . . . . 7.2 Communicateur issu dun autre 7.3 Subdivision de topologie . . . . 7.4 Intra et intercommunicateur . . 8 Conclusion

Introduction
Ce cours est issu de la formation faite par lIDRIS (http : //www.idris.f r).

Un code de calcul ou programme peut tre crit suivant deux modles de programmation : squentiel ou parallle. Dans le modle squentiel, un programme est excut par un unique processus. Ce processus tourne sur un processeur dune machine et a accs la mmoire du processeur. Il arrive que pour certains codes de calcul, la mmoire dun seul processeur ne suse plus (manipulation de gros tableaux) et/ou le temps de calcul soit trop important... Pour palier ces problmes, on peut avoir recours direntes mthodes comme le ranement de maillage adaptatif, le grid-meshing ou la programmation parallle. On sintresse ici plus particulirement la programmation parallle. Celle-ci permet de rpartir les charges de calcul sur plusieurs processus. Il existe deux types de programmation parallle : le MP I (Message Passing Interface) et le openMP (Multithreading). On se limitera au MP I . Dans un modle de programmation parallle par change de messages (MP I ), le programme est dupliqu sur plusieurs processus. Chaque processus excute un exemplaire du programme et a accs sa mmoire propre. De ce fait, les variables du programme deviennent des variables locales au niveau de chaque processus. De plus un processus ne peut pas accder la mmoire des processus voisins. Il peut toutefois envoyer des informations dautres processus condition que ces derniers (processus rcepteurs) soient au courant quils devaient recevoir ces informations du processus metteur. La communication entre processus se fait uniquement par passage de messages entre processus (cest dire : envoi et reception de messages). Techniquement, cette communication se fait via des fonctions de la bibliothque MP I appeles dans le programme. Lenvironnement MP I permet de grer et interprter ces messages.

2
2.1

Environnement MPI
description

Pour utiliser la bibliothque MP I , le programme source doit imprativement contenir : 1. lappel au module MP I : include mpif.h en fortran77, use MPI en fortran90, include mpi.h en C/C + +. 2. linitialisation de lenvironnement via lappel la subroutine MPI_INIT(code). Cette fonction retourne une valeur dans la variable code. Si linitialisation sest bien passe, la valeur de code est gale celle dans MPI_SUCCESS. 3. la dsactivation de lenvironnement via lappel la subroutine MPI_FINALIZE (code). Loublie de cette subroutine provoque une erreur. Une fois lenvironnement MP I initialis, on dispose dun ensemble de processus actifs et dun espace de communication au sein duquel on va pouvoir eectuer des oprations MP I . Ce couple (processus actifs,espace de communication) est appel communicateur. Le communicateur par dfaut est MPI_COMM_WORLD et comprend tous les processus actifs. Il est initialis lors de lappel la fonction MPI_INIT() et dsactiv par lappel la fonction MPI_FINALIZE(). On peut connatre le nombre de processus actifs grs par un communicateur avec la fonction MPI_COMM_SIZE(comm, nb_procs, code) ainsi que le rang (ou numro) dun processus avec la fonction MPI_COMM_RANK(comm, rang , code). . comm (< in >) est en entier dsignant le communicateur, . nb_procs (< out >) est en entier donnant le nombre de processus, . rang (< out >) est un entier indiquant le rang du processus. Il est important dans le sens o il sert lui didenticateur dans un communicateur. . code (< out >) est un entier retournant un code derreur. Remarque : Il faut toujours essayer de dvelopper un code parallle pour un nombre quelconque de processus.

2.2

Du programme source lexcution :

Trois tapes sont ncessaires : lcriture du programme, sa compilation puis son excution. 1. Lcriture : La gure 1 montre un exemple de programme (exercice Idris) en f ortran90. 2. La compilation du programme peut se faire par lintermdiaire dun Makele (gure 2). Les options de compilations dpendent du compilateur. La gure montre un exemple de Makele pour compiler le programme pairimpair.f 90 (gure 1) avec le compilateur du constructeur IBM (XL) 3. Lexcution du programme en interactif sur 4 processus se fait via la commande : mpiexec -n 4 /users/uppa/delage/test/pairimpair . Rponse du programme : processus de rang pair : 0 processus de rang impair : 1 processus de rang pair : 2 processus de rang impair : 3

Fig. 1: Programme (en Fortran90) processus pair et impair.

Fig. 2: Exemple de Makele pour le programme pairimpair.f 90.

3
3.1

Communications
Communications point point

La communication point point est une communication entre deux processus. Lun deux envoie un message (cest lmetteur), lautre le reoit (cest le rcepteur). Ce message doit contenir un certain nombre dinformations pour assurer une bonne rception et interprtation par le rcepteur, savoir : . le rang du processus metteur (rang _proc_source), . le rang du processus rcepteur (rang _proc_dest), . ltiquette du message (tag _emis pour message mis, tag _recu pour message reu), . le nom du communicateur (comm), . le type des donnes changes (type_emis pour message mis, type_recu pour message reu), voir tableau 1 pour le fortran et tableau 2 pour le C, . le nom donnes changes (val_emis pour message mis, val_recu pour message reu). . la taille des donnes changes (taille_emis pour message mis, taille_recu pour message reu) (scalaire, vecteur, matrice, ...). Plusieurs modes de transfert sont possibles pour changer des messages. On dcrit ici des fonctions MP I de communication en mode bloquant, qui laisse la main une fois que le message est bien reu. Cest le mode utiliser quand on commence parallliser un code. On peut ensuite passer un autre mode de tranfert pour optimiser le temps de communication (dtail plus tard). 1. MPI_SEND(val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, comm, code) pour lenvoi du message suivi de MPI_RECV(val_recu, taille_recu, type_recu, rang _proc_dest, tag _recu, comm, statut, code) pour la rception. Quand un message est envoy, il faut tre sr quil a t bien reu. . val_emis (< in >) : lment envoy, . taille_emis (< in >) : entier indiquant la taille de llment envoy (scalaire, vecteur, ...), . type_emis (< in >) : type de llment envoy, . rang_proc_dest (< in >) : entier indiquant le rang du processus qui reoit le message, . tag_emis (< in >) : entier dsignant ltiquette du message, . comm (< in >) : entier dsignant le communicateur (MP I _COMM _W ORLD par dfaut), . code (< out >) : entier donnant un code derreur, 8

. val_recu (< in >) : lment reu, . taille_recu (< in >) : entier indiquant la taille de llment reu (scalaire, vecteur, ...). Il doit correspondre celui indiqu dans taille_emis. . type_recu (< in >) : type de llment reu. Il doit aussi correspondre celui indiqu dans type_emis. . tag_recu (< in >) :entier dsignant ltiquette du message, . statut (< out >) : tableau dentiers de taille MP I _ST AT US _SIZE contenant de nombreuses informations sur le message. 2. MPI_SENDRECV(val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, val_recu, taille_recu, type_recu, rang _proc_source, tag _recu, comm, statut, code) pour lenvoi et la reception de messages. Attention, si on utilise la mme variable pour lenvoi et la rception (val_emis = val_recu), il y a crasement. rang_proc_source (< in >) est un entier indiquant le rang du processus qui a mis le message 3. MPI_SENDRECV_REPLACE(val_emis_recu, taille_emis_recu, type_emis_recu, rang _proc_dest, tag _emis, rang _proc_source, tag _recu, comm, statut, code) pour lenvoi et la reception de messages en utilisant le mme variable val_emis_recu pour lenvoi et la rception. Cette fois-ci il ny a pas dcrasement. La gure 3 propose un exemple de programme en F ortran90 dchange de messages entre deux processus (exercice de lIdris) : type MPI MP I _INT EGER MP I _INT EGER8 MP I _REAL MP I _DOUBLE _P RECISION MP I _COMP LEX MP I _LOGICAL MP I _CHARACT ER MP I _P ACKED type Fortran INTEGER INTEGER, kind=8 REAL DOUBLE COMPLEX LOGICAL CHARACTER Types htrognes

Tab. 1: Principaux type de donnes pour le fortran Remarques : On peut utiliser des jokers pour le rang du processus (rang _proc_dest = MP I _ANY _SOURCE , ie on reoit de nimporte 9

Fig. 3: Programme (en Fortran90) dchange de messages entre deux processus.

qui) et ltiquette (tag _recu = MP I _ANY _T AG) lors de la rception dun message. On peut communiquer avec un processus ctif de rang MPI_PROC_NULL. Cest trs utile lors dune action gnrique et quun des processus nexiste pas. Par exemple, si on dcide denvoyer un message son processus voisin droit, au niveau des bords dun domaine de calcul, il ny a plus de processus droit, do lutilit denvoyer le message un processus ctif. Si on envoie un message un processus qui nexiste pas, cela provoque une erreur. 10

type MPI MP I _INT MP I _UNSIGNED _INT MP I _F LOAT MP I _DOUBLE MP I _CHAR MP I _UNSIGNED _CHAR MP I _P ACKED

type C signed int unsigned int oat double signed char unsigned char Types htrognes

Tab. 2: Principaux type de donnes pour le C

3.2

Communications collectives

Elles permettent de communiquer en un seul appel avec tous les processus dun communicateur. Ce sont des fonctions bloquantes, cest dire que le systme ne rend la main un processus quune fois quil a termin la tache collective. Pour ce type de communication, les tiquettes sont automatiquement gres par le systme. On dtaille quelques fonctions de communication collective. 3.2.1 Diusion gnrale : MPI_BCAST()

Cette fonction permet un processus de diuser (BCAST pour broadcast) un message tous les processus du communicateur indiqu, y compris lui-mme (gure 4). MPI_BCAST(val_emis, taille_emis, type_emis, rang _proc_source, comm, code).

Proc0 Proc1 A Proc2 Proc3 MPI_BCAST()

Proc0 A Proc1 A Proc2 A Proc3 A

Fig. 4: Fonction MP I _BCAST (). Le processus P roc1 diuse la donne A (stocke dans sa mmoire) tous les processus P roc0 P roc3

11

3.2.2

Diusion slective de donnes rparties : MPI_SCATTER

Cette fonction permet un processus de diuser des donnes aux processus du communicateur indiqu de faon slective. En fait le processus metteur dispose de donnes quil rpartit. Chaque processus ( metteur mme compris) reoit un paquet de donnes dirent (gures 5 et 7). MPI_SCATTER(val_emis, taille_emis, type_emis, val_recu, taille_recu, type_recu,rang _proc_source, comm, code).

Proc0 Proc1 A0 A1 A2 A3 Proc2 Proc3 MPI_SCATTER()

Proc0 A0 Proc1 A1 Proc2 A2 Proc3 A3

Fig. 5: Fonction MP I _SCAT T ER(). Le processus P roc1 diuse ses donnes A0,..., A3 (stockes dans sa mmoire) tous les processus P roc0 P roc3 de faon rpartie.

3.2.3

Collecte de donnes rparties : MPI_GATHER()

Cette fonction permet au processus rcepteur de collecter les donnes provenant de tous les processus (lui-mme compris). Attention, le rsultat nest connu que par le processus rcepteur (gure 6). MPI_GATHER(val_emis, taille_emis, type_emis, val_recu, taille_recu, type_recu, comm, code).

Proc0 A0 Proc1 A1 Proc2 A2 Proc3 A3 MPI_GATHER()

Proc0 Proc1 A0 A1 A2 A3 Proc2 Proc3

Fig. 6: Fonction MP I _GAT HER(). Le processus P roc1 collecte les donnes A0,..., A3 provenant des processus P roc0 P roc3.

12

Fig. 7: Exemple de programme utilisant la fonction MP I _SCAT T ER().

3.2.4

Collecte gnrale : MPI_ALLGATHER()

Cette fonction eectue la mme chose que la fonction MP I _GAT HER, except que le rsultat de la collecte est connue de tous les processus du communicateur (gure 8). Ce serait lquivalent dun MP I _GAT HER suivi dun MP I _BCAST . MPI_ALLGATHER(val_emis, taille_emis, type_emis, val_recu, taille_recu, type_recu,rang _proc_dest, comm, code).

13

Proc0 A0 Proc1 A1 Proc2 A2 Proc3 A3 MPI_ALLGATHER()

Proc0 A0 A1 A2 A3 Proc1 A0 A1 A2 A3 Proc2 A0 A1 A2 A3 Proc3 A0 A1 A2 A3

Fig. 8: Fonction MP I _ALLGAT HER(). Le processus P roc1 collecte les donnes A0,..., A3 provenant des processus P roc0 P roc3 et le diuse tous les processus.

3.2.5

Synchronisation globale : MPI_BARRIER

Cette fonction bloque les processus lendroit o elle est appele dans le programme. Les processus restent en attente au niveau de cette barrire (BARRIER) jusqu ce quils y soient tous parvenus. Ensuite, ils sont librs. MPI_BARRIER(comm, code).

3.3

Oprations de rduction et communications collectives

Une rduction consiste appliquer une opration un ensemble dlments pour obtenir un scalaire. Cela peut tre la somme des lments dun vecteur ou la valeur maximale dun vecteur (voir tableau 3). Nom MP I _SUM MP I _P ROD MP I _MAX MP I _MIN Opration somme des lments produit des lments Recherche du maximum Recherche du minimum

Tab. 3: Quelques oprations de rduction prdnies Certaines fonctions MP I permettent de faire des oprations de rductions en plus des communications collectives. cest le cas des fonctions : . MPI_REDUCE() qui permet de faire des oprations de rduction sur des donnes rparties. Le rsultat de lopration de rduction est rcupr sur un seul processus. MPI_REDUCE(val_emis, val_recu, taille_emis, type_emis, operation, rang _proc_dest, comm, code). 14

Proc0 A0 Proc1 A1 Proc2 A2 Proc3 A3 MPI_REDUCE()

Proc0 Proc1 A Proc2 Proc3 A=A0+A1+A2+A3

Fig. 9: Fonction MP I _REDUCE (). Le processus P roc1 collecte les donnes A0,..., A3 provenant des processus P roc0 P roc3 et fait une opration de rduction. . MPI_ALL_REDUCE() qui permet de faire les mmes oprations de rduction que MPI_REDUCE(). La dirence est que le rsultat de lopration de rduction est connu de tous les processus dun mme communicateur. MPI_ALL_REDUCE(val_emis, val_recu, taille_emis, type_emis, operation, comm, code).

Proc0 A0 Proc1 A1 Proc2 A2 Proc3 A3 MPI_ALLREDUCE()

Proc0 A Proc1 A Proc2 A Proc3 A A=A0+A1+A2+A3

Fig. 10: Fonction MP I _ALLREDUCE (). Opration de rduction et diusion du rsultat lensemble des processus.

15

Optimisation dun programme parallle

Loptimisation dun code squentiel concerne la minimisation du temps de calcul. Lorsquon paralllise un code, un autre temps sajoute au temps de calcul, cest le temps de communication entre les processus (temps total = temps calcul + temps communication). Loptimisation dun code parallle consiste donc minimiser le temps de communication entre les processus. Celui-ci peut tre mesur via la fonction MPI_WTIME(). Avant de se lancer dans loptimisation dun programme parallle, il faut dabord comparer le temps de calcul et le temps de communication au temps total de simulation. Si le temps de communication est prpondrant devant le temps de calcul, alors on peut passer la phase doptimisation. Cette tape consiste rduire le temps de communication. Celui-ci contient un temps de prparation du message et un temps de transfert. Le temps de prparation contient un temps de latence pendant lequel les paramtres rseaux sont initialiss. Le reste du temps de prparation des messages (appel aussi temps de surcot) est li limplmentation MP I et au mode de transfert utilis (voir gure 11 pour plus de dtails). Il existe plusieurs possibilits pour optimiser le temps de communication, parmi elles : recouvrir les communications par des calculs. limiter les modes de transfert qui utilisent la recopie du message dans un espace mmoire temporaire (buf f ering ). limiter les appels rptitifs aux fonctions de communication MP I (qui cotent cher en temps).
TEMPS TOTAL DE SIMULATION

TEMPS DE CALCUL

TEMPS DE COMMUNICATION

TEMPS DE PREPARATION

TEMPS DE TRANSFERT

TEMPS DE LATENCE

TEMPS DE SURCOUT

Fig. 11: Composition du total de simulation dun programme parallle.

16

4.1

Modes denvoi des messages avec MP I

1. Standard : MP I choisit ou non de recopier le message envoyer dans une zone mmoire tampon du processus metteur. Sil y a recopie, laction denvoi se termine lorsque la recopie est termine, donc avant que la rception du message ait commence. Ceci permet de dcoupler lenvoi de la rception (asynchrone). Sil ny a pas recopie du message, lenvoi sachve une fois que le processus destinataire a bien reu le message. Lenvoi et la rception sont alors coupls (synchrone) (gures 12 et 13). MP I bascule automatiquement du mode asynchrone au mode synchrone suivant la taille des messages transfrer. Pour les petits messages, il y a recopie dans une zone tampon et pour les messages de grande taille, il ny a pas de recopie. 2. Synchroneous (synchrone) : lutilisateur impose un couplage entre lenvoi et la rception. Lenvoi peut commencer avant mme que lopration de rception ait t initialise. Lopration denvoi sachve une fois que lopration de rception a t poste (par le processus rcepteur) et le message bien reu (gure 13). 3. Buered : Lenvoi du message sachve une fois que la recopie du message dans une zone tampon est termine. Lenvoi et la rception sont dcoupls. Attention, lutilisateur doit eectuer lui-mme la recopie. Ce type denvoi est dconseill. 4. Ready : Lenvoi du message ne peut commencer que si la rception correspondante a DJ t poste, Sinon il y a erreur. Ce type denvoi est intressant pour les applications clients-serveurs.
SYSTEME SYSTEME

1. DEMANDE DENVOI

4. RECEPTION POSTEE ET TERMINEE

2. MPI RECOPIE 3. RECOPIE FINIE ENVOI FINI REPREND LA MAIN TRANSFERT

MEMOIRE

MEMOIRE

PROCESSUS EMETTEUR

PROCESSUS RECEPTEUR

Fig. 12: Envoi standard avec recopie.

17

SYSTEME

SYSTEME

TRANSFERT 1. DEMANDE DENVOI 2. RECEPTION POSTEE ET TERMINEE 3. ENVOI FINI REPREND LA MAIN

MEMOIRE

MEMOIRE

PROCESSUS EMETTEUR

PROCESSUS RECEPTEUR

Fig. 13: Envoi standard sans recopie ou envoi synchrone.

4.2
4.2.1

Communications bloquantes et non-bloquantes


Communications bloquantes

Lors de communications bloquantes, le processus qui eectue une action (de communication) ne rend la main quune fois laction termine. Envoi bloquant MPI_SEND() : Le processus metteur termine son action une fois que le message a t envoy et reu par le processus rcepteur. Rception bloquante MPI_RECV() : Le processus rcepteur ne rend la main que lorsquil a bien reu les donnes. 4.2.2 Communications non-bloquantes

Les communications non-bloquantes permettent doptimiser le temps de communication dans le sens o elles les recouvrent par des calculs. En eet, le processus qui eectue une opration de communication rend la main avant que lopration ait t termine. . Envoi non-bloquant MPI_ISEND() : le processus metteur initialise lopration denvoi mais ne la ralise pas. Lappel la fonction MP I sera termine avant que le message ne soit parti. Ainsi, son transfert partir de la mmoire du processeur metteur peut tre fait simultanment avec des calculs aprs linitialisation et avant lenvoi eectif. Attention, lutilisateur doit lui-mme sassurer que le message a bien t envoy avec des fonctions MP I adaptes (MPI_TEST() et MPI_WAIT()). La fonction MPI_ISEND(val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, comm, requete, code) possde un argument 18

de plus que la fonction MP I _SEND (), requete. Largument requete (< out >) : . identie lopration de communication, . contient des informations sur lopration de communication, savoir le mode denvoi, la destination du message, ... . fait correspondre lopration dinitialisation de la communication et celle de ralisation de la communication. . Rception non-bloquante MPI_IRECV() : Le processus rcepteur initialise la rception mais ne la ralise pas. Lappel la fonction MP I sera termine avant que le message ne soit reu. Ainsi, la rception du message par le processus rcepteur peut tre faite simultanment avec des calculs aprs linitialisation et avant la rception eective. Attention, lutilisateur doit lui-mme sassurer que le message a bien t reu avec des fonctions MP I adaptes (MPI_TEST() et MPI_WAIT()). Pour sassurer que lopration de communication a bien t eectue, lutilisateur peut utiliser deux fonctions MP I : MPI_TEST(requete, f lag , statut) : cette fonction permet de tester si lopration de communication, identie par requete (< in >), est termine. MP I _T EST retourne 2 arguments de sortie (< out >) f lag et statut. Si lopration de communication est termine, alors f lag = .true.. Sinon f lag = .f alse.. MPI_WAIT (requete, statut) : cette fonction oblige lopration de communication, identie par requete (< in >), sachever.

4.3

Synthse
mode envoi standard envoi synchrone rception bloquant MP I _SEND () MP I _SSEND () MP I _RECV () non-bloquant MP I _ISEND () MP I _ISSEND () MP I _IRECV ()

Tab. 4: Principaux modes de transfert Arguments des direntes fonctions MP I du tableau 4 : MP I _SEND (val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, comm, code) MP I _ISEND (val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, requete, code) MP I _SSEND (val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, requete, code) 19

MP I _ISSEND (val_emis, taille_emis, type_emis, rang _proc_dest, tag _emis, requete, code) MP I _RECV (val_recu, taille_recu, type_recu, rang _proc_dest, tag _recu, comm, statut, code) MP I _IRECV (val_recu, taille_recu, type_recu, rang _proc_dest, tag _recu, comm, requete, code)

20

Types de donnes drivs

Dans les communications MP I , les donnes transfres sont types. MP I dispose de types prdnis comme MP I _INT EGER, MP I _REAL, ... On peut crer des structures de donnes plus complexes, soit homognes (constitus de donnes de mme type) soit htrognes (constitus de donnes de types dirents). La cration dun type driv doit tre suivi de sa validation via la fonction MPI_TYPE_COMMIT(). Pour rutiliser le mme type driv, il faut dabord le librer avec la fonction MPI_TYPE_FREE(). Attention, il faut viter de passer directement des sections de tableaux. Mieux vaut passer par les types drivs !

5.1
5.1.1

Types de donnes drivs homognes


Donnes contiges

On peut construire une structure de donnes homognes partir dun ensemble de donnes, de type prdni, contiges en mmoire, via la fonction MPI_TYPE_CONTIGUOUS(nb_element, old_type, new _type, code) : . nb_element (< in >) est le nombre dlments de type prdni mettre dans le type driv, . old_type (< in >) est le type des lments qui constitue le nouveau type driv, . new_type (< out >) est le nom du nouveau type driv et code le retour derreur, . code (< out >) est le code derreur.

A11 A21 A31

A12 A22 A32

A13 A23 A33

A14 A24 A34

Fig. 14: cration dun type driv colonne partir dune matrice de rels Ai,j , i [1, 3], j [1, 4]. nb_element = 3, old_type = MP I _REAL

21

Les donnes contiges peuvent reprsenter une colonne dune matrice de rels Ai,j , i [1, 3], j [1, 4], par exemple (partie colore en jaune de la gure 14). 5.1.2 Donnes non contiges avec un pas constant

On peut construire une structure de donnes homognes partir dun ensemble de donnes, de type prdni, distantes dun pas constant en mmoire. Le pas peut tre donn en nombre dlments : cest le cas par exemple pour passer une ligne dune matrice de rels Ai,j , i [1, 3], j [1, 4],par exemple (partie colore en jaune de la gure 15). Dans ce cas, on utilise la fonction MPI_TYPE_VECTOR(nb_blocs, longueur _bloc, pas, old_type, new _type, code). . nb_blocs (< in >) est le nombre de blocs, . longueur_bloc (< in >) est le nombre dlments (de type old_type) dans chaque bloc, . pas (< in >) est le nombre dlments (de type old_type) entre chaque dbut de bloc, . old_type (< in >) est le type de llment partir duquel on souhaite crer un type driv, . new_type (< out >) est le type driv. Le pas peut tre donn en nombre doctets : cest le cas lorsque le type driv est construit partir de types plus complexes que les types prdnis. Dans ce cas, on utilise la fonction MPI_TYPE_CREATE_HVECTOR(nb_blocs, longueur _bloc, pas, old_type, new _type, code) : . nb_blocs (< in >) est le nombre de blocs, . longueur_bloc (< in >) est le nombre dlments (de type old_type) dans chaque bloc, . pas (< in >) est le nombre doctets (de type old_type) entre chaque dbut de bloc. Il doit tre dclar comme : integer(kind=MPI_ADDRESS_KIND) : :pas. . old_type (< in >) est le type de llment partir duquel on souhaite crer un type driv. . new_type (< out >) est le type driv. 22

pas

A11 A21 A31

A12 A22 A32

A13 A23 A33

A14 A24 A34

longueur_bloc nb_blocs

Fig. 15: cration dun type driv ligne partir dune matrice de rels Ai,j , i [1, 3], j [1, 4]. nb_blocs = 4, longueur _bloc = 1, pas = 3, old_type = MP I _REAL.

5.1.3

Donnes non contiges avec un pas variable

On peut construire une structure de donnes homognes compose dune squence de blocs contenant un nombre variable dlments de type prdni et dont les blocs sont distants dun pas variable en mmoire.
Old_type 1 New_type 0 nb_blocs=3 2 longueur_bloc=(1,2,3) 6 deplacement=(0, 2, 6), en nombre delements 2 3

Fig. 16: Construction dune MP I _T Y P E _INDEXED.

structure

de

donnes

avec

Le pas peut tre donn en nombre dlments : Dans ce cas on utilise la fonction MPI_TYPE_INDEXED(nb_blocs, longueur _bloc, deplacement, old_type, new _type, code). 23

nb_blocs (< in >) est le nombre de blocs, longueur_bloc (< in >) est un tableau de dimension nb_blocs contenant le nombre dlments de type old_type par bloc, deplacement (< in >) est un tableau de dimension nb_blocs contenant lespacement entre chaque bloc. Cet espacement est donn en multiple de old_type (voir gure 16). Le pas peut tre donn en nombre doctets quand la structure est construite partir dlments de type plus complexes que ceux prdnis : Dans ce cas on utilise la fonction : MPI_TYPE_CREATE_HINDEXED (nb_blocs, longueur _bloc, deplacement, old_type,new _type,code). nb_blocs (< in >) est le nombre de blocs, longueur_bloc (< in >) est un tableau de dimension nb_blocs contenant le nombre dlments de type old_type par bloc, deplacement (< in >) est un tableau de dimension nb_blocs contenant lespacement entre chaque bloc. Cet espacement est donn en octets (voir gure 17) et doit tre dclare comme integer (kind = MP I _ADDRESS _KIND ), dimension(nb_blocs) :: pas.
Old_type 1 New_type 0 nb_blocs=3 3 longueur_bloc=(1,2,3) 10 deplacement=(0, 3, 10), en nombre doctets 2

= 1octet 3

Fig. 17: Construction dune structure MP I _T Y P E _CREAT E _HINDEXED.

de

donnes

avec

5.2

Types drivs htrognes

Cest le constructeur le plus gnral. Il permet de crer des types de donnes htrognes quivalent des structures en C ou des types drivs en F ortran90. Pour cela, il faut dabord crer une structure constitue dlments de types dirents.

24

On utilise ensuite la fonction MPI_TYPE_CREATE_STRUCT(nb_elements, longueur _bloc, deplacement, tableau_types,new _type,code) (voir gure 18). nb_elements (< in >) est le nombre dlments de la structure, chaque lment constitue un bloc. longueur_bloc (< in >) est un tableau de dimension nb_elements contenant le nombre dlments de chaque bloc de la structure, deplacement (< in >) est un tableau de dimension nb_elements contenant ladresse de chaque dbut de bloc par rapport celle du premier bloc, en octets. Il doit tre dclar comme : integer (kind = MP I _ADDRESS _KIND ), dimension(nb_blocs) :: deplacement. On dtermine cette adresse via la fonction MPI_GET_ADDRESS(element_struct,adress_element, code). tableau_types (< in >) est un tableau de dimension nb_elements contenant le type de chaque bloc de la structure. new_type (< out >) est le nouveau type de donnes.
type1 Old_types 2 New_type 0 nb_blocs=5 longueur_bloc=(2, 1, 2, 3, 1) 3 7 13 16 1 2 type2 type3 = 1octet 3 1

tab_types=(type1, type2, type3, type1, type3) deplacement=(0, 3, 7, 13, 16), en nombre doctets

Fig. 18: Construction dune structure de donnes htrogne avec MP I _T Y P E _CREAT E _ST RUCT .

5.3
5.3.1

Exemples
Exemples sur des types de donnes drivs homognes

Exemple1 : Construction dun type sous matrice avec la fonction MP I _T Y P E _V ECT OR() : On construit un type driv sous-matrice partir dlments dune matrice de rels (voir programme gure 19). 25

Fig. 19: Construction de la transpose dune matrice laide de types drivs : programme en F ortran90.

26

Exemple2 : construction de la transpose dune matrice laide de type drivs (gures 20 et 21) (fonctions MP I _T Y P E _V ECT OR et MP I _T Y P E _CREAT E _HV ECT OR) : on construit un type ligne partir dlments dune matrice de rels, puis un type driv transpose (correspondant la transpose dune matrice) partir du type driv ligne.

Fig. 20: Construction de la transpose dune matrice laide de types drivs : programme.

Exemple3 : construction de matrices partir de types drivs homognes pas variables (fonctions MP I _T Y P E _INDEXED()) (gure 23 et son rsultat sur la gure 22).

27

Fig. 21: Construction de la transpose dune matrice laide de types drivs : rsultat.

Fig. 22: rsultat du programme triangle.f 90 (gure du cours de lIdris).

5.3.2

Exemples sur des types drivs htrognes

La gure montre un exemple de programme en F ortran90 utilisant une structure de donnes htrogne :

28

Fig. 23: Programme montrant lchange de sous matrices triangulaires entre deux processus.

29

Fig. 24: Interaction de MP I _T Y P E _CREAT E _ST RUCT .

deux

particules

avec

30

Topologies

MP I permet de dnir des topologies virtuelles de type cartsien ou graphe. Ces topologies font correspondre le domaine de calcul une grille de processus et permettent donc de rpartir les processus de manire rgulire sur le domaine de calcul. Ceci se rvle trs utile pour les problmes de type dcomposition de domaine.

6.1

Topologies de type cartsien

Dans cette topologie : chaque processus est dni dans une grille de processus, la grille peut tre priodique ou non, les processus de cette topologie sont identis par leurs coordonnes dans la grille. 6.1.1 Cration dune topologie cartsienne

Pour crer une topologie cartsienne contenant un ensemble de processus qui appartienne un communicateur donn (comm_ancien), on utilise la fonction : MPI_CART_CREATE(comm_ancien, ndims, dims, periods, reorganisation, comm_nouveau, code). . comm_ancien (< in >) : entier indiquant le nom de lancien communicateur (par dfaut MP I _COMM _W ORLD ), . ndims (< in >) : entier indiquant la dimension despace (2 pour 2D ), . dims (< in >) : tableau dentiers de dimension ndims indiquant le nombre dlments suivant chaque direction, . periods (< in >) : tableau de logicals de dimension ndims indiquant la periodicit (true pour oui), . reorganisation (< in >) : logical, reorganisation = true si renumrotation des processus dans comm_nouveau (conseill mais faire trs attention), reorganisation = f alse sinon. Si reorganisation = true, MP I renumrote les processus suivant laxe y puis x en 2D , suivant laxe z , y puis x en 3D . . comm_nouveau (< out >) : nom du nouveau communicateur (de type entier). . code (< out >) : code de retour (de type entier). Attention, cette communication est collective, elle concerne donc lensemble des processus appartenant comm_ancien.

31

6.1.2

Quelques fonctions utiles

. La fonction MPI_DIMS_CREATE(nb_procs, ndims, dims, code) dtermine le nombre de processus suivant chaque dimension de la grille en fonction du nombre total de processus. . nb_procs (< in >) est un entier indiquant le nombre de processus, . ndims (< in >) est un entier indiquant la dimension despace, . dims (< inout >) est un tableau dentiers de dimension ndims indiquant le nombre dlments suivant chaque direction. Si en entre, dims est un tableau dentiers nuls, cest MP I qui rpartit les processus dans chaque direction en fonction du nombre total de processus. Le tableau 5 montre quelques rpartitions de processus en fonction de la valeur initiale de dims (voir aussi la gure 25). . code (< out >) est le code derreur. Entres < in > Sortie < out > nb_procs ndims dims dims 8 2 (0, 0) (4, 2) 16 3 (0, 0, 0) (4, 2, 2) 16 3 (0, 4, 0) (2, 4, 2) 16 3 (0, 3, 0) error Tab. 5: Rpartition des processus avec la fonction MP I _DIMS _CREAT E dans une topographie cartsienne par MP I . . La fonction MPI_CART_RANK(comm_nouveau, coords, rang , code) donne le rang rang du processus associ au coordonnes coords dans la grille (voir aussi la gure 25). . comm_nouveau (< in >) est un entier indiquant le nouveau communicateur, . coords (< in >) est un tableau dentiers de dimension ndims contenant les coordonnes du processus de rang rang dans la grille, . rang (< out >) est un entier indiquant le rang du processus ayant pour coordonnes coords . code (< out >) est le code derreur (type entier). . La fonction MPI_CART_COORDS(comm_nouveau, rang , ndims, coords, code) est la fonction inverse de MP I _CART _RANK dans le sens o elle donne les coordonnes coords dun processus de rang rang dans la grille. . comm_nouveau (< in >) est un entier indiquant le nouveau communicateur, . rang (< in >) est un entier indiquant le rang du processus, 32

Proc1 (0,1)

Proc3 (1,1)

Proc5 (2,1)

Proc7 (3,1)

Proc0 (0,0)

Proc2 (1,0)

Proc4 (2,0)

Proc6 (3,0) X

Fig. 25: Rpartition de 8 processus (P roc0 P roc7) choisi par MP I sur la grille. Chaque processus a des coordonnes. . ndims (< in >) est un entier indiquant le nombre de dimensions, . coords (< out >) est un tableau dentiers de dimension ndims contenant les coordonnes du processus de rang rang dans la grille. (voir aussi la gure 25). . La fonction MPI_CART_SHIFT(comm_nouveau, direction, pas, rang _precedent, rang _suivant, code) donne le rang des processus voisins (rang _precedent et rang _suivant) dans la direction choisie, direction. . comm_nouveau (< in >) est un entier indiquant le nouveau communicateur. . direction (< in >) est un entier indiquant la direction dans laquelle on va chercher les rangs des processus voisins. direction = 0 suivant x et direction = 1 suivant y (gure 25). . pas (< in >) correspond au dplacement, pas = 1 pour les voisins directs (type entier). . ndims (< in >) est un entier indiquant le nombre de dimensions. . rang_precedent (< out >) est le rang du processus voisin Ouest si direction = 0, Sud si direction = 1. . rang_suivant (< out >) est un entier indiquant le rang du processus voisin Est si direction = 0, Nord si direction = 1. . code (< out >) est un entier indiquant le code derreur.

33

6.1.3

Exemple

La gure 26 montre comment on peut utiliser les direntes fonctions MP I concernant la topologie cartsienne.

Fig. 26: programme F 90 montrant lutilisation des direntes fonctions de topologie cartsienne

34

6.2

Topologies de type graphe

Lorsque la gomtrie du domaine de calcul devient complexe, la topologie de graphe de processus est plus approprie. On peut alors rpartir les processus sur des sous domaines de gomtries complexes elles aussi. Chaque processus peut avoir un nombre quelconque de voisins. 6.2.1 Cration dune topologie de type graphe
Proc3 Numero Proc 0 Proc0 Proc1 Proc2 1 2 3 Proc4 4 Numero proc voisins 1 0, 2, 3 1, 3, 4 1, 2, 4 2, 3

nb_procs=5

index(1, 4, 7, 10, 12)

liste_voisins=(1, 0,2,3, 1,3,4, 1,2,4, 2,3)

Fig. 27: Exemple de topologie de type graphe.

La fonction MPI_GRAPH_CREATE(comm_ancien, nb_procs, index, liste_voisins, reorganisation, comm_nouveau, code) permet de crer ce type de topologie (voir gure 27 pour exemple). comm_ancien (< in >) : nom de lancien communicateur (par dfaut MP I _COMM _W ORLD ), nb_procs (< in >) : entier indiquant le nombre de processus. index (< in >) : tableau dentiers de taille nb_procs indiquant pour chaque processus lindice du tableau liste_voisins qui contient le dernier voisin. liste_voisins (< in >) : tableau dentiers de taille le nombre total de voisins (sur tous les processus) indiquant successivement les rangs des processus voisins pour chaque processus. reorganisation (< in >) : logical, reorganisation = true si renumrotation des processus dans comm_nouveau (conseill mais faire trs attention), reorganisation = f alse sinon. Si reorganisation = true, MP I renumrote les processus suivant laxe y puis x en 2D , suivant laxe z , y puis x en 3D . 35

comm_nouveau (< out >) : nom du nouveau communicateur (de type entier). code(<out>) : code de retour (de type entier). 6.2.2 Quelques fonctions utiles

. La fonction MPI_GRAPH_NEIGHBORS_COUNT (comm_nouveau, rang , nb_voisins, code) dtermine le nombre de processus voisins pour un processus donn. . comm_nouveau (< in >) est un entier indiquant le nombre de processus, . rang (< in >) est un entier indiquant le rang du processus, . nb_voisins(< out >) est un entier indiquant le nombre de voisins, . code (< out >) est le code derreur. . La fonction MPI_GRAPH_NEIGHBORS(comm_nouveau, rang , nb_voisins, voisins, code) donne la liste des processus voisins pour un processus donn. . comm_nouveau (< in >) est un entier indiquant le nombre de processus, . rang (< in >) est un entier indiquant le rang du processus, . nb_voisins (< in >) est un entier indiquant le nombre de voisins, . voisins (< out >) est tableau dentiers de taille le nombre de voisins total, contenant la liste des voisins, . code (< out >) est le code derreur.

36

6.2.3

Exemple de lIdris : propagation dun feu de fort

Fig. 28: Programme en F 90 calculant la propagation dun feu de fort de parcelle en parcelle en utilisant une topologie de type graphe. (programme issu du cours de lIdris)

37

Fig. 29: Achage lcran des impressions du Programme de la gure 28. Le programme sarrte au bout de 10 itrations lorsque le critre darrt est vri.

Fig. 30: Visualisation de la propagation du feu de parcelle en parcelle (gure cours Idris).

38

7
7.1

Communicateurs
Introduction

Un communicateur est constitu dun ensemble de processus et dun contexte de communication. Ce contexte, mis en place lors de la construction du communicateur, permet de dlimiter lespace de communication et est gr par MP I . Par dfaut, cest le communicateur MPI_COMM_WORLD qui est cr lors de linitialisation de lenvironnement MP I . Celui-ci contient tous les processus actifs et cest au sein de cet ensemble quon eectue des oprations de communication. Cet ensemble de processus peut tre partitionn en plusieurs sous-ensembles de processus au sein desquels on pourra eectuer des oprations MP I . Ainsi, chaque sous-ensemble dispose de son propre espace de communication qui correspond en fait un communicateur. Les communicateurs peuvent-tre grs de manire dynamique. Ils sont crs en utilisant les fonctions MPI_CART_CREATE(), MPI_CART_SUB(), MPI_COMM_CREATE(), MPI_COMM_DUP() ou MPI_COMM_SPLIT(). Ils sont dtruits via la fonction MPI_COMM_FREE(). On peut se demander quelle est lutilit de crer un communicateur contenant un sous-ensemble de processus. Supposons quon dispose dun ensemble de processus dans le communicateur MP I _COMM _W ORLD . On souhaite eectuer des communications seulement entre les processus de rang pair. Une possibilit est de faire des tests (boucle if ) sur le rang de chaque processus, mais cela devient vite coteux..... Une autre possibilit consiste regrouper les processus de rang pair dans un nouveau communicateur, ce qui supprime les tests (pourvu quon prcise que les communications se font dans le nouveau communicateur).

7.2

Communicateur issu dun autre

La fonction MPI_COMM_SPLIT(comm, couleur , clef , nouveau_comm, code) partitionne un communicateur donn en autant de communicateurs voulus : . comm (< in >) est un entier dsignant le communicateur de dpart (quon veut partitionn), . couleur (< in >) est un entier. Une couleur est aecte chaque processus appartenant au mme sous-espace de communication. 39

. clef (< in >) est un entier qui permet MP I daecter un rang aux processus appartenant au mme sous-espace de communication. Il sagit dune numrotation locale. MP I attribue les rangs suivant des valeurs de clefs croissantes. Il est conseill de mettre la clef la plus petite sur le processus dtenant linformation distribuer (il aura ainsi le rang 0 dans la numrotation locale). . nouveau_comm (< out >) est un entier dsignant le nouveau communicateur. . code (< out >) est un entier donnant le code derreur. Un processus qui on attribue une couleur MPI_UNDEFINED nappartient qu son communicateur initial. Exemple : construction dun communicateur qui partage lespace de communication initial entre processus de rangs pairs et impairs via le constructeur MPI_COMM_SPLIT() : processus rang_global couleur clef rang_local P0 P1 P2 P3 P4 P5 0 1 2 3 4 5 10 20 10 20 10 20 6 1 0 2 5 0 2 1 0 2 1 0

Tab. 6: Construction du communicateur Comm_pair _impair avec MP I _COMM _SP LIT .

7.3

Subdivision de topologie

Lide consiste dgnrer une topologie cartsienne de processus de dimension despace dim en une topologie cartsienne de dimension (dim 1). Pour dgnrer une topologie cartsienne de dimension dim, il sut de crer des communicateurs de dimension (dim 1). Pour une topologie cartsienne de dimension dim = 2, la dgnrescence se traduit par la cration dautant de communicateurs quil y a de lignes, par exemple (voir gure 32). Les transferts dinformation se font alors au sein de chaque nouveau communicateur. Lintrt rside dans le fait quon peut eectuer des communications collectives restreintes un sous ensemble de processus appartenant la topologie dgnre. On peut dgnrer une topologie cartsienne soit partir de la fonction MPI_COMM_SPLIT() (dtaille prcdement)

40

Fig. 31: Programme en F 90 illustrant le partage de lespace de communication initial entre processus de rangs pairs et impairs.

41

soit partir de la fonction MPI_CART_SUB(CommCart, Subdivision, CommCartD, code) o : . CommCart (< in >) est un entier dsignant une topologie cartsienne, . Subdivision (< in >) est un tableau dentiers de dimension le nombre de communicateurs quon veut crer, . CommCartD (< out >) est un entier dsignant la topologie cartsienne dgnre, . code (< out >) est un entier dsignant le code derreur.
Y 2 1 0 P2 P1 P0 0 P5 v=c P4 v=b P3 v=a 1 P8 P7 P6 2 P12 P10 P9 3 X Y 2 1 0 P2 P1 P0 0 P5 v=c P4 v=b P3 v=a 1 P8 P7 P6 2 P12 P10 P9 3 X

Topologie cartesienne 2D

Topologie Cartesienne degeneree 1D Transfert information

Fig. 32: Topologie cartsienne 2D dgnre en topologie cartsienne 1D (subdivision en ligne).

7.4

Intra et intercommunicateur

Les intracommunicateurs sont des communicateurs qui eectuent des oprations de communication entre processus dun mme communicateur. Mais les communications entre communicateurs sont impossibles. Jusqu prsent, cest ce type de communicateur quon a construit. Un intercommunicateur est un communicateur qui permet dtablir des communications entre intracommunicateurs. Attention, dans le MP I 1 seules les communications point point sont permises. Pour crer un intercommunicateur, on utilise la fonction MPI_INTERCOMM_CREATE().

42

Fig. 33: Programme dgnrant une topologie cartsienne 2D en une topologie cartsienne 1D avec la fonction MP I _CART _SUB ().

43

Fig. 34: Programme dgnrant une topologie cartsienne 2D en une topologie cartsienne 1D avec la fonction MP I _COMM _SP LIT ().

44

Conclusion

La bibliothque MP I permet de faire du calcul parallle en se basant sur le principe dchanges de messages (communications) entre processus, chacun ayant sa propre mmoire. Ces oprations de communications peuvent tre collectives ou point point. Dans un code de calcul parallle, si le temps de communication devient prpondrant devant celui de calcul, on peut optimiser le temps de communication grce aux dirents modes de transfert de messages proposs par MP I ainsi quen recouvrant les communications par des calculs. MP I permet aussi de crer des topologies cartsiennes ou de type graphes (pour des gomtries de domaines plus complexes), ce qui est trs pratique lorsquon travaille sur des domaines de calcul ou quon souhaite faire de la dcomposition de domaine. MP I permet aussi de partitionner un ensemble de processus en plusieurs sous-ensembles de processus au sein desquels on pourra eectuer des oprations de communication. Ainsi, chaque sous-ensemble dispose de son propre espace de communication ou communicateur. Dans une nouvelle version de la bibliothque MP I (MP I 2), on note deux volutions principales : la gestion dynamique des processus et les EntresSorties parallles.

45

Vous aimerez peut-être aussi