• Aucun résultat trouvé

Travaux pratiques MPI

N/A
N/A
Protected

Academic year: 2022

Partager "Travaux pratiques MPI"

Copied!
28
0
0

Texte intégral

(1)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Travaux pratiques MPI

• Présentation de MPI

• Schéma général d’un programme MPI

• Exécution d’un programme C quelques commandes Unix

• Quelques fonctions MPI

• Exemples de programmes

• Communication

• Calcul de P

• Gestion des groupes

• Gestion des communicateurs

• Projets de TP

(2)

Présentation de MPI (Message Passing Interface)

• Bibliothèque standard à inclure dans un programme C (#include "mpi.h") ou Fortran (INCLUDE ’mpif.h’)

• Ancêtre : PVM (Parallel Virtual Machine) en 1991

• Plusieurs implantations : MPI-1(1994), MPICH2(2000) et OpenMPI(2009)

• Autres bibliothèques : OpenMP(2010),…

• Souvent utilisée dans des architectures à mémoire distribuée

• Modèle SPMD (Single Programme Multiple Data)

• Le même programme est installé dans chaque processeur (ou machine)

• Des instances multiples du programme traitent partiellement ou totalement les données

• Chaque instance a un identificateur unique par rapport à un communicateur

• L’instance exécute la partie du programme selon son identificateur

• Référence : http://www.open-mpi.org,...

(3)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Schéma général d’un programme MPI

rang  identificateur du processus en cours par rapport à un communicateur si (rang = identificateur_spécifique) alors

faire un traitement sinon

faire un autre traitement

p0

p1

p2

p3

p4

p5

p6

Communicateur A Communicateur B

(4)

Exécution d’un programme C

/* fichier hello.c*/

#include <stdio.h>

int main() {

printf("Hello World!");

return 0;

}

Compilation:

$gcc hello.c (ou gcc –o hello.exe hello.c) Exécution:

$./a (ou /home/……./a.exe ou ./hello) Résultat:

$ Hello World!

(5)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Quelques commandes Unix

$pwd

$ls -l

$hostname

$mpirun -n 1 hostname (ou mpiexec -np 1 hostname)

$mpirun -n 7 hostname

$mpirun hostname

$mpirun -n 5 hello

$mpirun -n 12 hello

$mpirun -machinefile machine.txt -n 4 hostname

(6)

Quelques fonctions MPI (1/2)

int MPI_Init(int *argc, char ***argv) int MPI_Finalize()

int MPI_Comm_rank(MPI_Comm comm, int *rank) int MPI_Comm_size(MPI_Comm comm, int *size)

int MPI_Send(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)

int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)

int MPI_Comm_group(MPI_Comm comm, MPI_Group *group) int MPI_Group_incl(MPI_Group group, int n, const int ranks[],

MPI_Group *newgroup) int MPI_Comm_create(MPI_Comm comm, MPI_Group group,

MPI_Comm *newcomm)

(7)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Quelques fonctions MPI (2/2)

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

MPI_Datatype datatype, MPI_Op op, int root,MPI_Comm comm) Int MPI_Allreduce( void *sendbuf, void *recvbuf, int count,

MPI_Datatype datatype, MPI_Op op, MPI_Comm comm ) Opérations :

MPI_MAX : maximum MPI_MIN : minimum

MPI_SUM : sum MPI_PROD : product

MPI_LAND : logical and MPI_BAND : bit-wise and MPI_LOR : logical or MPI_BOR : bit-wise or MPI_LXOR: logical xor MPI_BXOR : bit-wise xor

MPI_MAXLOC : max value + location MPI_MINLOC : min value + location Liste complète (≈360 fonctions) : https://www.open-mpi.org/doc/v1.8

(8)

Exemples de programmes

• Exemple 1 : Communication entre processus

• Exemple 2 : Calcul de P

• Exemple 3 : Gestion des groupes

• Exemple 4 : Gestion des communicateurs

• Exercices

(9)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Algorithme de communication

p  nombre total des processus rang  identificateur du processus si (rang ≠ 0) alors

message  ″Hello world du processus″ + rang envoyer(message,0)

sinon

écrire(″Hello world du processus 0 : nombre de processus ″,p) pour source=1 à (p-1) faire

recevoir(message,source)

écrire(message) p0

p2 p3

p1

(10)

Programme de communication (1/3)

/* programme helloMPI.c*/

#include <stdio.h>

#include <string.h>

#include "mpi.h"

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

int my_rank; /* rank of process */

int p; /* number of processes */

int source; /* rank of sender */

int dest; /* rank of receiver */

int tag=0; /* tag for messages */

char message[100]; /* storage for message */

MPI_Status status ; /* return status for receive */

(11)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Programme de communication (2/3)

/* start up MPI */

MPI_Init(&argc, &argv);

/* find out process rank */

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* find out number of processes */

MPI_Comm_size(MPI_COMM_WORLD, &p);

if (my_rank !=0){

/* create message */

sprintf(message, "Hello MPI World from process %d!", my_rank);

dest = 0; /* use strlen+1 so that '\0' get transmitted */

MPI_Send(message, strlen(message)+1, MPI_CHAR,dest,

tag,MPI_COMM_WORLD);

}

(12)

Programme de communication (3/3)

else{

printf("Hello MPI World From process 0: Num processes: %d\n",p);

for (source = 1; source < p; source++) {

MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status);

printf("%s\n",message);

} }

/* shut down MPI */

MPI_Finalize();

return 0;

}

(13)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Exercice 1

a) Compilation

$mpicc -o helloMPI.exe helloMPI.c -lm b) Exécution

$mpirun -n 5 helloMPI.exe c) Création de helloMPIMod.c

supprimer l’appel MPI_Send exécuter le programme

Que se passe-t-il ? d) Création de course.c

supprimer les appels MPI_Send

supprimer la boucle lorsque my-rank=0 (processus p0) remplacer sprintf par printf (un affichage par processus) exécuter le programme à 2 reprises

Que se passe-t-il ?

(14)

Algorithme du calcul de P

Calc_pi(rank, num_procs) si (rank = 0) alors

num_intervals  1000 diffuser(num_intervals)

h  1/num_intervals sum0

pour i = rank + 1 à num_intervals pas num_procs x=h * (i – 0,5)

sum = sum + 4*racine_carrée(1 – x

2

) mypi = h* sum

reduce(mypi,pi)

si (rank = 0) alors écrire(″PI=″, pi)

(15)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Schéma du calcul de P

Hypoyhèse :

num_procs = 3 (p0, p1 et p2) num_intervals =10 donc h = 0,1 p0 calcule les valeurs

x=0,05, x=0,35, x=0,65 et x=0,95 p1 calcule les valeurs

x=0,15, x=0,45 et x=0,75 p2 calcule les valeurs

x=0,25, x=0,55 et x=0,85

p0 p1 p2 p0 p1 p2 p0 p1 p2 p0 1 1

(16)

Programme du calcul de P (1/5)

/* fichier calculPi.c */

#include <mpi.h>

#include <stdio.h>

#include <string.h>

void calc_pi(int rank, int num_procs){

int i;

int num_intervals;

double h;

double mypi;

double pi;

double sum;

double x;

/* set number of intervals to calculate */

if (rank == 0) {

num_intervals = 1000;

}

(17)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Programme du calcul de P (2/5)

/* tell other tasks how many intervals */

MPI_Bcast(&num_intervals, 1, MPI_INT, 0, MPI_COMM_WORLD);

/* now everyone does their calculation */

h = 1.0 / (double) num_intervals;

sum = 0.0;

for (i = rank + 1; i <= num_intervals; i += num_procs) { x = h * ((double)i - 0.5);

sum += (4.0 * sqrt(1.0 - x*x));

}

mypi = h * sum;

/* combine everyone's calculations */

MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,MPI_COMM_WORLD);

if (rank == 0) {

printf("PI is approximately %.16f\n", pi);

} }

(18)

Programme du calcul de P (3/5)

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

int my_rank; /* rank of process */

int num_procs; /* number of processes */

int source; /* rank of sender */

int dest = 0; /* rank of receiver */

int tag = 0; /* tag for messages */

char message[100]; /* storage for message */

MPI_Status status ; /* return status for receive */

/* start up MPI */

MPI_Init(&argc, &argv);

/* find out process rank */

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* find out number of processes */

MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

(19)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Programme du calcul de P (4/5)

if (my_rank != 0) {

/* create message */

snprintf(message,26, "Greetings from process %d!", my_rank);

/* use strlen+1 so that '\0' get transmitted */

MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

}

else {

printf("Num processes: %d\n",num_procs);

for (source = 1; source < num_procs; source++) {

MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status);

printf("Process 0 received \"%s\"\n",message);

}

(20)

Programme du calcul de P (5/5)

/* now return the compliment */

snprintf(message, 26, "Hi, how are you? ");

}

MPI_Bcast(message, strlen(message)+1, MPI_CHAR, dest,

MPI_COMM_WORLD);

if (my_rank != 0) {

printf("Process %d received \"%s\"\n", my_rank, message);

}

/* calculate PI */

calc_pi(my_rank, num_procs);

/* shut down MPI */

MPI_Finalize();

return 0;

}

(21)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Exercice 2

a) Compilation

$mpicc -o helloMPI.exe helloMPI.c b) Exécution

$mpirun -n 4 helloMPI.exe

c) Corriger le programme pour calculer P

d) Créer calculMod.c tel que P = 4 *

dx/(1 + x2)

