MPI (Message Passing Interface)

Slides:



Advertisements
Présentations similaires
Hiver 2010JGA Beaulieu GEF 243B Programmation informatique appliquée Structure de base des programmes en C.
Advertisements

Premier programme en C :
La boucle for : init7.c et init71.c
Communications point à point Communications collectives Optimisations
Introduction au Langage C,C++
A RECUPERER EN ENTRANT Le polycopié de Caml Partie 1
Rappels C.
Développement logiciel sur micro-contrôleurs PIC en C
Formation C débutant. Notion de compilation source.c executable Phase de compilation Fichier de texte brut, inexploitable directement par la machine Fichier.
C.
Introduction à MPI 13 – 16 Décembre 2005 Laurence Viry.
Introduction à MPI Types dérivés MPI Décembre 2005

Structures et unions types énumérés Qu'est-ce qu'une structure
Les pointeurs Manipulation d'adresses et de ce qui est contenu dans ces adresses Très important, fondamental même en C mauvaise réputation : 'dur à comprendre',
Tableaux Certains problèmes nécessitent beaucoup de variables du même type. Exemple : relevé de températures matin et soir dans 10 villes pour 10 jours.
FLSI602 Génie Informatique et Réseaux
Parallel Programming in C with MPI and OpenMP
MPI et programmation par passage de messages
Common Gateway Interface
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Récursivité.
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
Présentation rapide de MPI : Message Passing Interface
Programme de baccalauréat en informatique Algorithmique et programmation IFT-1001 Thierry EUDE Hatem Mahbouli Laboratoire #12 Département dinformatique.
PROGRAMMATION SCIENTIFIQUE EN C PRO Généralités u Présentation du plan de cours –Disponibilité –Références u Environnement de travail –Langage C.
TRAITEMENT DE STRUCTURES
Langage Oriente Objet Cours 2.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Sixième cours Les chaînes de caractères et le passage de paramètres par référence Passage de paramètres par référence String.h.
IFT 6800 Atelier en Technologies d’information
Une brève introduction à MPI Destinée à l usage des utilisateurs de CIMENT Laurent Desbat juin 2002.
Parallel Programming in C with MPI and OpenMP
8PRO100 Éléments de programmation Les types composés.
COURS DE PROGRAMMATION ORIENTEE OBJET :
Plan cours La notion de pointeur et d’adresse mémoire.
L’essentiel du langage C
Structures des données
Le langage C Structures de données
Importance du réseau dans des architectures MIMD Tout échange entre les processeurs nécessite un transfert de données via le réseau.
Programmer en langage c
Programmation Système et Réseau (sous Linux)
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
La notion de type revisitée en POO
et quelques rappels sur certains éléments du langage C
Argc et argv Utilisation des paramètres de la ligne de commande.
Autres éléments du langage
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que l’on veut allouer. Le premier exemple: #include void main()
Buffer Overflow When Data Become Instructions Vendredi, 1er mars 2002 : Sart-Tilman.
Programmation parallèle
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
Programmation Système et Réseau
Les types composés Les enregistrements.
TABLEAUX des POINTEURS TRAITEMENT DE STRUCTURES
ISBN Chapitre 10 L'implémentation des sous- programmes.
8PRO100 Éléments de programmation Les pointeurs de caractères.
Cours LCS N°4 Présenté par Mr: LALLALI
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Pthread Ordonnancement. #define _MULTI_THREADED #include #ifndef _CHECK_H #define _CHECK_H /* headers used by a majority of the example program */ #include.
Master IRAD - SPIN / PROMELA
Client/Server Socket. Client/Serveur.
C++ BY AURÉLIEN MODULO MARION. PLAN DES TROIS PRÉSENTATIONS C++ avancé C++ orienté objet Bases de C++
1 UNIX AVANCE Yves PAGNOTTE – Janvier – LES PROCESSUS SOUS UNIX.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
M. BENJELLOUN : 2005 Le but final est de programmer un jeu où l'ordinateur choisira un nombre aléatoire entre 0 et 100 que vous devez deviner.
Transcription de la présentation:

MPI (Message Passing Interface) بـسـم الله الرحــمــن الرحـــيــم MPI (Message Passing Interface)

Introduction MPI est un environnement de programmation par passage de message qui fournit une large variété de primitives qui peuvent être appelées à partir de programmes C, C++, Fortran… Dans ce cours, nous allons voir la version 1, qui est basée sur un modèle de programmation statique : un nombre fixe de processus est créé au début de l'exécution du programme. La version MPI-2, permet la création dynamique de processus.

Architectures visées Machine parallèles à mémoire distribuée Grappes de stations (clusters) Réseaux hétérogènes de stations

Format des fonctions err = MPI_Xxxx(paramètre,...);

Initialisation Chaque programme MPI doit contenir la directive : #include "mpi.h" Avant l'appel de toute fonction MPI, la fonction MPI_Init doit être appelée: int MPI_Init(int argc, char **argv) Cette fonction permet d'initialiser MPI.

