calcul parallèle et distribué - jullian/downloads/cpd.pdf · mémoire distribuée remarques. di...

212
[email protected] http://www.lmpt.univ-tours.fr/~jullian/

Upload: others

Post on 15-Oct-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Calcul parallèle et distribué

Yann Jullian

Université François Rabelais

[email protected]://www.lmpt.univ-tours.fr/~jullian/

5 mars 2018

Page 2: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de base

Page 3: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Remarques

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

5 Distribution équitableExtension du tableau et MPI_Scatter

Distribution sous-optimale avec MPI_Scatterv

Distribution optimale avec MPI_Scatterv

6 Communications collectives : réductionsRéductions réparties : MPI_Reduce

Page 4: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Réductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

8 DeadlocksDé�nitionExemple

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguous

Page 5: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Extraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

10 CommunicateursPartitionner un communicateur

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lage

Mesures temporelles simples

MPIP

MPE

OPro�le

Autres problèmesOpérations �otantes

Race condition

Page 6: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 7: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire partagée

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 8: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire partagée

Une unique machine.

Tous les c÷urs de tous les processeurs ont accès à la mémoire.

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

Noeud 0

Mem

oire

Avantage

Parallélisation simple (OpenMP par exemple).

Inconvénient

Nombre de processeurs et mémoire limités au départ. Pas d'extensionpossible au delà de la capacité de la machine sur laquelle on exécute.

Page 9: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire distribuée

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 10: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire distribuée

Plusieurs machines connectées en réseaux.

Les processeurs d'un n÷ud n'ont pas accès aux mémoires des autresn÷uds.

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

C0 C1

C2 C3

Noeud 0 Noeud 1

Mem

oire

Mem

oire

Reseau

Avantage

On peut étendre le système en ajoutant des n÷uds.

Page 11: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire distribuée

Inconvénients

Nécessité de transférer la mémoire d'un n÷ud à l'autre.

Le coût de communication réseau peut être élevé si le volume dedonnées à communiquer est important.

Le coût d'un transfert réseau sera toujours beaucoup plus importantqu'une simple copie mémoire.

Page 12: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Mémoire distribuée

Remarques.

Di�érents threads d'un même processus ont accès à la mêmemémoire.

Di�érents processus n'ont jamais accès à la même mémoire, même siles processus sont lancés sur la même machine.

On peut donc aussi faire du calcul distribué avec une unique machine.

Page 13: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Exemples de clusters

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 14: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Exemples de clusters

Ada

332 n÷uds de calculs

4 processeurs Intel E5− 4650 (8 c÷urs) à 2.7 GHz par n÷ud

10624 c÷urs

46 To de RAM

233 T�ops théoriques, 192 T�ops (linpack)

Puissance : 244 kWatt

E�cacité énergétique : 786 M�ops / watt

http://www.idris.fr/ada/ada-presentation.html

Page 15: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Exemples de clusters

Turing

6144 n÷uds de calculs

16 processeurs POWER A2 (1 c÷ur) à 1.6 GHz par n÷ud

98304 c÷urs

96 To de RAM

1258 T�ops théoriques, 1073 T�ops (linpack)

Puissance : 493 kWatt

E�cacité énergétique : 2176 M�ops / watt

http://www.idris.fr/turing/turing-presentation.html

Page 16: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Message Passing Interface

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 17: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Message Passing Interface

Message Passing Interface (MPI)

C'est un ensemble de règles dé�nissant les communications entreprocessus, possiblement de n÷uds di�érents.

C'est l'outil standard pour les communications dans les clusters.

Il en existe plusieurs implémentations dans di�érents langages (C,C++ (abandonné avec MPI-3), Fortran) mais peut aussi être appelédepuis Java, Python. . .

Une implémentation fournit un ensemble de fonctions permettant lacommunication et les échanges de données.

Page 18: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Message Passing Interface

Principe d'un code utilisant MPI.

Plusieurs processus sont lancés en parallèle.

Chaque processus exécute le programme.

Le programme décrit le rôle de chaque processus.

La bibliothèque se focalise sur la synchronisation des processus etl'échange de données entre ceux-ci.

Page 19: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Message Passing Interface

Un message MPI est constitué de :

un communicateur (essentiellement un ensemble de processus),

un identi�cateur du processus émetteur,

le type de la donnée transférée,

sa longueur,

la donnée elle même,

un identi�cateur du processus récepteur.

Tous ces constituants devront être présent à l'appel des fonctions MPI.

Page 20: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Exemples de domaines d'applications

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 21: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Exemples de domaines d'applications

Prévisions météorologique,

Cryptographie,

Modélisation d'explosion nucléaire,

Astrophysique,

Dynamique des particules (calculs des interactions),

Pattern matching (comparaison d'ADN, traitement d'images).

Page 22: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Quelques liens

1 IntroductionMémoire partagéeMémoire distribuéeExemples de clustersMessage Passing InterfaceExemples de domaines d'applicationsQuelques liens

Page 23: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Introduction

Quelques liens

Implémentations open source.

MPICH2 : http://www.mpich.org

OpenMPI : http://www.open-mpi.org

Documentation.

http://www.open-mpi.org/doc/v1.10/

http://www.mpi-forum.org/docs/

Machines.

http://top500.org/

http://green500.org/

Sources.

http://www.idris.fr/data/cours/parallel/mpi/IDRISMPI.pdf

Page 24: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

Page 25: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Premier exemple

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

Page 26: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Premier exemple

// intro/minimal.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);printf("Sup.\n");MPI_Finalize();

return 0;}

Tout programme faisant appel à MPI doit :

inclure <mpi.h>,

initialiser l'environnement avec MPI_Init,

désactiver l'environnement avec MPI_Finalize.

Page 27: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Compilation, exécution

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

Page 28: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Compilation, exécution

$ mpicc -o source source.c

$ mpirun -n 2 source

mpicc n'est en fait qu'un appel élaboré à gcc :

mpicc -showme

L'option −n permet de préciser le nombre de processus à exécuter(en parallèle).

Si l'option −n est omise, le nombre de processus lancés dépend de lamachine.

La commande ci-dessus exécute source deux fois sur localhost eta�che :Sup.

Sup.

Page 29: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Compilation, exécution

L'option −host permet de préciser les machines à utiliser.

mpirun -host host0,host1 source

exécute source une fois sur host0 et une fois sur host1.

On peut combiner −n et −host. Si le nombre de processus donné estsupérieur au nombre de machine, on remonte à la première machine.

mpirun -n 3 -host host0,host1 source

exécute source une fois sur host0, une fois sur host1, puis une autrefois sur host0.

Page 30: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Compilation, exécution

On peut aussi utiliser l'option −host�le avec un �chier d'entrée.$ cat hostshost0 slots=2host1 slots=4

mpirun -n 7 -host�le hosts source

exécute source deux fois sur host0, quatre fois sur host1, puis unedernière fois sur host0.

man mpirun pour plus d'options et plus de détails sur le �chier hosts.

Page 31: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Comparaison avec OpenMP

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

Page 32: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Comparaison avec OpenMP

OpenMP

Une seule instance du programme est exécutée : il n'y a qu'un seulprocessus.

Le processus se divise en plusieurs threads exécutés en parallèle.

Les parties parallèles sont délimités par des directives pré-processeurs(#pragma).

MPI

Plusieurs instances du programme sont exécutées en même temps :plusieurs processus sont créés.

Chaque processus exécute l'intégralité du programme, et lesprocessus s'exécutent en parallèle.

MPI_Init et MPI_Finalize ne correspondent pas aux début et �n dela partie parallélisée.

Page 33: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Communicateur par défaut

2 EnvironnementPremier exempleCompilation, exécutionComparaison avec OpenMPCommunicateur par défaut

Page 34: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Communicateur par défaut

Les processus lancés par mpirun doivent pouvoir communiquer entre eux.

Tous les processus sont reliés par le communicateur par défaut

MPI_COMM_WORLD.

MPI_COMM_WORLD est créé par MPI_Init et détruit par MPI_Finalize.

Chaque processus a un rang qui l'identi�e dans MPI_COMM_WORLD.

C'est grâce à ce rang qu'on e�ectue le partage des tâches.

Toutes les communications entre processus passent par uncommunicateur.

Page 35: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Communicateur par défaut

// intro/default_comm.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);

int world_size;MPI_Comm_size(MPI_COMM_WORLD, &world_size);

int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);if (wrank!=1)

printf("Rang %d sur %d.\n", wrank, world_size);

MPI_Finalize();return 0;

}

Page 36: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Environnement

Communicateur par défaut

$ mpirun -n 4 sourceRang 2 sur 4.Rang 0 sur 4.Rang 3 sur 4.

Chaque processus de rang 6= 1 appelle printf (une seule fois) avecson rang.

L'ordre de sortie est indé�ni.

Page 37: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 38: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Principe

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 39: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Principe

Une communication dite point à point a lieu entre deux processus :l'émetteur et le récepteur (ou destinataire).

L'émetteur et le récepteur sont identi�és par leur rang dans lecommunicateur.L'enveloppe d'un message est constituée :

du communicateur (qui doit contenir les deux processus),du rang du processus émetteur,du rang du processus récepteur,de l'étiquette (un identi�ant) du message.

Il faut préciser le type des données communiquées.

