Programmation parallèle
MPI
Ichrak MEHREZ
(m_ichrak@[Link])
2018-2019
1
Présentation
Message Passing Interface (MPI), est une norme conçue
en 1993-94, qui définit une bibliothèque de fonctions,
utilisable avec les langages C, C++ et Fortran.
Elle permet d'exploiter des ordinateurs distants
ou multiprocesseur par passage de messages.
Elle est devenue de facto un standard de communication
pour des nœuds exécutant des programmes
parallèles sur des systèmes à mémoire distribuée.
2
Communicateurs
Deux processus, ou plus, ne pourront communiquer que
s'ils sont dans un même communicateur.
Un communicateur initial englobe tous les processus
(MPI_COMM_WORLD), qu'il est possible de subdiviser
en communicateurs plus petits correspondants à des
entités logiques.
3
Deux types de communications
1- Communications point-à-point
Les communications point-à-point permettent à deux
processus à l'intérieur d'un même communicateur
d'échanger une donnée (scalaire, tableau ou type dérivé).
Les fonctions correspondantes sont MPI_Send,
MPI_Recv et MPI_Sendrecv.
4
Deux types de communications
1- Communications collectives
Les communications collectives impliquent tous les
processus d'un communicateur.
Il est possible d'envoyer une même donnée à tous les
processus (MPI_Bcast), de découper un tableau entre
tous les processus (MPI_Scatter), ou d'effectuer une
opération (par exemple addition) où chaque processus
contribuera.
5
Types dérivés
Type de base (entier, flottant simple ou double précision,
caractère) sont nativement pris en charge.
Il est possible de créer des types dérivés, qui s'écartent
plus ou moins de ces types de base.
6
Squelette d’un programme
Toute unité de programme appelant des sous-
programmes MPI doit inclure un fichier d’en-têtes.
Concernant le c/c++ : Il faut inclure le fichier mpi.h
#include <mpi.h>
La fonction MPI_INIT() permet d’initialiser
l’environnement nécessaire :
MPI_INIT (int *argc, char ** argv)
Pour terminer l’environnement d’exécution MPI:
Int MPI_FINALIZE (int *argc, char ** argv)
7
Communicateur
MPI_COMM_WORLD comprend tous les processus
actifs
8
Communicateur
Nombre de processus gérés par un communicateur est
donné par MPI_COMM_SIZE() :
MPI_COMM_RANK() permet d’obtenir le rang d’un
processus
𝟎 ≤ MPI_COMM_RANK () ≤ MPI_COMM_SIZE() – 1
9
Communications point à point
Notions générales
Une communication dite point à point lorsqu’elle a lieu
entre deux processus, l’un appelé processus émetteur et
l’autre processus récepteur (ou destinataire).
L’émetteur et le récepteur sont identifiés par leur rang
dans le communicateur.
10
Communications point à point
Opérations d’envoi et de réception bloquantes
Opération d’envoi MPI_SEND
int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm );
Envoyer un message, à partir de l’adresse buf, de taille
count, de type datatype, étiqueté tag, au processus numéros
dest dans le communicateur comm.
11
Communications point à point
Opérations d’envoi et de réception bloquantes
Opération de réception MPI_Recv
int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int
source, int tag, MPI_Comm comm, MPI_Status *status );
Réception, à partir de l’adresse message buf, d’un
message de taille count, de type datatype, étiqueté tag, du
processus source.
Remarques : L’appel MPI_RECV ne pourra fonctionner avec une
opération MPI_SEND que si ces deux appels ont la même enveloppe
(source, dest, tag, comm)
12
Type MPI
Principaux types de données de base (C)
13
Communications point à point
Opération d’envoi et de réception simultanés MPI_SENDRECV
int MPI_Sendrecv( void *sendbuf, int sendcount, MPI_Datatype
sendtype, int dest, int sendtag, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm,
MPI_Status *status );.
Envoi, à partir de l’adresse sendbuf, d’un message de taille sendcount,
de type sendtype, étiquetté sendtag, au processus dest dans le
communicateur comm ;
Réception, à partir de l’adresse recvbuf, d’un message de taille
recvcount, de type recvtype, étiquetté recvtag, du processus source
dans le comm
14
Communications collectives
Notions générales
Une communication collective concerne toujours tous les
processus du communicateur indiqué.
Pour chacun des processus, l’appel se termine lorsque la
participation de celui-ci à l’opération collective est
achevée
15
Communications collectives
Synchronisation globale
int MPI_Barrier( MPI_Comm comm );
16
Communications collectives
Diffusion générale
int MPI_Bcast( void *buffer, int count, MPI_Datatype datatype,
int root, MPI_Comm comm );
Envoi, à partir de l’adresse buffer, d’un message constitué
de count élément de type datatype, par le processus root, à
tous les autres processus du communicateur comm.
Réception de ce message à l’adresse buffer pour les
processus autre que root.
17
Communications collectives
Diffusion sélective
int MPI_Scatter( void *sendbuf, int sendcnt, MPI_Datatype
sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int
root, MPI_Comm comm );
Distribution, par le processus root, à partir de l’adresse sendbuf, d’un
message de taille sendcnt, de type sendtype, à tous les processus du
communicateur comm;
Réception du message à l’adresse recvbuf, de longueur recvcnt et de
type recvtype par tous les processus du communicateur comm.
18
Communications collectives
Diffusion sélective
int MPI_Scatter( void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int
recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm );
Les données sont distribuées en tranches égales
La ième tranche est envoyée au ième processus.
19
Communications collectives
Collecte
int MPI_Gather( void *sendbuf, int sendcnt, MPI_Datatype
sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int
root, MPI_Comm comm );
Envoi de chacun des processus du communicateur comm, d’un
message sendbuf, de taille sendcnt et de type sendtype.
Collecte de chacun de ces messages, par le processus root, à partir
l’adresse recvcnt, sur une longueur recvcnt et avec le type recvtype.
20
Communications collectives
Collecte
int MPI_Gather( void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int
recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm );
Les données sont collectées dans l’ordre des rangs des processus.
21
Communications collectives
Collecte générale
int MPI_Allgather( void *sendbuf, int sendcount, MPI_Datatype
sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm );
Correspond à un MPI_GATHER() suivi d’un MPI_BCAST() :
Envoi de chacun des processus de comm, d’un message sendbuf, de
taille sendcount et de type sendtype
Collecte de chacun de ces messages, par tous les processus, à partir
l’adresse recvbuf, sur une longueur recvcount et avec le type recvtype
22
Communications collectives
Collecte générale
int MPI_Allgather( void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int
recvcount, MPI_Datatype recvtype, MPI_Comm comm );
23
Communications collectives
Collecte
int MPI_Gatherv( void *sendbuf, int sendcnt, MPI_Datatype
sendtype, void *recvbuf, int *recvcnts, int *displs, MPI_Datatype
recvtype, int root, MPI_Comm comm );
Correspond à un MPI_GATHER() pour lequel la taille des messages
varie.
Le ième processus du comm envoie au processus root, un message
depuis l’adresse sendbuf, de taille sendcnt, de type sendtype, avec
réception du message à l’adresse recvcnts, de type recvtype, de taille
recvcnts(i) avec un déplacement de displs(i).
24
Communications collectives
Réductions réparties
Une opération appliquée à un ensemble d’éléments pour en obtenir
une seule valeur. Des exemples typiques sont la somme des
éléments d’un vecteur SUM(A(:)) ou la recherche de l’élément de
valeur maximum dans un vecteur MAX(V(:)).
Le résultat est obtenu sur un seul processus (MPI_REDUCE()) ou
bien sur tous (MPI_ALLREDUCE() , qui est en fait équivalent à un
MPI_REDUCE() suivi d’un MPI_BCAST() ).
25
Communications collectives
Réductions réparties
int MPI_Reduce( void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm
comm );
Réduction répartie des éléments situés à partir de l’adresse sendbuf,
de taille count, de type datatype, pour les processus du
communicateur comm,
Ecrit le résultat à l’adresse recvbuf pour le processus de rang root
26
Communications collectives
Réductions réparties
Principales opérations de réduction
prédéfinies
27
Communications collectives
Réductions réparties
int MPI_Reduce( void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op
op, int root, MPI_Comm comm );
28
Communications collectives
Réductions réparties avec diffusion du résultat
int MPI_Allreduce( void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm );
Réduction répartie des éléments situés à partir de l’adresse sendbuf,
de taille count, de type datatype, pour les processus du
communicateur comm,
Ecrit le résultat à l’adresse recvbuf pour tous les processus du
communicateur comm.
29
Communications collectives
Réductions réparties avec diffusion du résultat
int MPI_Allreduce( void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
MPI_Op op, MPI_Comm comm );
30