Quitter MPI int MPI_Finalize() Permet de sortir de MPI et doit être appelée par tous les processus. Aucune fonction MPI ne doit être appelée après cette fonction.

Bonjour! (bonjour.c) #include <stdio.h> #include "mpi.h" main(int argc, char* argv[]) { MPI_Init(&argc, &argv); /* Démarrer MPI */ printf("Bonjour !\n"); MPI_Finalize(); /* Quitter MPI */ } /* main */

Compilation et exécution La compilation et l'exécution dépendent de l’environnement et de l’implémentation : MPICH CHIMP LAM

Compilation et exécution (salle de TP) Nous disposons de la version MPI-LAM. Compilation : mpicc bonjour.c –o boujour Exécution Avant l'exécution il faut lancer le démon MPI avec la commande lamboot (une seule fois). Pour lancer 4 processus : mpirun –np 4 bonjour Avant de quitter votre session, il faut lancer la commande lamhalt pour arrêter le démon MPI.

Communicateur MPI_COMM_WORLD Un communicateur est un ensemble de processus qui peuvent échanger des messages entre eux. MPI_COMM_WORLD est un communicateur prédéfini qui regroupe tous les processus. On peut définir d'autres communicateurs.

Communicateur MPI_COMM_WORLD

Rang d'un processus MPI_Rank(MPI_Comm comm, int *rang) retourne le rang d'un processus dans un communicateur (rang est un entier).

Taille MPI_Comm_size(MPI_Comm comm, int *taille) donne le nombre de processus dans le communicateur "comm'' (taille est un entier).

Exemple #include <stdio.h> #include "mpi.h" main(int argc, char* argv[]) { int rang; /* rang du processus */ int p; /* nombre de processus */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rang); MPI_Comm_size(MPI_COMM_WORLD, &p); printf("Mon numéro est : %d et le nombre de processus est :%d \n",rang,p); MPI_Finalize(); }

Communications point à point (point-to-point)

Envoi de messages MPI_Send(void* message, int count, MPI_Datatype datatype, int dest, int etiquette, MPI_Comm comm) Envoie un message à "dest''. Elle est bloquante.

MPI_Send (description): message : tableau de type ``datatype''. count : taille du message. datatype : type des données. Les types prédéfinies sont : MPI_CHAR MPI_SHORT MPI_INT MPI_UNSIGNED_CHAR MPI_LONG MPI_UNSIGNED_SHORT MPI_FLOAT MPI_UNSIGNED_LONG MPI_DOUBLE MPI_LONG_DOUBLE MPI_UNSIGNED MPI_PACKED MPI_BYTE etiquette : étiquette (pour différencier les messages d’un même couple émetteur/receveur).

Réception MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int etiquette, MPI_Comm comm, MPI_Status *status) Permet de recevoir un message de "source''. Elle est bloquante. "source'' peut avoir la valeur MPI_ANY_SOURCE (n'improte quelle source). "etiquette'' peut avoir la valeur MPI_ANY_TAG (n'importe quelle étiquette).

Réception (description) status : identificateur de l'émetteur et du message reçu. status.MPI_SOURCE : source status.MPI_TAG : tag status.ERROR : erreur "status'' contient l'information sur la taille du message. Pour cela, on appelle la fonction : int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *nbre)

Ordre de réception des messages Si deux processus A et B envoient un message à un autre processus C, l'ordre d'arrivé des messages n'est pas déterminé. Si un processus envoie un message m1 à C ensuite envoie un message m2 à C, alors m1 sera reçu avant m2.

… Exemple Affichage P0 bonjour de 1! P1 bonjour de 2! P2 bonjour de 7!

#include <stdio.h> #include <string.h> #include "mpi.h" main(int argc, char* argv[]) { int my_rank; /* rang du processus */ int p; /* nombre de processus */ int source; /* rang de l'émetteur */ int dest; /* rang du récepteur */ int tag = 0; /* étiquette */ char message[100]; /*pour stocker le message*/ MPI_Status status; /* status du message */ MPI_Init(&argc, &argv); /* Démarrer MPI */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p);

if (my_rank != 0) { /* si je ne suis pas le processus racine*/ sprintf(message, "Bonjour de %d!", my_rank); dest = 0; /* Utiliser strlen+1 pour que '\0' soit transmis! */ MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); } else { /* my_rank == 0 */ for (source = 1; source < p; source++) { MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status); printf("%s\n", message); } MPI_Finalize(); /* Quitter MPI */ } /* fin de la fonction main */

Exercices Utiliser MPI_ANY_SOURCE et MPI_ANY_TAG pour écrire le programme suivant : chaque processus envoi son rang au processus 0 le processus 0 reçoit le numéro et l'affiche Ecrire un programme qui permet de réaliser: le processus 0 envoi un vecteur au processus 1, le processus 1 envoie le vecteur reçu au processus 2 et ainsi de suite, jusqu'à réception du vecteur par le dernier processus.