Il existe plusieurs modes de transfert.

Page 40: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Exemple

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 41: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Exemple

int MPI_Ssend(const void *buf, int count, MPI_Datatype datatype,

int dest, int tag, MPI_Comm comm);

int MPI_Recv(void *buf, int count, MPI_Datatype datatype,

int source, int tag, MPI_Comm comm, MPI_Status *status);

comm : le communicateur.

tag : l'identi�ant du message.

dest/source : le rang du processus récepteur/émetteur dans lecommunicateur comm.

datatype : le type des données à envoyer/recevoir.

count : le nombre de données de type datatype à envoyer/recevoir.

buf : l'adresse du début des données à envoyer/recevoir.

Page 42: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Exemple

// intro/send-receive.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int witness = 0;if (wrank==2){

int modifier = 1;MPI_Ssend(&modifier, 1, MPI_INT, 3, 28, MPI_COMM_WORLD);

}else if (wrank==3)

MPI_Recv(&witness, 1, MPI_INT, 2, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

printf("Rang %d, witness %d.\n", wrank, witness);MPI_Finalize();return 0;

}

Page 43: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Exemple

$ mpirun -n 4 sourceRang 1, witness 0.Rang 0, witness 0.Rang 2, witness 0.Rang 3, witness 1.

Pour passer plusieurs valeurs :

// intro/send-receive.cint witness[] = {0, 0};if (wrank==2){

int modifier[] = {1, 1};MPI_Ssend(modifier, 2, MPI_INT, 3, 28, MPI_COMM_WORLD);

}else if (wrank==3)

MPI_Recv(witness, 2, MPI_INT, 2, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

Page 44: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Exemple

Pour toutes les communications, il faut préciser à la fois un typepour l'émission et un type pour la réception.

Le tag de MPI_Ssend doit correspondre à celui de MPI_Recv, sinon lacommunication échoue.

Le transfert de données se fait grâce à un simple �ux d'octets (pasde données sur le type).

C'est au programmeur de véri�er que les types d'émission et deréception sont les mêmes, ou au moins qu'ils sont compatibles (voirexemples frames 153 et 158).

Note.

La communication réussira si le nombre d'octets émis est égal aunombre d'octets reçus. Ainsi, on peut par exemple envoyer untableau de deux int et recevoir un seul long ou même un seul double.

Page 45: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Précisions sur le tag

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 46: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Précisions sur le tag

Le tag doit être un entier compris entre 0 et une valeur dépendantedu système, obtenu par le programme suivant.

// tag.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int flag;int* max_tag;MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB,

&max_tag, &flag);printf("Maximum tag : %d.\n", *max_tag);MPI_Finalize();

return 0;}

Ce maximum est toujours ≥ 32767.

Page 47: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Précisions sur le tag

Réutiliser le même tag pour plusieurs communications successivesn'est pas un problème : l'ordre de réception est le même que

l'ordre d'envoi, quelque soit le mode de communication.

À la réception d'un message, le rang de l'émetteur et l'étiquettepeuvent être des � jokers �, respectivement MPI_ANY_SOURCE etMPI_ANY_TAG.

Page 48: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Types de données de base

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 49: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Types de données de base

Type MPI Type C Taille des types C (octets)MPI_CHAR char 1

MPI_SHORT short 2

MPI_INT int 4

MPI_LONG long int 8

MPI_UNSIGNED_CHAR unsigned char 1

MPI_UNSIGNED_SHORT unsigned short 2

MPI_UNSIGNED unsigned int 4

MPI_UNSIGNED_LONG unsigned long int 8

MPI_FLOAT float 4

MPI_DOUBLE double 8

MPI_LONG_DOUBLE long double 16

Tous les types MPI_* ont pour taille 8 octets.

Page 50: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Remarques

3 Communications point à pointPrincipeExemplePrécisions sur le tagTypes de données de baseRemarques

Page 51: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications point à point

Remarques

Le processus récepteur ne sort de l'appel à MPI_Recv que lorsquel'intégralité du message du tag spéci�é a été reçu.

Le comportement du processus émetteur est plus compliqué (voirsection 7).

MPI_STATUS_IGNORE est une constante prédé�nie qui peut être utiliséeà la place de la variable statut.

On peut créer et communiquer des structures de données pluscomplexes (voir frame 165).

Page 52: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 53: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Notions générales

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 54: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Notions générales

Les communications collectives permettent de faire en une seuleopération une série de communications point à point.

Une communication collective concerne toujours tous les processusdu communicateur indiqué.

Pour chacun des processus, l'appel se termine lorsque la participationde celui-ci à l'opération collective est achevée, au sens descommunications point-à-point.

On ne dé�nit jamais les étiquettes explicitement ; le système les gèrede manière transparente. Avantage : les communications collectivesn'interfèrent jamais avec les communications point à point.

Page 55: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Notions générales

Il y a trois types de communications collectives.

1 Synchronisation globale : MPI_Barrier.2 Transfert de données uniquement :

di�usion globale de données : MPI_Bcast,di�usion sélective de données : MPI_Scatter, MPI_Scatterv,collecte de données réparties : MPI_Gather, MPI_Gatherv,collecte par tous les processus de données réparties : MPI_Allgather,collecte et di�usion sélective, par tous les processus, de donnéesréparties : MPI_Alltoall.

3 Transfert et e�ectue des opérations sur des données :réduction (somme, produit, maximum, minimum, etc.), qu'elles soientd'un type prédé�ni ou d'un type personnel : MPI_Reduce,réduction avec di�usion du résultat (équivalent à un MPI_Reduce suivid'un MPI_Bcast ) : MPI_Allreduce.

Page 56: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 57: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

int MPI_Barrier(MPI_Comm comm);

Barrier

P1

P3 P0 P1 P2 P3

P2

P0

attente des processus 0, 1, 2.

Tous les processus ont

Les processus reprennent

Processus 3 bloqué en

atteints la barrière.

leurs exécutions.

P0

P1

P2

P3

Tous les processus du communicateur doivent appeler la fonctionMPI_Barrier.

Un processus qui appelle la fonction reste bloqué et doit attendreque tous les autres processus du communicateur l'appellent.

Lorsque tous les processus du communicateur ont appelé la fonction,tous reprennent ensemble leurs exécutions.

Page 58: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

// collectives/barrier.c#include <mpi.h>#include <stdio.h>#include <time.h>

int main(int argc, char ** argv){

MPI_Init(&argc, &argv);

int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

if (wrank==0){

FILE* f = fopen("outin", "w");long int seconds = time(NULL);fprintf(f, "%ld", seconds);fclose(f);

}

MPI_Barrier(MPI_COMM_WORLD);

Page 59: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

long int witness = 0;FILE* f = fopen("outin", "r");fscanf(f, "%d", &witness);printf("Rang %d, witness %ld.\n", wrank, witness);fclose(f);

MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 1, witness 1450259857.Rang 0, witness 1450259857.Rang 2, witness 1450259857.

Rang 3, witness 1450259857.

Page 60: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

Sortie possible si on enlève l'appel à MPI_Barrier.

$ mpirun -n 4 sourceRang 1, witness 1450259857.Rang 3, witness 1450259857.Rang 0, witness 1450259860.

Rang 2, witness 1450259860.

Dans ce cas, les processus 1 et 3 ont lu le �chier avant que celui-cine soit modi�é par le processus 0, et ils récupèrent donc la valeurcontenue dans le �chier avant l'exécution du programme.

Les processus 0 et 2 ont lu le �chier après modi�cation, etrécupèrent donc la nouvelle valeur.

Page 61: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

Remarques

La fonction MPI_Barrier ne prend pas d'identi�ant de message enargument. La conséquence est que les processus peuvent appeler desMPI_Barrier di�érents (situés à di�érents endroits du programme).Ainsi, le code

if (wrank==0)MPI_Barrier(MPI_COMM_WORLD);

elseMPI_Barrier(MPI_COMM_WORLD);

aura le même e�et que

MPI_Barrier(MPI_COMM_WORLD);

Page 62: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Synchronisation globale : MPI_Barrier

En interne, MPI_Barrier e�ectue les étapes suivantes :Chaque processus de rang 6= 0 envoie un message vide au processusde rang 0 et attend une réponse,le processus de rang 0 attend d'avoir reçu des messages de tous lesprocessus (sauf lui même),lorsque le processus 0 a reçu tous les messages, il envoie une réponse(un autre message vide) à tous les processus, leur signalant ainsi quetous les processus ont atteints une barrière,les processus 6= 0 quittent MPI_Barrier à la reception de cetteréponse,le processus 0 quitte MPI_Barrier après l'envoi de toutes les réponses.

MPI_Barrier est l'unique fonction qui permet d'assurer lasynchronisation entre les processus. En particulier, aucune desopérations collectives présentées par la suite n'assure lasynchronisation.

Page 63: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion générale : MPI_Bcast

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 64: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion générale : MPI_Bcast

int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype,

int root, MPI_Comm comm);

P0

P1

P2

P3

count

Tous les processus du communicateur doivent appeler la fonctionMPI_Bcast.

Le processus de rang root est l'unique émetteur, tous sont récepteurs.

Après l'appel, les count données de type datatype pointées par buffersont égales pour tous les processus.

Page 65: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion générale : MPI_Bcast

