• Aucun résultat trouvé

Algorithmes Parallèles et Distribués MPI 3. Aspects avancés de MPI Camille Coti Franck Butelle César Rodríguez

N/A
N/A
Protected

Academic year: 2022

Partager "Algorithmes Parallèles et Distribués MPI 3. Aspects avancés de MPI Camille Coti Franck Butelle César Rodríguez"

Copied!
6
0
0

Texte intégral

(1)

Algorithmes Parallèles et Distribués

MPI 3. Aspects avancés de MPI

Camille Coti Franck Butelle César Rodríguez

LIPN, Université Paris 13 Formation Ingénieurs SupGalilée Info 3 et AIR 3

12/2020

Transparents préparés par Camille Coti, modifiés par César Rodríguez et Franck Butelle

(AIR3 + INFO3) APD – MPI 3 12/2020 1 / 24

Plan

1 Décomposition de domaine 3

2 Création de nouveaux communicateurs : Topologies cartésiennes 8

3 Création de nouveaux types de données 15

4 Opérations définies par l’utilisateur 22

(AIR3 + INFO3) APD – MPI 3 12/2020 2 / 24

Décomposition de domaine

Plan

1 Décomposition de domaine 3

Maître-esclave 4

Découpage en grille 6

Ghost Region 7

2 Création de nouveaux communicateurs : Topologies cartésiennes 8

3 Création de nouveaux types de données 15

4 Opérations définies par l’utilisateur 22

Décomposition de domaine Maître-esclave

Maître-esclave

Distribution des données

Le maître distribue le travail aux esclaves

Le maître démultiplexe les données, multiplexe les résultats Les esclaves necommuniquent pasentre eux

Efficacité

Files d’attentes de données et résultats au niveau du maître On retrouve la partie séquentielle de la loi d’Amdahl Communications : maître↔esclaves

Les esclaves ne travaillent que quand ils attendent des données ou qu’ils envoient leurs résultats

Seuls les esclaves participent effectivement au calcul

Possibilité d’un bon speedup à grande échellesi les communications sont rares Peu rentable pour quelques processus

(2)

Décomposition de domaine Maître-esclave

Schéma du Maître-esclave

Maître

Escl 1 Escl 2 Escl 3 Escl 4 Escl 5

Équilibrage de charge Statique :

Ï Utilisation deMPI_Scatterpour distribuer les données

Ï MPI_Gatherpour récupérer les résultats

Dynamique :

Ï Modepull: les esclaves demandent du travail

Ï Le maître envoie les «chunks» 1 par 1

(AIR3 + INFO3) APD – MPI 3 12/2020 5 / 24

Décomposition de domaine Découpage en grille

Découpage en grille

Grille de processus

On découpe les données et on attribue un processus à chaque sous-domaine

Décomposition 1D Découpage en bandes

0 1 2 3

Décomposition 2D

Découpage en rectangles(préférable si très grande taille)

0 1 2 3

4 5 6 7

8 9 10 11

12 13 14 15

(AIR3 + INFO3) APD – MPI 3 12/2020 6 / 24

Décomposition de domaine Ghost Region

Ghost region

Frontières entre les sous-domaines

Un algorithme peut avoir besoin des valeurs des points voisins pour calculer la valeur d’un point

Traitement d’images (détection de contours...), automates cellulaires...

Réplication des données situées à la frontière

Chaque processus dispose d’un peu des données des processus voisins Mise à jour à la fin d’une étape de calcul

Création de nouveaux communicateurs : Topologies cartésiennes

Plan

1 Décomposition de domaine 3

2 Création de nouveaux communicateurs : Topologies cartésiennes 8

Création 9

Fonctions utiles 10

Exemples 11

sous-communicateurs 13

Communicateurs non cartésiens 14

3 Création de nouveaux types de données 15

4 Opérations définies par l’utilisateur 22

(3)

Création de nouveaux communicateurs : Topologies cartésiennes Création

Création d’une topologie cartésienne

Décomposition en structure géométrique

On transpose un communicateur sur une topologie cartésienne :

intMPI_Cart_create(MPI_Commcomm_old,intndims,const intdims[], const intperiods[],intreorder,MPI_Comm∗comm_cart)

0 1 2 3

4 5 6 7

8 9 10 11

12 13 14 15

En 2D

comm_old: le communicateur de départ ndims: ici 2

