MPI

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Autres langues :anglais 100% • ‎français 100%

Sommaire

Description

L'interface MPI (Message Passing Interface) a été conçue pour la programmation sur des architectures à mémoire distribuée. MPI est une norme définissant un ensemble de fonctions de communication entre des processus qui sont exécutés sur un ou plusieurs processeurs.

MPI utilise en général la technique appelée SPMD (Single Program Multiple Data) pour obtenir une exécution parallèle. Selon cette technique, il n'est pas nécessaire d'écrire un programme différent pour chaque processeur, un seul suffit. Lors de l'exécution d'un programme MPI, plusieurs instances du même programme sont exécutées simultanément. Chaque instance constitue ce qu'on appelle un processus MPI. Chaque processus MPI exécute donc le même programme, mais chacune des copies de celui-ci effectue des calculs sur des données différentes selon son rang parmi les processus. Diverses fonctions de communication sont utilisées pour échanger des données entre les processus MPI.

Commandes de base

Liste de quelques commandes pour la programmation MPI. Ces appels MPI suffiront pour beaucoup de cas rencontrés par les utilisateurs de MPI.

MPI_Init Initialise les processus MPI
MPI_Comm_size Retourne le nombre de processus alloués
MPI_Comm_rank Retourne le numéro du processus où le code est exécuté
MPI_Send Envoie un message
MPI_Recv Reçoit un message
MPI_Bcast Diffusion d'une variable à tous les processus (broadcast)
MPI_Finalize Termine les processuss MPI

Implantation des commandes MPI de base en Fortran

Dans un programme MPI en Fortran, une des lignes suivantes doit apparaître au début de toutes les unités de programme (programme principal, sous-programmes, fonctions, modules) qui utilisent MPI :

include 'mpif.h'

ou

use mpi


Les sous-programmes de base en Fortran :

CALL MPI_Init( integer ierr)
CALL MPI_Comm_size( integer comm, integer size, integer ierr )
CALL MPI_Comm_rank( integer comm, integer rank, integer ierr )
CALL MPI_Send( choice buf, integer count, integer datatype, integer dest, integer tag, integer comm, integer ierr )
CALL MPI_Recv( choice buf, integer count, integer datatype, integer source, integer tag, integer comm, integer status(MPI_STATUS_SIZE), integer ierr )
CALL MPI_Bcast( choice buf, integer count, integer datatype, integer root, integer comm, integer ierr )
CALL MPI_Finalize( integer ierr )

Implantation des commandes MPI de base en C

La ligne suivante doit apparaître au début d'un programme MPI en C :

#include "mpi.h"


Les fonctions de base en C :

int MPI_Init( int *argc, int *argv )
int MPI_Comm_size( MPI_Comm comm, int *size )
int MPI_Comm_rank( MPI_Comm comm, int *rank )
int MPI_Send( 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 )
int MPI_Bcast( void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm )
int MPI_Finalize( void )

Implantation des commandes MPI de base en C++

Depuis la norme MPI 2.2, l'interface C++ est désuète. Bien qu'elle soit toujours prise en charge par les principales distribution, nous ne recommandons pas son usage, car elle pourrait être supprimée dans le futur. Utilisez plutôt l'interface C. Pour savoir ce que cela implique pour vous, nous vous suggérons l'excellent article suivant (en anglais) : The MPI C++ bindings are gone: what does it mean to you ?

Si voulez connaître l'histoire de la disparition de l'interface C++, vous pouvez consulter cet article.

Définition des paramètres

ierr Code d'erreur retourné (sortie). En C, le code d'erreur est retourné par la fonction elle-même
argc,argv Arguments passés à la fonction main d'un programme en C. Non modifiés par MPI
comm Le communicateur MPI (ex : MPI_COMM_WORLD)
size Le nombre de processus MPI dans le groupe associé au communicateur
rank Le numéro du processus MPI dans le groupe associé au communicateur
buf L'adresse du premier élément du vecteur (buffer) à transférer
count Le nombre d'éléments du vecteur à transférer
datatype Le type des données contenues dans le vecteur. Utilisez les types définis dans MPI (MPI_INTEGER, MPI_REAL8, etc.)
source Numéro du processus d'où originent les données à transférer
dest Numéro du processus recevant les données transférées
tag Étiquette identifiant le message
root Numéro du processus d'où origine la valeur de la variable lors d'une diffusion générale (broadcast)
status Objet décrivant l'état de la réception (vecteur en Fortran)

Compilation

La compilation d'un code source utilisant MPI requiert des éléments supplémentaires à ceux d'un code série. Pour simplifier la vie des utilisateurs la bibliothèque est distribuée avec des scripts de compilation qui ajoute les options requises par MPI lors de l'appel du compilateur. Ainsi, pour compiler un code en Fortran, on utilise la commande mpif90 ou mpif77, pour un code source en C, on utilise mpicc et pour un code source en C++, on utilise mpicxx.

C'est pourquoi vous trouverez sur les systèmes de Calcul Québec, bien souvent plus d'une version d'une même version de la bibliothèque désirée, MVAPICH2 ou Open MPI. Le nom du module indique si les compilateurs sous-jacents sont ceux de GCC, d'Intel ou de PGI. Notez que la liste des options passées à la commande de compilation de MPI sont transmises au compilateur sous-jacents. Il faut donc utiliser les mêmes options que celles comprises par le compilateur. Par exmple, si vous utilisez un module Open MPI avec les compilateurs d'Intel, vous pouvez compilez un fichier source C de la façon suivante (notez l'option -xHost spécifique aux compilateurs d'Intel) :

[nom@serveur $] mpicc -xHost -c monFichierSource.c


Exécution

Tel qu'expliqué précédemment, la technique de parallélisation MPI consiste à exécuter plusieurs instances du même programme, mais chacune avec des données différentes et, généralement, avec des communications entre les différentes instances. Ainsi, l'exécution du programme doit être lancée par une commande indiquant le nombre d'instances et parfois certaines informations supplémentaires. Les commandes les plus couramment utilisées sont mpirun et mpiexec. On recommande généralement d'utiliser mpiexec dont l'utilisation est un peu plus uniforme selon les distributions. Par exemple, on soumettra un cas avec quatre instances de la façon suivante :

[nom@serveur $] mpiexec -n 4 monExecutableMPI [args]


[args] indique des arguments optionnels pour l'exécutable. Avec les versions actuelles de MPI, cahque instance a accès à cette liste d'arguments. Afin de connaître la liste d'options spécifique à la version de MPI que vous utilisez, visitez les pages de Open MPI ou de MVAPICH2.

Exemples détaillés

Chaque exemple est disponible en Fortran et en C.

Exemple 1 : Hello World : L'origine de tous les exemples

Exemple 2 : Barrier : Un autre Hello World

Exemple 3 : Broadcast : Communication collective

Exemple 4 : Send-Recv : Communication point à point

Exemple 5 : Send-Recv bloquant : Communication point à point

Exemple 6 : Isend-Irecv non bloquant : Communication point à point

Exemple 7 : Scatter : Communication collective

Exemple 8 : Scatterv : Communication collective

Exemple 9 : Gather : Communication collective

Exemple 10 : Allgather : Communication collective

Exemple 11 : Alltoall : Communication collective

Exemple 12 : Reduce : Communication collective

Exemple 13 : MPI_Group : Création de groupes

Exemple 14 : Pack : Utilisation de Pack

Exemple 15 : Datatype : Création de types dérivés

Exemple 16 : Request : Méthode maître-esclaves

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager