Utilisateur:Kabyhaswell/ProgrammationParallèleMPI/Exercices/Premiers pas
Lancement
modifierExercice 1-1 : lancement simple
modifierExécutez, sur votre machine, 4 processus du programme hostname
moi@thrall:$ mpiexec -n 4 hostname
thrall thrall thrall thrall
Exercice 1-2 : lancement sans options
modifierSi on ne passe pas le nombre de processus avec l'option -n <N>
, l'environnement d'exécution utilise tous les cœurs disponibles. En utilisant votre machine local, combien d'instances du programme hostname
sont lancées si vous ne la passez pas ?
mpiexec
en lance autant que de cœurs physiques (donc sans compter l'hyperthreading) sont disponibles sur la machine.
Par exemple, sur une machine équipée d'un processeur Intel Core i7-4770, donc disposant de 4 cœurs hyperthreadés, soit 4 cœurs physiques et 8 cœurs logiques, on obtient :
moi@thrall:$ mpiexec hostname thrall thrall thrall thrall
Exercice 1-3 : machinefile
modifierNous avons vu que le nombre de processus à lancer sur une machine pouvait être donné dans le machinefile. En utilisant un machinefile qui contient uniquement votre machine (donc localhost
), lancez 3 instance du programme hostname
sans passer l'option -n <N>
au mpiexec
.
On utilise l'option slots=<N>
dans le machinefile:
moi@thrall:$ cat machinefile localhost slots=3
Puis on lance avec :
moi@thrall:$ mpiexec --machinefile machinefile hostname thrall thrall thrall
Exercice 1-4 : machinefile et limites
modifierOn peut également donner dans le machinefile une limite au nombre de processus à lancer par machine. Écrivez un machinefile qui n’autorise pas plus de deux processus sur la machine locale.
localhost max-slots=2
Essayez de lancer deux instances du programme hostname
avec l'option -n 2
.
moi@thrall:$ mpiexec --machinefile machinefile -n 2 hostname
thrall thrall
L'oversubscription s'autorise avec l'option --oversubscribe
. Essayez de lancer trois instances du programme hostname
avec l'option -n 3
et votre machinefile. Que se passe-t-il ?
Cela fonctionne :
moi@thrall:$ mpiexec --oversubscribe --machinefile machinefile -n 3 hostname thrall thrall thrall
L'oversubscription s'interdit avec l'option --nooversubscribe
. En l’interdisant, essayez de lancer trois instances du programme hostname
avec l'option -n 3
et votre machinefile. Que se passe-t-il ?
Cela ne fonctionne pas, l’environnement d'exécution refuse de lancer davantage de processus qu'il n'y a de ressources disponbiles
moi@thrall:$ mpiexec --nooversubscribe --machinefile machinefile -n 3 hostname -------------------------------------------------------------------------- Conflicting directives for mapping policy are causing the policy to be redefined: New policy: oversubscribe Prior policy: BYSOCKET:NOOVERSUBSCRIBE Please check that only one policy is defined. --------------------------------------------------------------------------
Compilation
modifierExercice 1-5 : Compilation d'un programme simple
modifierCopiez le code suivant dans un fichier.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main( int argc, char** argv ) {
int rank, size;
/* Initialisation (obligatoire) */
MPI_Init( &argc, &argv );
/* On détermine qui on est et combien il y a de processus, et on l’affiche) */
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
printf( "Bonjour, je suis le processus %d/%d\n", rank, size );
/* Finalisation (obligatoire) */
MPI_Finalize();
return EXIT_SUCCESS;
}
Essayez de le compiler avec un compilateur normal, par exemple gcc
. Que se passe-t-il ? Pourquoi ?
Cela ne fonctionne pas car gcc
ne sait pas où trouver les fichiers d'en-têtes.
moi@thrall:$ gcc -o exemple1 exemple1.c exemple1.c:3:10: fatal error: mpi.h: Aucun fichier ou dossier de ce type #include <mpi.h> ^15 août 2018 à 21:06 (UTC)~ compilation terminated.
Compilez-le maintenant avec mpicc
.
Cela fonctionne sans erreur.
moi@thrall:$ mpicc -o exemple1 exemple1.c
Avec ldd
, regardez quelles bibliothèques sont liées avec l’exécutable produit. Que constatez-vous à propos de MPI ?
On voit que la bibliothèque MPI est liée avec l'exécutable.
moi@thrall:$ ldd exemple1 linux-vdso.so.1 (0x00007ffc3d3b8000) libmpi.so.40 => /opt/mpi/lib/libmpi.so.40 (0x00007f1db611c000) […]
Exercice 1-6 : Compilation d'un programme nécessitant des bibliothèques
modifierCopiez le code suivant dans un fichier.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <mpi.h>
int main( int argc, char** argv ) {
int rank;
struct timespec ts;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
clock_gettime( CLOCK_REALTIME, &ts );
printf( "Bonjour, je suis le processus %d, il est %ld secondes apres l'Epoch et sqrt( 5 ) = %lf\n", rank, ts.tv_sec, sqrt( 5.0) );
MPI_Finalize();
return EXIT_SUCCESS;
}
Ce programme fait appel à deux fonctions se trouvant dans des bibliothèques : clock_gettime
a besoin de librt
et sqrt
a besoin de libm
. Certains compilateurs les incluent eux-mêmes, certaines versions de la libc les fournissent, donc il n'est pas toujours nécessaire de lier avec ces bibliothèques. Cependant, l’objet de cet exercice est d'utiliser les appels aux fonctions qui se trouvent dans ces bibliothèques en les passant à la compilation.
Compilez le programme ci-dessus en liant avec les bibliothèques nécessaires.
On utilise le compilateur mpicc
exactement comme on utiliserait un autre compilateur.
moi@thrall:$ mpicc -o exemple2 exemple2.c -lm -lrt
Avec ldd
, regardez quelles bibliothèques sont liées avec l'exécutable produit.
On voit maintenant, en plus de la bibliothèque MPI, les bibliothèques librt
et libm
que l’on vient de lier avec l'exécutable.
moi@thrall:$ ldd exemple2 linux-vdso.so.1 (0x00007fffb44ca000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3228a98000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f3228a8e000) libmpi.so.40 => /opt/mpi/lib/libmpi.so.40 (0x00007f322877c000) […]