// collectives/bcast.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int witness = wrank;MPI_Bcast(&witness, 1, MPI_INT, 2, MPI_COMM_WORLD);

printf("Rang %d, witness %d.\n", wrank, witness);MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 1, witness 2.Rang 0, witness 2.Rang 2, witness 2.

Rang 3, witness 2.

Page 66: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion sélective : MPI_Scatter

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 67: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion sélective : MPI_Scatter

int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,

int root, MPI_Comm comm);

P0

P1

P2

P3

Tous les processus du communicateur doivent appeler la fonctionMPI_Scatter.

Le processus de rang root est l'unique emetteur, tous sont récepteurs.

sendcount est le nombre de données émises à un seul processus.

Page 68: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion sélective : MPI_Scatter

MPI_Scatter découpe la donnée à envoyer en plusieurs (autant que deprocessus dans le communicateur) morceaux de taille sendcount.L'ordre des données envoyés correspond à l'ordre des rangs desprocessus récepteurs : le ième jeu de données est envoyé auprocessus de rang i .Le nombre total de données émises est sendcount * (nombre deprocessus dans le communicateur).sendcount*sizeof(sendtype (en C)) == recvcount*sizeof(recvtype

(en C))

// collectives/scatter.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

Page 69: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion sélective : MPI_Scatter

int array[] = {wrank, 2*wrank, 3*wrank, 4*wrank};int witness=0;MPI_Scatter(array, 1, MPI_INT,

&witness, 1, MPI_INT, 2, MPI_COMM_WORLD);printf("Rang %d, witness %d.\n", wrank, witness);MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 0, witness 2.Rang 1, witness 4.Rang 2, witness 6.

Rang 3, witness 8.

Page 70: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gather

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 71: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gather

int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,

int root, MPI_Comm comm);

P0

P1

P2

P3

C'est l'opération inverse de MPI_Scatter.

root est l'unique récepteur, tous sont émetteurs.

sendcount est le nombre de données émises par un seul processus.

Les données sont collectées dans l'ordre des rangs des processus.

Mêmes contraintes que MPI_Scatter sur les tailles des données.

Page 72: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gather

// collectives/gather.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);

int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int witness[] = {0, 0, 0, 0};MPI_Gather(&wrank, 1, MPI_INT,

witness, 1, MPI_INT, 2, MPI_COMM_WORLD);printf("Rang %d, witness", wrank);

for (int i=0; i<4; ++i)printf(" %d", witness[i]);

printf(".\n");

MPI_Finalize();return 0;

}

Page 73: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gather

$ mpirun -n 4 sourceRang 0, witness 0 0 0 0.Rang 3, witness 0 0 0 0.Rang 1, witness 0 0 0 0.

Rang 2, witness 0 1 2 3.

Page 74: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte générale : MPI_Allgather

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 75: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte générale : MPI_Allgather

int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,

MPI_Comm comm);

P0

P1

P2

P3

Tous les processus sont émetteurs, et tous sont récepteurs.

sendcount est le nombre de données émises par un processus, pour

un processus.

Les données sont collectées dans l'ordre des rangs des processus.

Revient à faire MPI_Gather avec le processus 0 comme récepteur, suivide MPI_Gather avec le processus 1 comme récepteur, et ainsi de suitepour tous les processus.

Page 76: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte générale : MPI_Allgather

// collectives/allgather.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);

int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int witness[] = {0, 0, 0, 0};MPI_Allgather(&wrank, 1, MPI_INT,

witness, 1, MPI_INT, MPI_COMM_WORLD);printf("Rang %d, witness", wrank);

for (int i=0; i<4; ++i)printf(" %d", witness[i]);

printf(".\n");

MPI_Finalize();return 0;

}

Page 77: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte générale : MPI_Allgather

$ mpirun -n 4 sourceRang 0, witness 0 1 2 3.Rang 3, witness 0 1 2 3.Rang 2, witness 0 1 2 3.

Rang 1, witness 0 1 2 3.

Page 78: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 79: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

int MPI_Scatterv(const void *sendbuf, const int sendcounts[], const int displs[],MPI_Datatype sendtype, void *recvbuf, int recvcount,

MPI_Datatype recvtype, int root, MPI_Comm comm);

P0

P1

P2

P3

0 1 3 4

indices

Même fonctionnement et propriétés que MPI_Scatter, mais on peutrégler le nombre et l'emplacement des données émises avec lesarguments sendcounts et displs (displacements / o�sets).

Les deux arguments sendcounts et displs ne servent que pour leprocessus émetteur.

La taille sendcounts et displs est le nombre de processus dans lecommunicateur.

Page 80: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

P0

P1

P2

P3

0 1 3 4

indices

P0 P1 P2 P3recvcount 1 2 1 2

Seulement pour P2 :

sendbuf de taille 1+ 2+ 1+ 2 = 6,

sendcounts = {1, 2, 1, 2}

displs = {0, 1, 3, 4}.

Page 81: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

// collectives/scatterv.c#include <mpi.h>#include <stdio.h>#include <stdlib.h>

int main(int argc, char **argv){

MPI_Init(NULL, NULL);

int world_size, wrank;MPI_Comm_size(MPI_COMM_WORLD, &world_size);MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int recvbuf[] = {wrank, wrank};int recvcount = (wrank%2) + 1;int *sendbuf, *sendcounts, *displs;int total = 6;if (wrank==2){

sendcounts = (int*) calloc(world_size, sizeof(int));for (int i=0; i<world_size; ++i)

sendcounts[i]= (i%2) + 1;

Page 82: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

displs = (int*) calloc(world_size, sizeof(int));displs[0] = 0;for (int i=1; i<world_size; ++i)

displs[i] = displs[i-1] + sendcounts[i-1];

sendbuf = (int*) calloc(total, sizeof(int));for (int i=0; i<total; ++i)

sendbuf[i] = 28+i;}

MPI_Scatterv(sendbuf, sendcounts, displs, MPI_INT, recvbuf,recvcount, MPI_INT, 2, MPI_COMM_WORLD);

printf("Rang %d, recvbuf %d %d.\n", wrank, recvbuf[0], recvbuf[1]);

if (wrank==2){

free(sendcounts);free(displs);free(sendbuf);

}

Page 83: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Di�usion : MPI_Scatterv

MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 0, recvbuf 28 0.Rang 1, recvbuf 29 30.Rang 2, recvbuf 31 2.

Rang 3, recvbuf 32 33.

Page 84: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 85: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, const int recvcounts[], const int displs[],

MPI_Datatype recvtype, int root, MPI_Comm comm);

P0

P1

P2

P3

0 1 3 4

indices

Même fonctionnement et propriétés que MPI_Gather, mais on peutrégler le nombre et l'emplacement des données reçues avec lesarguments recvcounts et displs (displacements / o�sets).

Les deux arguments recvcounts et displs ne servent que pour leprocessus récepteur.

La taille recvcounts et displs est le nombre de processus dans lecommunicateur.

Page 86: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

P0

P1

P2

P3

0 1 3 4

indices

P0 P1 P2 P3sendcount 1 2 1 2

Seulement pour P2 :

recvbuf de taille 1+ 2+ 1+ 2 = 6,

recvcounts = {1, 2, 1, 2}

displs = {0, 1, 3, 4}.

Page 87: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

// collectives/gatherv.c#include <mpi.h>#include <stdio.h>#include <stdlib.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int world_size, wrank;MPI_Comm_size(MPI_COMM_WORLD, &world_size);MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int sendbuf[] = {wrank, wrank};int sendcount = (wrank%2) + 1;int *recvbuf, *recvcounts, *displs;int total = 6;if (wrank==2){

recvcounts = (int*) calloc(world_size, sizeof(int));for (int i=0; i<world_size; ++i)

recvcounts[i]= (i%2) + 1;

Page 88: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

displs = (int*) calloc(world_size, sizeof(int));displs[0] = 0;for (int i=1; i<world_size; ++i)

displs[i] = displs[i-1] + recvcounts[i-1];

recvbuf = (int*) calloc(total, sizeof(int));}

MPI_Gatherv(sendbuf, sendcount, MPI_INT, recvbuf,recvcounts, displs, MPI_INT, 2, MPI_COMM_WORLD);

if (wrank==2){

for (int i=0; i<total; ++i)printf("%d ", recvbuf[i]);

printf("\n");

free(recvcounts);free(displs);free(recvbuf);

}

Page 89: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collecte : MPI_Gatherv

MPI_Finalize();return 0;

}

$ mpirun -n 4 source0 1 1 2 3 3.

Page 90: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collectes et di�usions sélectives : MPI_Alltoall

4 Communications collectivesNotions généralesSynchronisation globale : MPI_BarrierDi�usion générale : MPI_BcastDi�usion sélective : MPI_ScatterCollecte : MPI_GatherCollecte générale : MPI_AllgatherDi�usion : MPI_ScattervCollecte : MPI_GathervCollectes et di�usions sélectives : MPI_Alltoall

Page 91: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collectes et di�usions sélectives : MPI_Alltoall

int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,

MPI_Comm comm);

a b c d

a b c d

a b c d

a b c d

a

b

c

d

a

b

c

d

a

b

c

d

a

b

c

d

P0

P1

P2

P3

Correspond à un MPI_Allgather où la donnée envoyée dépend duprocessus récepteur.