Ecrire un programme qui fait la même chose que l'exercice 2, mais cette fois le message est envoyé en pipeline (découpé en plusieurs morceaux).

Envoi/réception non bloquant int MPI_Isend(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)

Communications collectives

Synchronisation int MPI_Barrier(MPI_Comm comm) Synchronisation ou rendez-vous Pas d'échange d'informations Tous les processus sont assurés que tous ont ralliés le point de synchronisation

Diffusion Un même processus envoie une même valeur à tous les autres processus (d'un communicateur). Données A0 A0 processus

Diffusion int MPI_Bcast(void *buff, int count, MPI_Datatype datatype, int root, MPI_Comm comm) Appel par tous les processus du communicateur comm avec la même valeur de root, count, datatype. La valeur détenue par le processus root sera émise et rangée chez chacun des autres processus.

Diffusion void Get_data(int my_ rank, float *a_ ptr){ int root = 0; int count = 1; if (my_ rank == root) { printf(" Donner a\ n"); scanf("%f", a_ ptr); } MPI_Bcast(a_ptr, 1, MPI_FLOAT, root, MPI_COMM_WORLD);

Réduction Collecte et réduction par un processus d'un ensemble de valeurs détenues par tous les processus. Données A0 B0 C0 D0 E0 A0+B0+C0+D0+E0 processus

Réduction MPI_Reduce(void *sbuf, void* rbuf, int count, MPI_Datatype dtype, MPI_Op op, int root, MPI_Comm comm) Appel par tous les processus du communicateur comm avec une même valeur de count, datatype, op. Les Opérations binaires prédéfinies par MPI sont (MPI_ MAX , MPI_ SUM ...), avec possibilité de définir de nouvelles opérations. Seul le processus root détient le résultat.

Exemple ps_local = ps(x,y,n); /* produit scalaire de deux vecteurs */ MPI_Reduce(&ps_local, &ps_global, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);

Réduction généralisée int MPI_Allreduce(void *sbuf, void *rbuf, int count, MPI_Datatype dtype, MPI_Op op, MPI_Comm comm) C'est une réduction avec résultat dans chacun des processus.

Exemple ps_local = ps(x,y,n); /* produit scalaire de deux vecteurs */ MPI_Allreduce(&ps_local, &ps_global, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);

Rassemblement int MPI_Gather(void *sbuf, int scount, MPI_Datatype sdtype, void *rbuf, int rcount, MPI_Datatype rdtype, int root, MPI_Comm comm) Mise bout à bout des messages de chacun des processus (All-to-One). Données A0 B0 C0 D0 E0 A0 B0 C0 D0 E0 processus

Commérage (All-to-All) int MPI_Allgather(void *sbuf, int scount, MPI_Datatype sdtype, void *rbuf, int rcount, MPI_Datatype rdtype, MPI_Comm comm) Même chose que MPI_Gather, avec résultat dans chacun des processus. Données A0 B0 C0 D0 E0 A0 B0 C0 D0 E0 processus

Distribution personnalisée int MPI_Scatter(void *sbuf, int scount,MPI_Datatype sdtype, void *rbuf, int rcount, MPI_Datatype rdtype, int root, MPI_Comm comm) Distribution d'un message personnalisé aux autres processus (One-to-All) Données A0 B0 C0 D0 E0 A0 B0 C0 D0 E0 processus

Compactage/décompactage Les fonctions MPI_Pack et MPI_Unpack, compactent et décompactent différents données destinées à être envoyées. int MPI_Pack(void *buf, int count, MPI_Datatype dtype, void *packbuf, int packsize, int *packpos, MPI_Comm comm) int MPI_Unpack(void* inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)

Exemple #define COM MPI_COMM_WORLD if (my_rank == root){ printf("Donner a, b, et n\ n"); scanf("% f %f %d", a, b, n); /* compactage des données dans le buffer */ position = 0; /* On commence au début du buffer */ MPI_ Pack( a, 1, MPI_ FLOAT, buffer, 100, &position, COM); /* position a été incrémenté de sizeof(float) bytes */ MPI_ Pack( b, 1, MPI_ FLOAT, buffer, 100, &position,); MPI_ Pack( n, 1, MPI_ INT, buffer, 100, &position, COM); /* Diffusion du contenu du buffer */ MPI_Bcast( buffer, 100, MPI_PACKED, root, COM); }

exemple (suite) else { MPI_Bcast( buffer, 100, MPI_PACKED, root, COM); /* Unpack des données depuis le buffer */ position = 0; MPI_ Unpack( buffer, 100, &position, a, 1, MPI_FLOAT, COM); /* De même, position a été incrémenté de sizeof( float) bytes */ MPI_Unpack( buffer, 100, &position, b, 1, MPI_FLOAT, COM); MPI_Unpack( buffer, 100, &position, n, 1, MPI_INT, COM); }