dims: nombre de processus dans chaque dimension (ici {4, 4}) periods: si on sort par un côté on revient par l’autre (1=vrai, 0=faux) reorder: autoriser ou non de modifier les rangs des processus

comm_cart: nouveau communicateur

(AIR3 + INFO3) APD – MPI 3 12/2020 9 / 24

Création de nouveaux communicateurs : Topologies cartésiennes Fonctions utiles

Fonctions utiles sur le nouveau communicateur

D’autres opérations sur les communicateurs avec topologie cartésienne :

intMPI_Cart_coords(MPI_Commcomm,intrang,intmaxdims,intcoords[]);

Permet d’obtenir lescoordonnéesd’un rang donné

intMPI_Cart_rank(MPI_Commcomm,intcoords[],int∗rang);

fonction inverse de la précédente :

Permet d’obtenir lerangdu processus associé aux coordonnées données Le rang est toujoursrelatifau communicateur !

intMPI_Cart_shift(MPI_Commcomm,intnumdim,intdeplact, int∗rang_src,int∗rang_dst);

Trouver les processusprécédant(rang_src) etsuivant(rang_dest) dans la dimension n°numdimavec un saut dedeplact(qui peut être<0 )

(AIR3 + INFO3) APD – MPI 3 12/2020 10 / 24

Création de nouveaux communicateurs : Topologies cartésiennes Exemples

Exemple (1/2)