Le ième processus envoie le jème jeu de données au jème processusqui le place dans à la ième place.

Page 92: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collectes et di�usions sélectives : MPI_Alltoall

// collectives/alltoall.c#include <math.h>#include <mpi.h>#include <stdio.h>#include <stdlib.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);

int world_size, wrank;MPI_Comm_size(MPI_COMM_WORLD, &world_size);MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int power = pow(10, wrank+1);int sendbuf[] = {power, power+1, power+2, power+3};int recvbuf[] = {0, 0, 0, 0};

MPI_Alltoall(sendbuf, 1, MPI_INT,recvbuf, 1, MPI_INT, MPI_COMM_WORLD);

Page 93: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives

Collectes et di�usions sélectives : MPI_Alltoall

printf("Rang %d, recvbuf", wrank);for (int i=0; i<world_size; ++i)

printf(" %d", recvbuf[i]);printf(".\n");

MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 0, recvbuf 10 100 1000 10000.Rang 1, recvbuf 11 101 1001 10001.Rang 2, recvbuf 12 102 1002 10002.

Rang 3, recvbuf 13 103 1003 10003.

Page 94: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

5 Distribution équitableExtension du tableau et MPI_Scatter

Distribution sous-optimale avec MPI_Scatterv

Distribution optimale avec MPI_Scatterv

Page 95: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

On veut distribuer le plus équitablement possible un tableau T à Néléments sur P processus.

Si P divise N, on utilise simplement MPI_Scatter : le processusémetteur envoie N/P éléments à chaque processus.

Si P ne divise pas N, on ne peut pas utiliser MPI_Scatterdirectement, mais on peut utiliser MPI_Scatterv.

Dans tous les cas, il faut déterminer au préalable le nombred'éléments à envoyer à chaque processus.

Page 96: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Extension du tableau et MPI_Scatter

5 Distribution équitableExtension du tableau et MPI_Scatter

Distribution sous-optimale avec MPI_Scatterv

Distribution optimale avec MPI_Scatterv

Page 97: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Extension du tableau et MPI_Scatter

Soit N ′ le plus petit entier > N divisible par P . En C, avec unedivision entière,

N’ = (N/P + 1) * P;

On étend le tableau T en un tableau T ′ de taille N ′ : les N premierséléments des deux tableaux sont les mêmes, et on remplit T ′ avecdes valeurs neutres (des 0 si on compte sommer les éléments, 1 sion veut les multiplier. . .).

On utilise MPI_Scatter sur T ′ et on envoie N ′/P éléments à chaqueprocessus.

33 13 54 69 5 74 74 57 67 5

33 13 54 69 5 74 74 57 67 5

**

T

T’

N = 10

N’ = 12

P = 3

Page 98: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Distribution sous-optimale avec MPI_Scatterv

5 Distribution équitableExtension du tableau et MPI_Scatter

Distribution sous-optimale avec MPI_Scatterv

Distribution optimale avec MPI_Scatterv

Page 99: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Distribution sous-optimale avec MPI_Scatterv

Tous les processus à part un reçoivent N/P éléments de T .

On choisit un processus, en général l'émetteur, pour recevoir ce quireste, soit

N/P + N%P;

éléments.

33 13 54 69 5 74 74 57 67 5T 28 N = 11 P = 3

Le processus choisi reçoit entre 1 et P − 1 éléments de plus que lesautres.

Page 100: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Distribution optimale avec MPI_Scatterv

5 Distribution équitableExtension du tableau et MPI_Scatter

Distribution sous-optimale avec MPI_Scatterv

Distribution optimale avec MPI_Scatterv

Page 101: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Distribution équitable

Distribution optimale avec MPI_Scatterv

On choisit N%P processus, en général ceux de faibles rangs, pourrecevoir N/P + 1 éléments du tableau.

Les autres processus reçoivent N/P éléments.

33 13 54 69 5 74 74 57 67 5T 28 N = 11 P = 3

La di�érence de nombre d'éléments reçus pour deux processus est aumaximum 1.

Page 102: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

6 Communications collectives : réductionsRéductions réparties : MPI_ReduceRéductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

Page 103: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce

6 Communications collectives : réductionsRéductions réparties : MPI_ReduceRéductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

Page 104: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce

Une réduction est une opération appliquée à un ensembled'éléments pour en obtenir une seule valeur. Par exemple,somme/maximum d'éléments venant de plusieurs processus.

int MPI_Reduce(const void *sendbuf, void *recvbuf, int count,

MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);

P0

P1

P2

P3 1000

100

10

1

1000

maximum

P0

P1

P2

P3 1000

100

10

1

1111

somme

L'argument op permet de choisir l'opération de réduction. Voir frame106 pour la liste des opérations prédé�nies.

Page 105: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce

Si chaque processus envoie un tableau, la fonction de réduction estappliquée pour chaque indice.

P0

P1

P2

P3 1000 2000

100 200

2010

1 2

1111 2222

somme

P0

P1

P2

P3 1000 2000

100 200

2010

1 2

maximum

1000 2000

Les fonctions MPI_Op_create et MPI_Op_free permettent de dé�nir desopérations de réductions personnelles.

Page 106: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce

Principales opérations de réduction prédé�nies.

Nom OpérationMPI_SUM Somme des élémentsMPI_PROD Produit des élémentsMPI_MAX Maximum des élémentsMPI_MIN Minimum des élémentsMPI_MAXLOC Maximum + indice (voir exemple)MPI_MINLOC Minimum + indice (voir exemple)MPI_LAND ET logiqueMPI_LOR OU logiqueMPI_LXOR OU exclusif logique

Page 107: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_SUM

6 Communications collectives : réductionsRéductions réparties : MPI_ReduceRéductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

Page 108: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_SUM

// collectives/reduce_sum.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int seeds[] = {wrank, 2*wrank};int sums[] = {0, 0};MPI_Reduce(&seeds, &sums, 2, MPI_INT, MPI_SUM, 2, MPI_COMM_WORLD);

printf("Rang %d, sums %d %d.\n", wrank, sums[0], sums[1]);MPI_Finalize();return 0;

}

Page 109: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_SUM

$ mpirun -n 4 sourceRang 1, sums 0 0.Rang 0, sums 0 0.Rang 2, sums 6 12.

Rang 3, sums 0 0.

Page 110: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_MAXLOC

6 Communications collectives : réductionsRéductions réparties : MPI_ReduceRéductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

Page 111: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_MAXLOC

// collectives/reduce_maxloc.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);struct{

double val;int rank;

} in, out;

in.val = 10*wrank;in.rank = wrank;

MPI_Reduce(&in, &out, 1, MPI_DOUBLE_INT, MPI_MAXLOC, 2,MPI_COMM_WORLD);

printf("Rang %d, out %f %d.\n", wrank, out.val, out.rank);MPI_Finalize();return 0;

}

Page 112: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Reduce, MPI_MAXLOC

$ mpirun -n 4 sourceRang 0, out 0.000000 0.Rang 3, out 0.000000 0.Rang 2, out 30.000000 3.

Rang 1, out 0.000000 0.

Utile pour savoir d'où vient le maximum.

Il existe d'autres types de paires MPI : MPI_FLOAT_INT, MPI_LONG_INT,

MPI_DOUBLE_INT, MPI_SHORT_INT, MPI_2INT, MPI_LONG_DOUBLE_INT.

Page 113: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Allreduce

6 Communications collectives : réductionsRéductions réparties : MPI_ReduceRéductions réparties : MPI_Reduce, MPI_SUM

Réductions réparties : MPI_Reduce, MPI_MAXLOC

Réductions réparties : MPI_Allreduce

Page 114: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Allreduce

int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count,

MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);

1111 2222

1111 2222

1111 2222

1111 2222P0

P1

P2

P3 1000 2000

100 200

2010

1 2

somme

Tous les processus calculent la réduction, et obtiennent donc lemême résultat.

// collectives/allreduce_sum.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

Page 115: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communications collectives : réductions

Réductions réparties : MPI_Allreduce

int seeds[] = {wrank, 2*wrank};int sums[] = {0, 0};MPI_Allreduce(&seeds, &sums, 2, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

printf("Rang %d, sums %d %d.\n", wrank, sums[0], sums[1]);MPI_Finalize();return 0;

}

$ mpirun -n 4 sourceRang 1, sums 6 12.Rang 0, sums 6 12.Rang 2, sums 6 12.

Rang 3, sums 6 12.

Page 116: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 117: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Fonctions

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 118: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Fonctions

Bloquant Non bloquantEnvoi standard MPI_Send MPI_Isend

Envoi en mode bu�erisé MPI_Bsend MPI_Ibsend

Envoi en mode synchrone MPI_Ssend MPI_Issend

Envoi en mode ready MPI_Rsend MPI_Irsend

Réception MPI_Recv MPI_Irecv

Le mode utilisé par un envoi standard est décidé par MPI lors dechaque appel.

Les fonctions MPI_Send, MPI_Bsend, MPI_Ssend, MPI_Rsend ont toutesle même prototype (voir frame 41) et sont interchangeables dansl'exemple frame 42.

Les fonctions MPI_Isend, MPI_Ibsend, MPI_Issend, MPI_Irsend onttoutes le même prototype (voir frame 132) et sont interchangeablesdans l'exemple frame 132.

