Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
developpement:activites:integration:par4all4wheezy [2013/09/26 09:13] equemene [Installation] |
developpement:activites:integration:par4all4wheezy [2015/01/07 10:04] (Version actuelle) |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
====== Installation de Par4All sous Debian Wheezy ====== | ====== Installation de Par4All sous Debian Wheezy ====== | ||
- | |||
- | |||
- | <note important>En construction</note> | ||
<note important>Cette page présente l'installation de par4all pour les versions 1.4 de Par4All. </note> | <note important>Cette page présente l'installation de par4all pour les versions 1.4 de Par4All. </note> | ||
Ligne 19: | Ligne 16: | ||
===== Installation ===== | ===== Installation ===== | ||
+ | |||
+ | ==== Préparation du système ==== | ||
+ | |||
+ | <code> | ||
+ | apt-get install libncurses5 libreadline6 python ipython cproto indent flex bison automake libtool autoconf libreadline6-dev python-dev swig python-ply libgmp3-dev libmpfr-dev gfortran subversion git wget libmpfr4 python-docutils tex4ht | ||
+ | </code> | ||
+ | |||
+ | ==== Récupération, compilation et installation ==== | ||
Voici les quelques commandes pour installer **Par4All** dans ''/opt'' à partir des sources. | Voici les quelques commandes pour installer **Par4All** dans ''/opt'' à partir des sources. | ||
Ligne 43: | Ligne 48: | ||
</code> | </code> | ||
+ | ===== Utilisation ===== | ||
- | ==== Préparation du système ==== | ||
- | <code> | + | <note important> |
- | apt-get install libncurses5 libreadline6 python ipython cproto indent flex bison automake libtool autoconf libreadline6-dev python-dev swig python-ply libgmp3-dev libmpfr-dev gfortran subversion git wget libmpfr4 python-docutils tex4ht | + | Je conseille très **fortement** de toujours disposer d'exécutables "//témoins//" pour vérifier les sorties des autres implémentations ! Nous pouvons voir que le programme ci-dessus présente en sortie les éléments de la diagonale de la matrice, éléments qui peuvent être utilisés pour une vérification //a minima// des résultats.</note> |
- | </code> | + | |
- | ==== Récupération, compilation et installation ==== | + | ==== Le code source ==== |
- | + | ||
- | Pour la version 1.2 : le dossier d'installation choisi est ''/opt/par4all-1.2'' | + | |
- | <code> | + | |
- | # Passage en root | + | |
- | sudo su - | + | |
- | # Recuperation du code par WGET | + | |
- | cd /tmp | + | |
- | wget http://download.par4all.org/releases/debian/x86_64/par4all-1.2-d26bc44_src.tar.gz | + | |
- | # Expansion de l'archive | + | |
- | tar xzf par4all-1.2-d26bc44_src.tar.gz | + | |
- | # Passage dans le répertoire | + | |
- | cd par4all-1.2_src/ | + | |
- | # Compilation et installation dans /opt/par4all-1.2 | + | |
- | src/simple_tools/p4a_setup.py --prefix=/opt/par4all-1.2 -v --jobs=4 | + | |
- | </code> | + | |
- | + | ||
- | + | ||
- | Pour la version 1.3 | + | |
- | <code> | + | |
- | # Passage en root | + | |
- | sudo su - | + | |
- | # Recuperation du code par WGET | + | |
- | cd /tmp | + | |
- | wget http://download.par4all.org/development/debian/x86_64/2011-10-15/par4all-1.3-20111015T235237~6d76df5_src.tar.gz | + | |
- | # Expansion de l'archive | + | |
- | tar xzf par4all-1.3-20111015T235237~6d76df5_src.tar.gz | + | |
- | # Passage dans le répertoire | + | |
- | cd par4all-1.3_src/ | + | |
- | # Compilation et installation dans /opt/par4all-1.3 | + | |
- | src/simple_tools/p4a_setup.py --prefix=/opt/par4all-1.3 -v --jobs=4 | + | |
- | </code> | + | |
- | + | ||
- | <code> | + | |
- | + | ||
- | </code> | + | |
- | + | ||
- | + | ||
- | + | ||
- | ===== Utilisation ===== | + | |
- | + | ||
- | La première étape consiste à charger les variables d'environnements pour ensuite utiliser la commande "magique", ''p4a''<code> | + | |
- | # Pour la version 1.3 et si vous utilisez ksh ou assimiles | + | |
- | source /opt/par4all-1.3/etc/par4all-rc.sh | + | |
- | # Pour la version 1.3 et si vous utilisez csh ou assimiles | + | |
- | source /opt/par4all-1.3/etc/par4all-rc.csh | + | |
- | </code> | + | |
Ensuite, il faut disposer d'un code très simple et que nous savons aisément parallélisable : un produit de matrices par exemple. Le code source le plus élémentaire que nous puissions trouver est le suivant : | Ensuite, il faut disposer d'un code très simple et que nous savons aisément parallélisable : un produit de matrices par exemple. Le code source le plus élémentaire que nous puissions trouver est le suivant : | ||
Ligne 102: | Ligne 60: | ||
#include <stdio.h> | #include <stdio.h> | ||
- | #define size 2048 | + | #define SIZE 2048 |
#define FTYPE double | #define FTYPE double | ||
int main(void) | int main(void) | ||
{ | { | ||
- | FTYPE a[size][size]; | + | FTYPE a[SIZE][SIZE]; |
- | FTYPE b[size][size]; | + | FTYPE b[SIZE][SIZE]; |
- | FTYPE c[size][size]; | + | FTYPE c[SIZE][SIZE]; |
+ | FTYPE trace=0.; | ||
- | int i,j,k; | + | for (unsigned int i = 0; i < SIZE; ++i) { |
- | + | for (unsigned int j = 0; j < SIZE; ++j) { | |
- | for (i = 0; i < size; ++i) { | + | a[i][j] = (FTYPE)(i + j); |
- | for ( j = 0; j < size; ++j) { | + | b[i][j] = (FTYPE)(i - j); |
- | a[i][j] = (FTYPE)i + j; | + | |
- | b[i][j] = (FTYPE)i - j; | + | |
c[i][j] = 0.0f; | c[i][j] = 0.0f; | ||
} | } | ||
} | } | ||
- | for ( i = 0; i < size; ++i) { | + | for (unsigned int i = 0; i < SIZE; ++i) { |
- | for ( j = 0; j < size; ++j) { | + | for (unsigned int j = 0; j < SIZE; ++j) { |
- | for (k = 0; k < size; ++k) { | + | for (unsigned int k = 0; k < SIZE; ++k) { |
c[i][j] += a[i][k] * b[k][j]; | c[i][j] += a[i][k] * b[k][j]; | ||
} | } | ||
Ligne 129: | Ligne 86: | ||
} | } | ||
- | for ( i = 0; i < size; ++i) { | + | for (unsigned int i = 0; i < SIZE; ++i) { |
- | printf("%f ",c[i][i]); | + | trace+=c[i][i]; |
} | } | ||
- | printf("\n"); | + | |
+ | printf("La trace de la matrice est %.2f\n",trace); | ||
return 0; | return 0; | ||
} | } | ||
</code> | </code> | ||
+ | |||
+ | ==== Compilation standard & Exécution ==== | ||
Si nous appelons ce code ''matrix.c'', pour le compiler simplement avec GCC, nous avons :<code> | Si nous appelons ce code ''matrix.c'', pour le compiler simplement avec GCC, nous avons :<code> | ||
- | gcc -o matrix matrix.c | + | gcc -std=c99 -o matrix matrix.c |
</code> | </code> | ||
- | Si nous voulons optimiser un peu la compilation, nous utilisons les options ''-O3'', ''-mtune=native'' et ''-march=native'' :<code> | + | En exécutant directement **matrix** par ''/usr/bin/time ./matrix'', nous obtenons un superbe ''Segmentation fault''. |
- | gcc -O3 -march=native -mtune=native -o matrix matrix.c | + | <code> |
+ | Command terminated by signal 11 | ||
+ | 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 376maxresident)k | ||
+ | 0inputs+0outputs (0major+134minor)pagefaults 0swaps | ||
</code> | </code> | ||
- | <note important> | + | Pour y remédier, nous étendons la taille de la pile (//stack// en langue de Shakespeare) à l'infini : |
- | Je conseille très **fortement** de toujours disposer d'exécutables "//témoins//" pour vérifier les sorties des autres implémentations ! Nous pouvons voir que le programme ci-dessus présente en sortie les éléments de la diagonale de la matrice, éléments qui peuvent être utilisés pour une vérification //a minima// des résultats.</note> | + | <code> |
+ | # Pour eviter les Segmentation Fault | ||
+ | ulimit -s unlimited | ||
+ | </code> | ||
+ | |||
+ | L'exécution précédente de **matrix** par la commande ''/usr/bin/time ./matrix'' donne alors : | ||
+ | <code> | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 152.60user 0.02system 2:32.91elapsed 99%CPU (0avgtext+0avgdata 98796maxresident)k | ||
+ | 0inputs+0outputs (0major+24740minor)pagefaults 0swaps | ||
+ | </code> | ||
+ | |||
+ | Le programme s'est exécuté en 2 minutes et 32 secondes et donne une trace de 18428734073246580736. | ||
+ | |||
+ | ==== Compilation optimisée & Exécution ==== | ||
+ | |||
+ | Nous avons plusieurs [[http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html|niveaux d'optimisation intégré à GCC]]. | ||
+ | |||
+ | Si nous voulons optimiser un peu la compilation, nous utilisons les options ''-O2'', ''-mtune=native'' :<code> | ||
+ | gcc -std=c99 -O2 -mtune=native -o matrix-O2 matrix.c | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 75.10user 0.02system 1:15.26elapsed 99%CPU (0avgtext+0avgdata 98796maxresident)k | ||
+ | 0inputs+0outputs (0major+24740minor)pagefaults 0swaps | ||
+ | </code> | ||
+ | |||
+ | Si nous voulons optimiser un peu la compilation, nous utilisons les options ''-O3'', ''-mtune=native'' :<code> | ||
+ | gcc -std=c99 -O3 -mtune=native -o matrix-O3 matrix.c | ||
+ | </code> | ||
+ | |||
+ | L'exécution précédente de **matrix** par la commande ''/usr/bin/time ./matrix-O3'' donne alors : | ||
+ | <code> | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 39.61user 0.01system 0:39.70elapsed 99%CPU (0avgtext+0avgdata 98796maxresident)k | ||
+ | 0inputs+0outputs (0major+24740minor)pagefaults 0swaps | ||
+ | </code> | ||
+ | |||
==== Pour utiliser P4A en mode analyse ==== | ==== Pour utiliser P4A en mode analyse ==== | ||
+ | |||
+ | La première étape consiste à charger les variables d'environnements pour ensuite utiliser la commande "magique", ''p4a''<code> | ||
+ | # Si vous utilisez ksh ou assimiles | ||
+ | source /opt/par4all/etc/par4all-rc.sh | ||
+ | # Si vous utilisez csh ou assimiles | ||
+ | source /opt/par4all/etc/par4all-rc.csh | ||
+ | </code> | ||
Utilisation directe | Utilisation directe | ||
Ligne 156: | Ligne 165: | ||
</code> | </code> | ||
- | Utilisation avec compilation séparée | + | L'exécution précédente de matrix par la commande ''/usr/bin/time ./matrix-simple'' donne alors : |
<code> | <code> | ||
- | p4a --simple -vv matrix.c | + | La trace de la matrice est 18428734073246580736.00 |
- | gcc -O3 -mtune=native -o matrix-simple matrix.p4a.c | + | 40.73user 0.03system 0:40.85elapsed 99%CPU (0avgtext+0avgdata 98796maxresident)k |
+ | 0inputs+0outputs (0major+24740minor)pagefaults 0swaps | ||
</code> | </code> | ||
+ | |||
==== Pour utiliser P4A en mode OpenMP ==== | ==== Pour utiliser P4A en mode OpenMP ==== | ||
Ligne 166: | Ligne 177: | ||
Utilisation directe | Utilisation directe | ||
<code> | <code> | ||
- | p4a --openmp -vv matrix.c --fine -o matrix-openmp | + | p4a --openmp -vv matrix.c --fine -o matrix-OpenMP |
</code> | </code> | ||
- | Utilisation avec compilation séparée | + | Utilisation en 2 étapes |
<code> | <code> | ||
p4a --openmp -vv matrix.c | p4a --openmp -vv matrix.c | ||
- | gcc -fopenmp -O3 -mtune=native -o matrix-openmp matrix.p4a.c | + | gcc -fopenmp -O3 -mtune=native -o matrix-OpenMP matrix.p4a.c |
</code> | </code> | ||
+ | |||
+ | L'exécution précédente de matrix par la commande ''/usr/bin/time ./matrix-OpenMP'' donne alors : | ||
+ | <code> | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 182.20user 0.12system 0:23.39elapsed 779%CPU (0avgtext+0avgdata 99068maxresident)k | ||
+ | 0inputs+0outputs (0major+24825minor)pagefaults 0swaps | ||
+ | </code> | ||
+ | |||
+ | Par défaut, le programme OpenMP se lance sur tous les coeurs disponibles (virtuels ou pas !). Pour limiter sur un certain nombre de coeurs ''N'', utilisons ''export OMP_NUM_THREADS=N'' : | ||
+ | |||
+ | <code> | ||
+ | N=1 | ||
+ | while [ $N -ge 1 ] | ||
+ | do | ||
+ | echo "Lancement sur $N thread(s)" | ||
+ | export OMP_NUM_THREADS=$N | ||
+ | /usr/bin/time ./matrix-OpenMP | ||
+ | N=$(($N-1)) | ||
+ | echo | ||
+ | done | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | Lancement sur 8 threads | ||
+ | |||
+ | 187.95user 0.08system 0:24.13elapsed 779%CPU (0avgtext+0avgdata 99088maxresident)k | ||
+ | |||
+ | Lancement sur 7 threads | ||
+ | |||
+ | 170.10user 0.04system 0:26.00elapsed 654%CPU (0avgtext+0avgdata 99076maxresident)k | ||
+ | |||
+ | Lancement sur 6 threads | ||
+ | |||
+ | 151.38user 0.07system 0:27.95elapsed 541%CPU (0avgtext+0avgdata 99072maxresident)k | ||
+ | |||
+ | Lancement sur 5 threads | ||
+ | |||
+ | 125.15user 0.06system 0:29.87elapsed 419%CPU (0avgtext+0avgdata 99064maxresident)k | ||
+ | |||
+ | Lancement sur 4 threads | ||
+ | |||
+ | 104.46user 0.04system 0:26.33elapsed 396%CPU (0avgtext+0avgdata 99056maxresident)k | ||
+ | |||
+ | Lancement sur 3 threads | ||
+ | |||
+ | 95.95user 0.02system 0:32.17elapsed 298%CPU (0avgtext+0avgdata 99048maxresident)k | ||
+ | |||
+ | Lancement sur 2 threads | ||
+ | |||
+ | 87.65user 0.03system 0:43.94elapsed 199%CPU (0avgtext+0avgdata 99032maxresident)k | ||
+ | |||
+ | Lancement sur 1 threads | ||
+ | |||
+ | 91.47user 0.02system 1:31.65elapsed 99%CPU (0avgtext+0avgdata 99012maxresident)k | ||
+ | </code> | ||
+ | |||
==== Pour utiliser P4A en mode Cuda ==== | ==== Pour utiliser P4A en mode Cuda ==== | ||
- | Utilisation directe | + | Utilisation directe avec la commande suivante ne fonctionne pas avec la version 1.4 de par4all et le paquet Debian rétroporté du SDK CUDA version 5.5. |
<code> | <code> | ||
- | export CUDA_DIR=/opt/cuda | + | export CUDA_DIR=/usr/lib/nvidia-cuda-toolkit/ |
p4a --cuda -vv matrix.c --fine -o matrix-cuda | p4a --cuda -vv matrix.c --fine -o matrix-cuda | ||
</code> | </code> | ||
+ | |||
+ | Nous allons explorer une autre solution : | ||
Utilisation avec compilation séparée | Utilisation avec compilation séparée | ||
<code> | <code> | ||
- | export CUDA_DIR=/opt/cuda | ||
# Appel de Par4all | # Appel de Par4all | ||
p4a --fine --cuda -vv matrix.c | p4a --fine --cuda -vv matrix.c | ||
# Compilation des sources CUDA avec le compilateur Nvidia | # Compilation des sources CUDA avec le compilateur Nvidia | ||
- | nvcc --cuda -I$CUDA_DIR/include -DP4A_ACCEL_CUDA -I/opt/par4all-1.3/share/p4a_accel -o matrix.p4a.cpp matrix.p4a.cu | + | nvcc --cuda -I/usr/include -DP4A_ACCEL_CUDA -I/opt/par4all/share/p4a_accel -o matrix.p4a.cpp matrix.p4a.cu |
- | nvcc --cuda -I$CUDA_DIR/include -DP4A_ACCEL_CUDA -I/opt/par4all-1.3/share/p4a_accel -o p4a_accel.cpp /opt/par4all-1.3/share/p4a_accel/p4a_accel.cu | + | nvcc --cuda -I/usr/include -DP4A_ACCEL_CUDA -I/opt/par4all/share/p4a_accel -o p4a_accel.cpp /opt/par4all/share/p4a_accel/p4a_accel.cu |
# Compilation des deux sources | # Compilation des deux sources | ||
- | g++ -c -I$CUDA_DIR/include -DP4A_ACCEL_CUDA -I/opt/par4all-1.3/share/p4a_accel -Wall -fno-strict-aliasing -fPIC -O3 -o matrix.p4a.o matrix.p4a.cpp | + | g++ -c -I/usr/include -DP4A_ACCEL_CUDA -I/opt/par4all/share/p4a_accel -Wall -fno-strict-aliasing -fPIC -O3 -o matrix.p4a.o matrix.p4a.cpp |
- | g++ -c -I$CUDA_DIR/include -DP4A_ACCEL_CUDA -I/opt/par4all-1.3/share/p4a_accel -Wall -fno-strict-aliasing -fPIC -O3 -o p4a_accel.o p4a_accel.cpp | + | g++ -c -I/usr/include -DP4A_ACCEL_CUDA -I/opt/par4all/share/p4a_accel -Wall -fno-strict-aliasing -fPIC -O3 -o p4a_accel.o p4a_accel.cpp |
# Compilation finale de l'executable | # Compilation finale de l'executable | ||
- | g++ -L$CUDADIR/lib64 -L$CUDADIR/lib -Bdynamic -lcudart -o matrix-cuda matrix.p4a.o p4a_accel.o | + | g++ -L/usr/lib/x86_64-linux-gnu -Bdynamic -lcudart -o matrix-CUDA matrix.p4a.o p4a_accel.o |
# Effacement des fichiers intermédiaires inutiles | # Effacement des fichiers intermédiaires inutiles | ||
rm p4a_accel.o p4a_accel.cpp | rm p4a_accel.o p4a_accel.cpp | ||
</code> | </code> | ||
+ | |||
+ | En lançant la ''/usr/bin/time ./matrix-CUDA'' | ||
+ | |||
+ | <code> | ||
+ | /usr/bin/time ./matrix-CUDA | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 2.81user 1.01system 0:03.84elapsed 99%CPU (0avgtext+0avgdata 122360maxresident)k | ||
+ | 0inputs+88outputs (0major+27380minor)pagefaults 0swaps | ||
+ | </code> | ||
+ | |||
==== Pour utiliser P4A en mode OpenCL ==== | ==== Pour utiliser P4A en mode OpenCL ==== | ||
Ligne 205: | Ligne 283: | ||
Utilisation simple passe | Utilisation simple passe | ||
<code> | <code> | ||
- | p4a --opencl -vvv matrix.c -o matrix-ocl | + | p4a --opencl -vvv matrix.c -o matrix-OpenCL |
</code> | </code> | ||
- | Utilisation double passe | + | Son exécution donne ''/usr/bin/time ./matrix-OpenCL'' |
<code> | <code> | ||
+ | La trace de la matrice est 18428734073246580736.00 | ||
+ | 3.39user 3.22system 0:06.66elapsed 99%CPU (0avgtext+0avgdata 156856maxresident)k | ||
+ | 32inputs+112outputs (0major+38185minor)pagefaults 0swaps | ||
</code> | </code> | ||
- | ===== Exemple ===== | ||
- | --- //[[emmanuel.quemener@ens-lyon.fr|Emmanuel Quemener]] 2011/11/06 17:38// | + | ===== Analyse des résultats ===== |
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | --- //[[emmanuel.quemener@ens-lyon.fr|Emmanuel Quemener]] 2013/09/26 21:44// |