e) Quelle est la version qui donne les meilleures précisions relativement à num_intervals réduit sachant que les 25 chiffres de P sont :

Pi25 = 3,141592653589793238462643

f) Déterminer le temps d’exécution des deux versions en utilisant MPI_Wtime()

0 1

(22)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Algorithme de gestion des groupes

NBPROCS=8

rank1={0,1,2,3}, rank2=[4,5,6,7}

rank  identificateur du processus p nombre total des processus

si (rank < NBPROCS / 2) alors inclure(rank,groupe1)

Sinon

inclure (rank,groupe2) recevoir(message,source) écrire(message)

22

(23)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Programme de gestion des groupes (1/2)

#include "mpi.h"

#include <stdio.h>

#define NPROCS 8

int main(argc,argv) int argc; char *argv[]; {

int rank, new_rank, sendbuf, recvbuf, ranks1[4]={0,1,2,3},ranks2[4]={4,5,6,7};

MPI_Group orig_group, new_group;

MPI_Comm new_comm;

MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

sendbuf = rank;

/* Extract the original group handle */

MPI_Comm_group(MPI_COMM_WORLD, &orig_group);

(24)

Programme de gestion des groupes (2/2)

/* Divide tasks into two distinct groups based upon rank */

if (rank < NPROCS/2)

MPI_Group_incl(orig_group, NPROCS/2, ranks1, &new_group);

else

MPI_Group_incl(orig_group, NPROCS/2, ranks2, &new_group);

/* Create new communicator and then perform collective communications */

MPI_Comm_create(MPI_COMM_WORLD, new_group, &new_comm);

MPI_Allreduce(&sendbuf, &recvbuf, 1, MPI_INT, MPI_SUM, new_comm);

MPI_Group_rank (new_group, &new_rank);

printf("rank= %d newrank= %d recvbuf= %d\n",rank,new_rank,recvbuf);

MPI_Finalize();

}

(25)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Algorithme de gestion des communicateurs

mon_rang  identificateur du processus P  nombre total des processus

si (mon_rang < NBPROCS 0) alors inclure(mon_rang,groupe1)

Sinon

inclure (mon_rang,groupe2) recevoir(message,source)

écrire(message)

(26)

Programme de gestion des communicateurs

#include <stdio.h>

#include <mpi.h>

main(int argc, char **argv) {

MPI_Comm row_comm, col_comm;

int myrank, size, P=4, Q=3, p, q;

MPI_Init (&argc, &argv);

MPI_Comm_rank (MPI_COMM_WORLD, &myrank);

MPI_Comm_size (MPI_COMM_WORLD, &size); /* Determine row and column position */

p = myrank / Q; q = myrank % Q; /* pick a row-major mapping */ /* Split comm into row and column comms */

MPI_Comm_split(MPI_COMM_WORLD, p, q, &row_comm); /* color by row, rank by column */ MPI_Comm_split(MPI_COMM_WORLD, q, p,

&col_comm); /* color by column, rank by row */

printf("[%d]:My coordinates are (%d,%d)\n",myrank,p,q);

MPI_Finalize();

(27)

Architectures parallèles, M. Eleuldj, Département Génie Informatique, EMI, octobre 2014

Exercice 3

a)

Compilation

$mpicc -o groupe.exe groupe.c b) Exécution

$mpirun groupe.exe

c) Diviser MPI_COMM_WORLD en 3 communicateurs non chevauchés (non- overlapped) tels que :

processus du rang 0, 3, 6,... appartient au premier groupe processus du rang 1, 4, 7,... appartient au deuxième groupe processus du rang 2, 5, 8,... appartient au troisième groupe

(28)

Références

• Ivan Lavallée, « Algorithmique parallèle et distribuée » Traité des nouvelles technologies, Hermes, 1990.

• Kai Hwang, « Advanced computer architecture:

Parallelism, Sqcalability, Programmability », McGraw Hill Series in Computer Science, 1993.

• http://www.unix.mcs.anl.gov/mpi/tutorial/perf/index.ht ml

• http://www.unix.mcs.anl.gov/mpi « MPI : A message Passing Interface Standard », Message Passing

Interface Forum, 1995

Références

Documents relatifs

int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm). adresse du

[r]

On fait cela tant qu’il y a plusieurs ´el´ements dans le tableau.. Si le tableau est de taille impaire, son ´el´ement central

Avec cmovl on a if(*t&lt;m) m=*t; et la fonction calcule le plus petit ´el´ement.. Avec cmova la comparaison est

On oublie donc les s ` a la fin de vingt, cent, million

(Within these notes, for simplicity, we equate GOF patterns with design patterns; we use Small Cap- itals for the names of patterns.) These programs are parametrized along

3) Montrer que si la suite (f n ) converge en mesure vers la fonction f, alors elle poss` ede une sous-suite qui converge presque partout

[r]