Page 119: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications bloquantes

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 120: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications bloquantes

On parle d'un appel bloquant lorsque l'espace mémoire servant à lacommunication (données + enveloppe) peut être réutilisé immédiatementaprès la sortie de l'appel.

Par � réutilisé �, on veut dire :

pour l'émetteur, les éléments du pointeur sur les données à envoyerpeuvent être modi�és, et le pointeur lui-même peut être libérer sansque cela in�ue sur la communication (typiquement, la fonction MPIa copié les données à transférer dans un bu�er temporaire, voir parexemple frame 123),

pour le récepteur, le pointeur sur les données à recevoir contientl'intégralité des données transmises et les éléments peuvent être lus.

Page 121: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications bloquantes

Confusion sur le terme bloquant (malheureusement standard) pourl'émetteur.

Le terme s'applique à l'espace mémoire contenant les données àtransmettre, pas à la communication.

Le terme ne signi�e pas que l'émetteur attend la �n de lacommunication pour sortir de la fonction MPI.

L'émetteur peut même sortir de la fonction MPI avant que latransmission de données n'ait démarrée (voir frame 123).

Pas de confusion pour le récepteur.

Lorsque l'appel à la fonction MPI d'une réception bloquante termine,la communication est e�ectivement terminée.

Page 122: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode bu�erisé

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 123: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode bu�erisé

Lors d'un envoi en mode bu�erisé, le message et l'enveloppe sont copiésà un autre endroit de la mémoire du processus émetteur.

Fonction associée : MPI_Bsend.

L'appel à MPI_Bsend peut se faire même si le processus récepteurn'est pas encore en attente du message (il n'a pas atteint la fonctionde réception).

L'appel à MPI_Bsend peut se terminer même si la totalité du messagen'a pas été reçu, ou même si le processus récepteur n'a pas atteint lafonction de réception.

Si le processus récepteur est en attente du message lors de l'appel àMPI_Bsend, le bu�er peut être omis.

Page 124: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode synchrone

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 125: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode synchrone

Lors d'un envoi en mode synchrone, le processus émetteur doit attendreque la fonction de réception se termine.

Fonction associée : MPI_Ssend.

L'appel à MPI_Ssend peut se faire même si le processus récepteurn'est pas encore en attente du message (il n'a pas atteint la fonctionde réception).

C'est un bon moyen de synchroniser les deux processus.

Dans le cas d'une réception non bloquante (et uniquement dans cecas), la fonction de réception, et donc l'appel à MPI_Ssend, peuventse terminer sans que le message soit complètement transmis.

Page 126: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode ready

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 127: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode ready

Un envoi en mode ready n'est correct que si le processus récepteur estdéjà en attente du message.

Fonction associée : MPI_Rsend.

Permet d'omettre certaines opérations de communications, maisnécessite d'ordonnancer les processus.

Le comportement adopté lorsque le processus récepteur n'est pas enattente du message est indé�ni.

Très peu utilisé car très risqué.

Page 128: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode standard

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 129: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Envoi bloquant, mode standard

Le comportement exact du mode standard est décidé au moment del'envoi.

Fonction associée : MPI_Send.

Suivant la taille des données / l'avancement des processus, MPI_Sendse comportera soit comme un MPI_Bsend, soit comme un MPI_Ssend,soit comme un MPI_Rsend.

Il n'est pas possible de déterminer à l'avance son comportement.

Page 130: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications non bloquantes

7 Modes de communicationsFonctionsCommunications bloquantesEnvoi bloquant, mode bu�eriséEnvoi bloquant, mode synchroneEnvoi bloquant, mode readyEnvoi bloquant, mode standardCommunications non bloquantes

Page 131: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications non bloquantes

Un appel non bloquant démarre l'émission ou la réception d'un messagepuis termine immédiatement (le programme continue son exécution).

Permet de continuer les calculs pendant que la communications'e�ectue.

Tout appel non bloquant nécessite l'appel à la fonction MPI_Wait (ouune de ses déclinaisons) pour terminer correctement l'appel.

Dans le cas d'un envoi non bloquant, la mémoire contenant lemessage ne doit pas être réutilisée (mais peut être lue) avant l'appelà MPI_Wait.

Dans le cas d'une réception non bloquante, la mémoire destinée àrecevoir le message ne doit pas être lue avant l'appel à MPI_Wait.

Un envoi non bloquant peut être couplé à une réception bloquante etinversement.

Page 132: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications non bloquantes

int MPI_Isend(const void *buf, int count, MPI_Datatype datatype,

int dest, int tag, MPI_Comm comm, MPI_Request *request);

int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,

int source, int tag, MPI_Comm comm, MPI_Request *request);

int MPI_Wait(MPI_Request *request, MPI_Status *status);

// non-bloquant.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

Page 133: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications non bloquantes

int witness = 0;MPI_Request request;if (wrank==2){

int modifier = 1;MPI_Isend(&modifier, 1, MPI_INT, 3, 28, MPI_COMM_WORLD,

&request);// Computations.MPI_Wait(&request, MPI_STATUS_IGNORE);

}else if (wrank==3){

MPI_Irecv(&witness, 1, MPI_INT, 2, 28, MPI_COMM_WORLD,&request);

// Other computations.MPI_Wait(&request, MPI_STATUS_IGNORE);

}

printf("Rang %d, witness %d.\n", wrank, witness);MPI_Finalize();return 0;

}

Page 134: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Modes de communications

Communications non bloquantes

$ mpirun -n 4 sourceRang 0, witness 0.Rang 2, witness 0.Rang 3, witness 1.

Rang 1, witness 0.

L'argument de type MPI_Request est un identi�ant de l'appel nonbloquant.

Il faut en allouer un par appel non bloquant.

Page 135: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

8 DeadlocksDé�nitionExemple

Page 136: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Dé�nition

8 DeadlocksDé�nitionExemple

Page 137: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Dé�nition

On est en situation de deadlock lorsqu'un processus attend indé�nimentune action d'un autre processus.

Peut arriver lors de communications bloquantes, ou lors d'appel àMPI_Wait.Ils peuvent être provoqués par :

un appel à MPI_Recv sans émission correspondante, soit parce qu'iln'y a simplement pas d'émission, soit à cause d'une erreur dansl'enveloppe de l'émission (un tag ou un processus émetteur incorrect),(le plus souvent) un ordonnancement incorrect des émissions /réceptions.

Note.

Puisque le mode utilisé par MPI_Send n'est décidé qu'à l'appel de lafonction, certains programmes ne provoqueront passystématiquement un deadlock, même si l'ordonnancement desémissions / réceptions est incorrect.

Page 138: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Exemple

8 DeadlocksDé�nitionExemple

Page 139: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Exemple

// possible-deadlock.c#include <mpi.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

if (wrank==0){

int send0 = 10, recv0;MPI_Send(&send0, 1, MPI_INT, 1, 28, MPI_COMM_WORLD);MPI_Recv(&recv0, 1, MPI_INT, 1, 42, MPI_COMM_WORLD,

MPI_STATUS_IGNORE);}else if (wrank==1){

int send1 = 11, recv1;MPI_Send(&send1, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);MPI_Recv(&recv1, 1, MPI_INT, 0, 28, MPI_COMM_WORLD,

MPI_STATUS_IGNORE);}

Page 140: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Exemple

MPI_Finalize();return 0;

}

Si les deux appels à MPI_Send se font en mode synchrone, il y aura undeadlock.

Si un des appels se fait en mode bu�erisé, il n'y aura pas dedeadlock.

Page 141: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Deadlocks

Exemple

Le même programme avec des MPI_Ssend à la place des MPI_Send

provoquera systématiquement un deadlock.

Une des manières de s'assurer que l'ordonnancement descommunications est correct est d'utiliser des MPI_Ssend partout (maisle programme sera un peu plus lent).

Une bonne règle d'écriture de programme MPI est de mettre desMPI_Ssend partout dans un premier temps, puis de les remplacer pardes MPI_Send lorsqu'on est sûr que toutes les communicationss'e�ectuent correctement.

Page 142: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 143: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Introduction

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 144: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Introduction

Il est possible de créer ses propres types de données MPI.

Le type créé sera de type MPI_Datatype.

Tout type créé destiné à être utilisé pour une communication doitêtre enregistré à l'aide de la fonction MPI_Type_commit.int MPI_Type_commit(MPI_Datatype *datatype);

Tout type créé avec un MPI_Type_commit doit être libéré par unMPI_Type_free (surtout si on veut réutiliser le nom).int MPI_Type_free(MPI_Datatype *datatype);

Deux sortes de types peuvent être créés :extraction de données d'un tableau (MPI_Type_vector,MPI_Type_indexed),des types utilisés pour faire passer les structures qu'on dé�nit(MPI_Type_create_struct).

Page 145: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction contiguë : MPI_Type_contiguous

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 146: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction contiguë : MPI_Type_contiguous

int MPI_Type_contiguous(int count, MPI_Datatype oldtype,

MPI_Datatype *newtype);

count

Le nombre total d'éléments de type oldtype contenu dans *newtype

est count.

Page 147: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction contiguë : MPI_Type_contiguous

// types/contiguous.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int data[24];for (int i=0; i<24; ++i)

data[i] = 0;

MPI_Datatype CType;MPI_Type_contiguous(8, MPI_INT, &CType);MPI_Type_commit(&CType);