intmain (intargc,char∗∗argv) { inttaille, rang, nrang, prev, succ;

intnbDims=1;

inttabDims[nbDims], newDims[nbDims];

intperiods[nbDims];

MPI_Commcomm;

MPI_Init(&argc, & argv);

MPI_Comm_size(MPI_COMM_WORLD, &taille);

MPI_Comm_rank(MPI_COMM_WORLD, &rang);

assert (taille >= 4);/∗ termine en cas d’échec du test ∗/

printf ("Je suis %d !\n", rang);

/∗ Une seule dimension, avec presque tous les threads ∗/

tabDims[0] = taille − 2;

periods[0] = 1;

MPI_Cart_create(MPI_COMM_WORLD, nbDims, tabDims, periods, 1, &comm);

Création de nouveaux communicateurs : Topologies cartésiennes Exemples

Exemple (2/2)

/∗ Certains threads n’appartiennent pas au nouveau communicateur ∗/

if(comm ==MPI_COMM_NULL) { printf ("Je suis %d, exclu !\n", rang);

}else{

/∗ Mon rang dans le nouv. communicateur ∗/

MPI_Comm_rank(comm, &nrang);

/∗ récupère mes coordonnées ∗/

MPI_Cart_coords(comm, nrang, nbDims, newDims);

printf ("%d: nouv. rang %d, x=%d\n", rang, nrang, newDims[0]);

MPI_Cart_shift(comm, 0, 1, &prev, &succ);

printf ("%d: nrang %d à dist 1: pre=%d succ=%d\n", rang, nrang, prev, succ);

MPI_Cart_shift(comm, 0, 2, &prev, &succ);

printf ("%d: nrang %d à dist 2: pre=%d succ=%d\n", rang, nrang, prev, succ);

MPI_Comm_free(&comm); /∗ pas sur ceux qui sont exclus ! ∗/

}

MPI_Finalize();

(4)

Création de nouveaux communicateurs : Topologies cartésiennes sous-communicateurs

Extraction de sous-communicateurs d’un comm. cartésien

intMPI_Cart_sub(MPI_Commcomm_old,

const intremain_dims[ ],MPI_Comm∗comm_new);

comm_old: le communicateur cartésien de départ

remain_dims: quelles dimensions sont dans le communicateur (1) ou non (0) comm_new: le nouveau communicateur contenant la sous grille dontfait partie le processus appelant.

X Y

Z

Exemple

Sicomm_olda une topologie (X,Y,Z) en 3×4×2 et remain_dimsest{1, 0, 1}, alors

MPI_Cart_sub() crée ? communicateurs avec une topologie en : ?

(AIR3 + INFO3) APD – MPI 3 12/2020 13 / 24

Création de nouveaux communicateurs : Topologies cartésiennes Communicateurs non cartésiens

Communicateurs non cartésiens

On peut créer des sous-communicateurs de communicateurs déjà créés MPI_Comm_create

MPI_Comm_split MPI_Graph_create MPI_Dist_graph_create . . .

(AIR3 + INFO3) APD – MPI 3 12/2020 14 / 24

Création de nouveaux types de données

Plan

1 Décomposition de domaine 3

2 Création de nouveaux communicateurs : Topologies cartésiennes 8

3 Création de nouveaux types de données 15

Schéma de fonctionnement 16

Bloc d’éléments contigus 17

Bloc d’éléments non contigus 18

Structures de données 20

4 Opérations définies par l’utilisateur 22

Création de nouveaux types de données Schéma de fonctionnement

Principe de fonctionnement

On définit le datatype (voir diapos suivantes)

Ï MPI_Type_contiguous,MPI_Type_vector,MPI_Type_indexed,MPI_Type_struct On l’enregistre(commit) "Obligatoire

Ï MPI_Type_commit(MPI_Datatype∗type) On peut récupérer sa taille en octets

Ï MPI_Type_size(MPI_Datatypetype,int∗ size) On le libère à la fin

Ï MPI_Type_free(MPI_Datatype∗type)

Extrait des types de base

MPI_CHAR MPI_SHORT MPI_INT

MPI_LONG MPI_UNSIGNED MPI_FLOAT MPI_DOUBLE MPI_LONG_DOUBLE MPI_BYTE MPI_UNSIGNED_CHAR MPI_UNSIGNED_SHORT MPI_UNSIGNED_LONG

(5)

Création de nouveaux types de données Bloc d’éléments contigus

Bloc d’éléments contigus

Création d’un block d’éléments :

int MPI_Type_contiguous(intcount,MPI_Datatypeoldtype, MPI_Datatype∗newtype );

NB :oldtypepeut être un type complexe.

oldtype

oldtype

oldtype

oldtype

VECTOR

(AIR3 + INFO3) APD – MPI 3 12/2020 17 / 24

Création de nouveaux types de données Bloc d’éléments non contigus

Bloc d’éléments non contigus

Vecteur de données

int MPI_Type_vector(intnbblocs,int longbloc , int pas,

MPI_Datatypeoldtype,MPI_Datatype∗newtype );

On lienbblocsblocs delongblocéléments séparés par un paspasd’éléments.

Exemple :nbblocs=3, longbloc=2, pas=5

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 ...

Quelles cases du tableaubuffsont envoyées ? intbuff[128];

MPI_Datatypedt;

intnbblocs=2, longbloc=2, pas=4;

MPI_Type_vector(nbblocs, longbloc, pas,MPI_INT, &dt);

MPI_Type_commit(&dt);

MPI_Send(buff, 2, dt, vois,tag,comm);//? ?

0 1 2 3 4 5 6 7 8 9 10 11 ...

(AIR3 + INFO3) APD – MPI 3 12/2020 18 / 24

Création de nouveaux types de données Bloc d’éléments non contigus

Recalculer la taille d’un bloc

Spécialement utile pour les blocs d’éléments non contigus

"Problème : Envoi de plusieurs blocs d’éléments non contigus

Les blocs d’éléments non contigus sont a priori inutilisables pour scatter, gather,...

Solution :

int MPI_Type_create_resized(MPI_Datatypeoldtype,MPI_Aintlb,MPI_Aintext, MPI_Datatype∗newtype)

Création d’un nouveau type identique à oldtype, sauf pour le calcul des offset : borne inf : lb(souvent 0) et borne sup :lb+ext(typiquement le premier sous élément d’un bloc d’éléments non contigus).

A la place du MPI_Send précédent

MPI_Type_create_resized(dt, 0, longbloc∗sizeof(int), &typeReduit);

MPI_Type_commit(&typeReduit);

MPI_Send(buff, 2, typeReduit, vois, tag, comm);

Création de nouveaux types de données Structures de données

Cas des struct

MPI n’a pas accès aux structures déclarées par le programmeur, il faut tout lui expliquer ! On donne les éléments, leur nombre et l’offset auquel ils sont positionnés :

intMPI_Type_create_struct(int count ,

int array_of_block_lengths[] ,

MPI_Aint array_of_displacements[] ,

MPI_Datatype array_of_types[] ,

MPI_Datatype *newtype );

count: nombre de champs dans la structure (taille des tableauxarray_of_...) array_of_block_lengths: nombre d’éléments dans le champ (pour les tableaux) array_of_displacements: permet à MPI de faire la (dé)sérialisation

array_of_types: idem, nécessaire pour la (dé)sérialisation newtype: le nom du nouveau type de données

(6)

Création de nouveaux types de données Structures de données

Création de type structuré — exemple

typedef struct{

inti; // bloc de 1 INT à l’adresse 0 doubled1;// bloc de 1 DOUBLE à l’adr. 8 doubled2;// bloc de 1 DOUBLE à l’adr. 16 charstr[5];// bloc de 5 CHAR à 2 l’adr. 24 } my_struct;

intlongblocs[4] = { 1, 1, 1, 5 };

MPI_Aintpositions[4] = {

offsetof (my_struct, i), // #include <stddef.h>

offsetof (my_struct, d1), offsetof (my_struct, d2), offsetof (my_struct, str) };

MPI_Datatypetypes[4] = {MPI_INT,MPI_DOUBLE,MPI_DOUBLE,MPI_CHAR};

MPI_Type_create_struct(4, longblocs, positions, types, &dt);

MPI_Type_commit(&dt);

(AIR3 + INFO3) APD – MPI 3 12/2020 21 / 24

Opérations définies par l’utilisateur

Plan

1 Décomposition de domaine 3

2 Création de nouveaux communicateurs : Topologies cartésiennes 8

3 Création de nouveaux types de données 15

4 Opérations définies par l’utilisateur 22

Création d’opération de réduction 23

Exemple 24

(AIR3 + INFO3) APD – MPI 3 12/2020 22 / 24

Opérations définies par l’utilisateur Création d’opération de réduction

Définition d’opérations de réduction

Syntaxe

Définition d’unenouvelle opérationà utiliser avec les opérations de réduction : intMPI_Op_create(MPI_User_function ∗function,intcommute,MPI_Op∗op);

La fonctionfunctiondoit avoir le prototype suivant :

voidMPI_User_function (void∗invec,void∗inoutvec,int∗len,MPI_Datatype∗dt);

La fonction doit être associative.

Elle peut être commutative (commute=1) ou pas

Opérations définies par l’utilisateur Exemple

Exemple d’implémentation de MPI_PROD avec des nombres complexes typedef struct{

doublereal,imag;

} Complex;

/∗ la fonction de l’utilisateur ∗/

voidmyProd(void∗inTab,void∗inoutTab,int∗len,MPI_Datatype∗dptr ) { Complex c; Complex ∗in = (Complex ∗) inTab;

Complex ∗inout = (Complex ∗) inoutTab;

for(inti=0; i< ∗len; ++i) {

c.real = inout−>real ∗ in−>real − inout−>imag∗in−>imag;

c.imag = inout−>real ∗ in−>imag + inout−>imag∗in−>real;

∗inout = c;

in++; inout++;

} }

intmain (intargc,char∗argv[]) { // ... declarations

MPI_Opmyop;

/∗ construction du type complexe pour MPI : 2 réels∗/

MPI_Type_contiguous(2,MPI_DOUBLE, &mpicomplex);

MPI_Type_commit(&mpicomplex);

/∗ creation de l’operateur ∗/

MPI_Op_create(myProd, 1, &myop);

//... initialisations

MPI_Reduce(sendBuf, recvBuf, 2, mpicomplex, myop, 0,MPI_COMM_WORLD);

//...

}

Références

Documents relatifs

3. Tout intervalle [a, b] ne rencontrant pas A ne contient qu’un nombre fini des u n. grande) valeur d’adh´ erence. de la suite (u

For a long time Mira variables, OH/IR- and Carbon- stars were the most frequently studied Asymptotic Giant Branch (AGB) objects.. The Semiregular (types SRa and SRb) and the

Parallélisme au niveau matériel Processeur super-scalaire.

1962 premier ordinateur multiprocs (4) mais système non parallèle 1964 premier ordi double cœur et premier ordinateur à structure parallèle.. 1965 premier

Algorithmes distribués classiques (1ère partie) Éveil distribué par inondation.

Tout mesg envoyé à un site est placé dans sa file d’attente.. L’ordonnanceur du réseau permet aux

Si on a un algo d’élection alors on a un algo d’AC (en ajoutant 2m messages et D unités de temps). AC −→ élection (en ajoutant n − 1 messages et h unités de temps, où h est

pire des cas atteint pour un anneau avec identités en ordre décroissant et tous initiateurs... Donc 3n −