if (wrank==0){

for (int i=0; i < 24; i++)data[i] = i;

MPI_Ssend(data+10, 1, CType, 1, 28, MPI_COMM_WORLD);}

Page 148: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction contiguë : MPI_Type_contiguous

else if (wrank==1){

MPI_Recv(data, 1, CType, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

for (int i=0; i < 8; i++)printf("%d ", data[i]);

printf(".\n");}

MPI_Type_free(&CType);MPI_Finalize();return 0;

}

$ mpirun -n 2 source

10 11 12 13 14 15 16 17.

Page 149: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas constant : MPI_Type_vector

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 150: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas constant : MPI_Type_vector

int MPI_Type_vector(int count, int blocklength, int stride,

MPI_Datatype oldtype, MPI_Datatype *newtype);

blocklength

stride

count est le nombre de blocks.

Le nombre total d'éléments de type oldtype contenu dans *newtype

est count*blocklength.

Page 151: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas constant : MPI_Type_vector

// types/vector.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int data[24];for (int i=0; i<24; ++i)

data[i] = 0;

MPI_Datatype VType;MPI_Type_vector(4, 2, 6, MPI_INT, &VType);MPI_Type_commit(&VType);

if (wrank==0){

for (int i=0; i < 24; i++)data[i] = i;

MPI_Ssend(data, 1, VType, 1, 28, MPI_COMM_WORLD);}

Page 152: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas constant : MPI_Type_vector

else if (wrank==1){

MPI_Recv(data, 1, VType, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

for (int i=0; i < 24; i++)printf("%d ", data[i]);

printf("\n");}

MPI_Type_free(&VType);MPI_Finalize();return 0;

}

$ mpirun -n 2 source

0 1 0 0 0 0 6 7 0 0 0 0 12 13 0 0 0 0 18 19 0 0 0 0.

Page 153: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas constant : MPI_Type_vector

Le processus récepteur peut aussi réorganiser les données reçues, parexemple au début du tableau.

Il faut faire attention au nombre de données e�ectivement reçues (ici8 éléments de types MPI_INT).

// types/vector_2.celse if (wrank==1){

MPI_Recv(data, 8, MPI_INT, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

for (int i=0; i < 8; i++)printf("%d ", data[i]);

printf(".\n");}

$ mpirun -n 2 source

0 1 6 7 12 13 18 19.

Page 154: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas variable : MPI_Type_indexed

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 155: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas variable : MPI_Type_indexed

int MPI_Type_indexed(int count, const int blengths[],const int displacements[], MPI_Datatype oldtype,

MPI_Datatype *newtype);

blengths[0] blengths[1] blengths[3]

disp[0]

disp[1]

disp[2]

disp[3]

blengths[2]

count est le nombre de blocks. C'est aussi la taille de blengths etdisplacements.

Le nombre total d'éléments est la somme des éléments de blengths.

Page 156: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas variable : MPI_Type_indexed

// types/indexed.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int data[24];for (int i=0; i<24; ++i)

data[i] = 0;

int blengths[] = {2, 3, 4, 2};int disp[] = {1, 7, 12, 19};

MPI_Datatype IType;MPI_Type_indexed(4, blengths, disp, MPI_INT, &IType);MPI_Type_commit(&IType);

Page 157: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas variable : MPI_Type_indexed

if (wrank==0){

for (int i=0; i < 24; i++)data[i] = i;

MPI_Ssend(data, 1, IType, 1, 28, MPI_COMM_WORLD);}else if (wrank==1){

MPI_Recv(data, 1, IType, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

for (int i=0; i < 24; i++)printf("%d ", data[i]);

printf("\n");}

MPI_Type_free(&IType);MPI_Finalize();return 0;

}

Page 158: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Extraction à pas variable : MPI_Type_indexed

$ mpirun -n 2 source

0 1 2 0 0 0 0 7 8 9 0 0 12 13 14 15 0 0 0 19 20 0 0 0.

On peut également réorganiser les données reçues.

// types/indexed_2.celse if (wrank==1){

MPI_Recv(data, 11, MPI_INT, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

for (int i=0; i < 11; i++)printf("%d ", data[i]);

printf(".\n");}

$ mpirun -n 2 source

1 2 7 8 9 12 13 14 15 19 20.

Page 159: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Padding

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 160: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Padding

Les données doivent être alignées dans la mémoire (contraintematériel). Cela signi�e que l'adresse initiale d'une variable de typeprimitif de taille X octets doit être divisible par X .

Les champs d'une structure sont écrits en mémoire de manière àminimiser l'espace mémoire de la structure tout en respectant

l'alignement.

Il en va de même pour les cases d'un tableau.

Pour respecter l'alignement, soit dans les structures, soit dans lestableaux, des octets inutilisés sont ajoutés en mémoire. C'est lepadding.

Page 161: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Padding

typedef struct{

char c;int i;short int si;

} A;

A tab[2];

0x0 0x4 0x8

tab[0] tab[1]

0xC

Disons que l'adresse de tab, et donc de tab[0].c est 0x0 (en héxadécimal)pour simpli�er.

Page 162: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Padding

0x0 0x4 0x8

tab[0] tab[1]

0xC

L'adresse de tab[0].i est la première adresse divisible par 4 après0x1, soit 0x4. On a ajouté trois octets de padding.

tab[0].si peut être directement après tab[0].i puisque 0x8 estdivisible par 2. Pas de padding.

Si on plaçait tab[1] immédiatement après tab[0], tab[1].i tomberaitsur l'adresse 0xE non divisible par 4. Deux octets de padding sontajoutés à la �n de la structure.

Le résultat de sizeof(A) est 12.

Page 163: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Padding

Veri�cation avec la fonction offsetof de stddef.h.

#include <stddef.h>#include <stdio.h>

typedef struct{

char c;int i;short int si;

} A;

int main(){

printf("c: %d, i: %d, si: %d, total: %d\n", offsetof(A, c),offsetof(A, i), offsetof(A, si), sizeof(A));

return 0;}

Résultat :c : 0, i : 4, si : 8, total : 12.

Page 164: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

9 Types de données dérivésIntroductionExtraction contiguë : MPI_Type_contiguousExtraction à pas constant : MPI_Type_vectorExtraction à pas variable : MPI_Type_indexedPaddingStructure de données MPI_Type_create_struct

Page 165: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

int MPI_Type_create_struct(int count, int *array_of_blocklengths,MPI_Aint *array_of_displacements, MPI_Datatype *array_of_types,

MPI_Datatype *newtype);

count : le nombre de champs de la structure.

array_of_blocklengths : tableau de taille count. Chaque élément dutableau est le nombre d'éléments du champ associé (1 pour les typesprimitifs, taille_du_tableau pour les tableaux).

array_of_displacements : tableau de taille count. Chaque élément dutableau est l'adresse du champ dans la structure.

array_of_types : tableau de taille count contenant les types dechaque champs.

newtype : l'adresse du type créé par la fonction.

Page 166: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

La fonction offsetof de stddef.h permet de remplirarray_of_displacements.

L'exemple suivant est à compiler avec l'option −lm pour l'utilisationdu cos.

// types/create_struct.c#include <math.h>#include <mpi.h>#include <stddef.h>#include <stdio.h>

#define FIELDS 3#define TRACKS 14

typedef struct{

int track_count;double lengths[TRACKS];double total;

} album;

Page 167: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int blocklengths[FIELDS] = {1, TRACKS, 1};

MPI_Aint displacements[FIELDS];displacements[0] = offsetof(album, track_count);displacements[1] = offsetof(album, lengths);displacements[2] = offsetof(album, total);

MPI_Datatype types[FIELDS] = {MPI_INT, MPI_DOUBLE, MPI_DOUBLE};MPI_Datatype mpi_album;

MPI_Type_create_struct(FIELDS, blocklengths, displacements,types, &mpi_album);

MPI_Type_commit(&mpi_album);

Page 168: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

album silence;if (wrank==0){

silence.track_count = TRACKS;silence.total = 0;for (int i=0; i<TRACKS; ++i){

silence.lengths[i] = fabs(5*cos(i));silence.total += silence.lengths[i];

}

MPI_Ssend(&silence, 1, mpi_album, 1, 28, MPI_COMM_WORLD);}else if (wrank==1){

MPI_Recv(&silence, 1, mpi_album, 0, 28, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

printf("track_count: %d\nlengths:", silence.track_count);for (int i=0; i<TRACKS; ++i)

printf(" %.2f", silence.lengths[i]);printf("\ntotal: %.2f\n", silence.total);

}

Page 169: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Types de données dérivés

Structure de données MPI_Type_create_struct

MPI_Type_free(&mpi_album);MPI_Finalize();return 0;

}

$ mpirun -n 2 sourcetrack_count : 14lengths : 5.00 2.70 2.08 4.95 3.27 1.42 4.80 3.77 0.73 4.56 4.20 0.02 4.22 4.54

total : 46.25

Page 170: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communicateurs

10 CommunicateursPartitionner un communicateur

Page 171: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communicateurs

Partitionner un communicateur

10 CommunicateursPartitionner un communicateur

Page 172: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communicateurs

Partitionner un communicateur

int MPI_Comm_split(MPI_Comm comm, int color, int key,

MPI_Comm *newcomm);

Tous les processus d'une même couleur se retrouvent dans le mêmecommunicateur.

La variable newcomm a le même nom pour tous les processus, mais sadé�nition di�ère : pour le processus X , le newcomm ne contient que lesprocessus de même couleur que X .

Chaque processus a un rang dans le nouveau communicateur ;celui-ci peut di�érer du rang dans MPI_COMM_WORLD.

Les rangs du nouveau communicateur vont de 0 à #processus − 1.

L'argument key permet de contrôler les nouveaux rangs : si leprocessus X a une key inférieure à celle du processus Y (pour unemême couleur), le rang de X dans le nouveau communicateur serainférieur à celui de Y .

Page 173: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communicateurs

Partitionner un communicateur

// comm_split.c#include <mpi.h>#include <stdio.h>

int main(int argc, char** argv){

MPI_Init(NULL, NULL);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int colors[4] = {11, 11, 10, 11};MPI_Comm new_comm;MPI_Comm_split(MPI_COMM_WORLD, colors[wrank], -wrank, &new_comm);

int nrank;MPI_Comm_rank(new_comm, &nrank);

int witness = 100*wrank;MPI_Bcast(&witness, 1, MPI_INT, 0, new_comm);printf("world: %d, new: %d, witness: %d\n", wrank, nrank, witness);

MPI_Finalize();return 0;

}

Page 174: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Communicateurs

Partitionner un communicateur

$ mpirun -n 2 sourceworld : 1, new : 1, witness : 300world : 3, new : 0, witness : 300world : 0, new : 2, witness : 300

world : 2, new : 0, witness : 200

Les processus de wrank 0, 1, 3 ont même couleur, et le processus dewrank 2 est tout seul.

L'argument key étant -wrank, les rangs dans le nouveauxcommunicateurs se retrouvent dans l'ordre inverse de MPI_WORLD_COMM.

Le broadcast ne s'e�ectue e�ectivement qu'à l'interieur du nouveaucommunicateur.

Page 175: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lageAutres problèmes

Page 176: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lageAutres problèmes

Page 177: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

Debugger parallèle : cher, nécessaire quand le nombre de processusdevient trop grand, adapté pour les clusters.

TotalView :http://www.roguewave.com/products-services/totalview

DDT : http://www.allinea.com/products/ddt

Debugger série : su�t pour un petit nombre de processus.gdb : https://www.open-mpi.org/faq/?category=debugging(section 6)

Page 178: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

Pour attacher gdb à un processus, il faut connaître la machine et lePID du processus.

Ne pas oublier de compiler avec l'option −g .

// debug.c#include <mpi.h>#include <stdio.h>#include <unistd.h>

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int world_size;MPI_Comm_size(MPI_COMM_WORLD, &world_size);

int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

Page 179: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

int i = 0;char hostname[256];gethostname(hostname, sizeof(hostname));if (wrank==0){

printf("PID %d on %s ready for attach\n", getpid(), hostname);fflush(stdout);while (0 == i)

sleep(5);}

MPI_Barrier(MPI_COMM_WORLD);// Suite du programme.MPI_Finalize();return 0;

}

Page 180: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

$ gdb

(gdb) attach PID (stoppe l'exécution du processus)

(gdb) up (plusieurs fois, jusqu'à atteindre la fonction sleep)

(gdb) set var i = 1 (pour sortir de la boucle)

(gdb) c (pour reprendre l'exécution)

Page 181: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Debug

Une seconde méthode permet de lancer autant de gdb que deprocessus.

Facile si tous les processus sont lancés sur localhost, plus compliquési on est sur un cluster (voir lien frame 177).

Nécessite seulement un MPI_Barrier au début du programme :notamment, pas besoin d'ajouter hostname/pid/sleep comme pourl'autre méthode.

La commande

$ mpirun -n 4 xterm -e gdb source

lancera gdb dans quatres terminaux : un par processus. Il faut lancerles programmes (avec run) dans chaque gdb.

Page 182: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Méthodologie de debug de code MPI

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lageAutres problèmes

Page 183: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Méthodologie de debug de code MPI

Quelques recommendations.

Débugger le programme en série sans MPI (gdb / printf).

Débugger le programme MPI avec un seul processus (gdb / printf).Utiliser exclusivement des MPI_Ssend (mode synchrone) et MPI_Recv

pour les communications point-à-point (les communicationscollectives peuvent être laissées en l'état) et

véri�er les communications (MPIP / printf),éventuellement débugger avec gdb.

Changer les MPI_Ssend (mode synchrone) et MPI_Recv en d'autresmode de communications si nécessaire.

Page 184: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lage

Mesures temporelles simples

MPIP

MPE

OPro�le

Autres problèmes

Page 185: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Pro�ler consiste à analyser plusieurs aspects d'un programme(l'utilisation mémoire, le temps d'exécution des fonctions /instructions, . . .) dans le but de l'optimiser.Pro�lers commerciaux :

Intel VTune : https://software.intel.com/en-us/intel-vtune-amplifier-xe/

Allinea MAP : http://www.allinea.com/products/map

Pro�lers libres :MPIP : http://mpip.sourceforge.net/ (uniquement pour lesfonctions MPI).MPE :http://www.mcs.anl.gov/research/projects/perfvis/

(uniquement pour les fonctions MPI).OPro�le : http://oprofile.sourceforge.net/news/(indépendant de MPI).Valgrind : http://valgrind.org/ (indépendant de MPI).

Page 186: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Mesures temporelles simples

Mesure externe : la commande time

$ time mpirun -n 2 sourcereal 0m6.808s

user 0m10.172s

sys 0m0.120s

real : temps écoulé entre le début et la �n du programme. Les autresprocessus de la machine in�uent sur cette mesure.

user : temps CPU passé à l'exécution du programme en modeutilisateur. Indépendant des autres processus.

sys : temps CPU passé à l'exécution du programme en mode kernel.Indépendant des autres processus.

Page 187: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Les temps user et sys ne concernent que la machine sur laquelle lacommande time a été lancée.

La mesure externe n'est donc utile que lorsque tous les processus setrouvent sur la même machine.

Les temps user et sys rapportent la somme des temps CPU dechaque c÷ur.

Sur notre exemple, 2 c÷urs ont totalisés (10.172+ 0.120)s de tempsCPU : puisque les deux c÷urs ont travaillés en parallèle, le tempsuser+sys est supérieur au temps real.

Page 188: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Mesure interne : la fonction double MPI_Wtime()

Renvoie le nombre de secondes écoulées depuis une date passéearbitraire (qui ne change pas au cours de l'exécution).

Peut utiliser (ou non, s'il y a mieux) la fonction C gettimeofday

(man gettimeofday).

Inconvénient : nécessite de modi�er le code.

// wtime.c#include <mpi.h>#include <stdio.h>#include <unistd.h>

Page 189: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

int main(int argc, char **argv){

MPI_Init(&argc, &argv);int wrank;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

int witness = 0;if (wrank==2){

int modifier = 1;sleep(2);MPI_Send(&modifier, 1, MPI_INT, 3, 28, MPI_COMM_WORLD);

}else if (wrank==3){

double start = MPI_Wtime();MPI_Recv(&witness, 1, MPI_INT, 2, 28, MPI_COMM_WORLD,

MPI_STATUS_IGNORE);printf("MPI_Recv : %f secondes.\n", MPI_Wtime()-start);

}

Page 190: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

MPI_Barrier(MPI_COMM_WORLD);printf("Rang %d, witness %d.\n", wrank, witness);MPI_Finalize();return 0;

}

$ mpirun -n 2 sourceMPI_Recv : 2.000119 secondes.Rang 3, witness 1.Rang 2, witness 0.Rang 1, witness 0.

Rang 0, witness 0.

Page 191: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

MPIP

http://mpip.sourceforge.net/

Pro�le uniquement les fonctions MPI.

Ne nécessite pas de modi�cations de code.

Ne nécessite pas de recompiler le programme, mais donne desresultats plus précis si on compile en debug.

Nécessite de relinker le programme.

Nécessite libunwind (présent dans les dépôts debian).

Page 192: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

$ mpicc -g -o source source.c -L${mpiP_root}/lib -lmpiP -lm -lbfd -liberty-lunwind

$ mpirun -n 4 source

Produit un �chier source.X.XXXX.X.mpiP comportant six sections :

MPI Time,

Callsites,

Aggregate Time,

Aggregate Sent Message Size,

Callsite Time statistics,

Callsite Message Sent statistics.

Les slides suivant décrivent la sortie obtenue en lançant le programme deMPI_Wtime.

Page 193: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

MPI Time (seconds)

Task AppTime MPITime MPI%

0 2 2 100.00

1 2 2 100.00

2 2 0.0004 0.02

3 2 2 99.98

* 8 6 74.99

Task : le rang du processus ou * pour la somme.

AppTime : temps total du programme.

MPITime : temps passé dans les fonctions MPI uniquement.

MPI% : rapport entre MPITime et AppTime.

Page 194: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Callsites : 3

ID Lev File/Address Line Parent_Funct MPI_Call

1 0 wtime.c 26 main Barrier

2 0 wtime.c 17 main Send

3 0 wtime.c 22 main Recv

ID : identi�ant utilisé pour les autres statistiques.

Lev : ( ? :/)

File/Address : le �chier d'origine.

Line : la ligne de l'appel MPI.

Parent_Func : la fonction qui contient l'appel MPI.

MPI_Call : la fonction MPI appelée.

Page 195: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Aggregate Time (top twenty, descending, milliseconds)

Call Site Time App% MPI% COV

Barrier 1 4e+03 49.99 66.66 1.15

Recv 3 2e+03 25.00 33.34 0.00

Send 2 0.105 0.00 0.00 0.00

Call : la fonction MPI appelée.

Site : identi�ant du site (ID de la section Callsite).

Time : somme sur tous les processus du temps passé dans cettefonction MPI.

App% : le rapport entre Time et le temps total du programme.

MPI% : le rapport entre Time et le temps total MPI.

COV : coe�cient de variation entre les processus.

Page 196: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Aggregate Sent Message Size (top twenty, descending, bytes)

Call Site Count Total Avrg Sent%

Send 2 1 4 4 100.00

Call : la fonction MPI appelée.

Site : identi�ant du site (ID de la section Callsite).

Count : le nombre d'appel a la fonction.

Total : le nombre total d'octets envoyés par cette fonction.

Avrg : le nombre moyen par appel d'octets envoyés.

Sent% : le rapport entre Total et le nombre total d'octets envoyéspar toutes les fonctions MPI.

Page 197: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Callsite Time statistics (all, milliseconds) : 6

Name Site Rank Count Max Mean Min App% MPI%

Barrier 1 0 1 2e+03 2e+03 2e+03 100.00 100.00

Barrier 1 1 1 2e+03 2e+03 2e+03 100.00 100.00

Barrier 1 2 1 0.295 0.295 0.295 0.01 73.75

Barrier 1 3 1 0.031 0.031 0.031 0.00 0.00

Barrier 1 * 4 2e+03 1e+03 0.031 49.99 66.66

Recv 3 3 1 2e+03 2e+03 2e+03 99.98 100.00

Recv 3 * 1 2e+03 2e+03 2e+03 25.00 33.34

Send 2 2 1 0.105 0.105 0.105 0.01 26.25

Send 2 * 1 0.105 0.105 0.105 0.00 0.00

Page 198: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Name : la fonction MPI appelée.

Site : identi�ant du site (ID de la section Callsite).

Rank : le rang du processus.

Count : le nombre d'appel à la fonction.

Max : le temps (en millisecondes) du plus long appel à la fonction.

Mean : le temps moyen (en millisecondes) d'un appel à la fonction.

Min : le temps (en millisecondes) du plus court appel à la fonction.

App% : le rapport entre le temps passé dans cette fonction et letemps total d'exécution du programme.

MPI% : le rapport entre le temps passé dans cette fonction et letemps total d'exécution des fonctions MPI.

Page 199: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Callsite Message Sent statistics (all, sent bytes)

Name Site Rank Count Max Mean Min Sum

Send 2 2 1 4 4 4 4

Send 2 * 1 4 4 4 4

Name : la fonction MPI appelée.

Site : identi�ant du site (ID de la section Callsite).

Rank : le rang du processus.

Count : le nombre d'appel à la fonction.

Max : le plus grand nombre d'octets transférés en un appel.

Mean : le nombre moyen par appel d'octets transférés.

Min : le plus petit nombre d'octets transférés en un appel.

Sum : la somme des octets transférés pour tous les appels de lafonctions.

Page 200: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

MPE

http://www.mcs.anl.gov/research/projects/perfvis/

Pro�le uniquement les fonctions MPI.

Ne nécessite pas de modi�cations de code.

Ne nécessite pas de recompiler le programme.

Nécessite de relinker le programme.

Viens avec une interface graphique.

Ne marche pas avec du C++.

Page 201: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

$ mpicc -c source.c -o source.o$ mpecc -mpilog source.o -o source

$ mpirun -n 4 source

Produit un �chier source.clog2.L'interface graphique, assez intuitive, se lance avec :$ jumpshot source.clog2

Page 202: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

OPro�le

http://oprofile.sourceforge.net/news/

Permet de compter les cycles CPU, les 'cache misses' (et un tasd'autres paramètres) de chaque fonctions / instructions d'unprogramme.

Ne nécessite pas de modi�cations de code.

Nécessite de recompiler le programme en debug pour avoir desinformations précises.

Non spéci�que au programme MPI.

Documentation : http://oprofile.sourceforge.net/docs/

Ne marche pas dans les machines virtuelles.

Page 203: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Quick start (cycles CPU) :

$ operf -t mpirun -n 2 source$ opreport -l -m tid source -o pro�le

$ opannotate -as -t 2 source > annotated

operf permet d'analyser le programme. Les resultats sont écrits dansle dossier oprofile_data. L'option -t permet de séparer les di�érentsprocessus.

La ligne opreport génère le �chier pro�le qui contient, pour chaquefonctions appelées et pour chaque processus, le nombre de cycleCPU passés dans cette fonction.

La ligne opannotate génère le �chier annotated qui contient lesinstructions assembleurs du code, et pour chacune d'elle, le nombrede cycle CPU passés dans cette instruction.

Page 204: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Le �chier pro�le s'organise de la manière suivante :

samples % samples % image name symbol name33038 39.6791 32711 39.2963 source ma_fonction(int, int)

Les deux premières colonnes réfèrent au processus de rang 0, avec lenombre et le pourcentage de cycles passés dans la fonctionma_fonction.

Les 3ième et 4ième colonnes réfèrent au processus de rang 1.

Les 5ième et 6ième colonnes sont le nom de l'exécutable et leprototype de la fonction.

Page 205: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

Le �chier annotated s'organise de la manière suivante :

: instruction (en C);111 0.1333 123 0.1478 : 444a8f: movslq %edx,%rdx63 0.0757 60 0.0721 : 444a92: movsd (%r8,%rdx,8),%xmm094 0.1129 73 0.0877 : 444a98: mulsd (%r11,%rax,8),%xmm0

1437 1.7259 1428 1.7155 : 444a9e: addsd (%rcx),%xmm0660 0.7927 675 0.8109 : 444aa2: movsd %xmm0,(%rcx)

Pour chaque instruction C, la liste des instructions assembleur estdétaillée.

On retrouve la même organisation que dans pro�le pour les 4premières colonnes.

On peut ainsi voir immédiatement les passages lents du code, mais laméthode n'est pas parfaite :http://oprofile.sourceforge.net/doc/debug-info.html.

Page 206: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Pro�lage

On peut demander à operf de mesurer d'autres paramètres avecl'option -e.

La liste de ces paramètres dépend de l'architecture dumicroprocesseur : http://oprofile.sourceforge.net/docs/.

LLC_MISSES en particulier peut être intéressant à analyser /optimiser.

Page 207: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

11 Analyse de codes MPIDebugMéthodologie de debug de code MPIPro�lageAutres problèmes

Opérations �otantes

Race condition

Page 208: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

Opérations �otantes

Les opérations sur les �otants ne sont pas associatives : le résultatdépend de l'ordre des opérations.

Dans les codes parallèles, l'ordre des opérations à e�ectuer peutdépendre du nombre de processus utilisés.

Le code série et les codes parallèles pourront donc donner desrésultats di�érents, et on peut se poser la question

La di�érence est-elle dû à une erreur dans le code parallèleou aux erreurs d'arrondis ?

Très di�cile de répondre en général. Il existe une méthode decorrection d'erreurs (assez lourde).

Page 209: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

// roundoff.c#include <mpi.h>#include <stdio.h>#include <stdlib.h>

#define TE 28000

int main(int argc, char** argv){

MPI_Init(&argc, &argv);int wrank, world_size;MPI_Comm_rank(MPI_COMM_WORLD, &wrank);MPI_Comm_size(MPI_COMM_WORLD, &world_size);

float tab[TE];if (wrank==0){

for (int i=0; i<TE; ++i)tab[i] = (rand() % 1000) / 1000.;

}

MPI_Bcast(tab, TE, MPI_FLOAT, 0, MPI_COMM_WORLD);

Page 210: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

float local = 0;for (int i=wrank; i<TE; i+=world_size)

local += tab[i];

float result;MPI_Reduce(&local, &result, 1, MPI_FLOAT, MPI_SUM, 0,

MPI_COMM_WORLD);

if (wrank==0){

float serial = 0;for (int i=0; i<TE; ++i)

serial += tab[i];

printf("serial: %f, parallel: %f\n", serial, result);}

MPI_Finalize();return 0;

}

Page 211: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

$ mpirun -n 2 sourceserial : 13911.528320, parallel : 13911.541016

$ mpirun -n 4 sourceserial : 13911.528320, parallel : 13911.516602

$ mpirun -n 8 sourceserial : 13911.528320, parallel : 13911.522461

Page 212: Calcul parallèle et distribué - jullian/downloads/cpd.pdf · Mémoire distribuée Remarques. Di érents threads d'un même processus ont accès à la même mémoire. Di érents

Calcul distribué

Analyse de codes MPI

Autres problèmes

Race condition

On est en situation de 'race condition' lorsque le résultat duprogramme dépend de l'ordre d'exécution des instructions desdi�érents processus.

Ne peut se produire que si une resource commune à plusieursprocessus (pour MPI, le disque dur) est modi�ée/lue.

Peut être réglé en ajoutant des synchronisations.

Voir l'exemple frame 60.