Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

developpement:activites:integration:par4all4wheezy [2013/09/26 21:39]
equemene [Pour utiliser P4A en mode OpenCL]
developpement:activites:integration:par4all4wheezy [2015/01/07 10:04]
Ligne 1: Ligne 1:
-====== 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>​ 
- 
-===== Contexte ===== 
- 
-Comment facilement paralléliser les codes que nous avons à disposition pour exploiter les derniers développements matériels à notre disposition (multi-coeurs,​ GPU) ? 
- 
-Par4All exploite un outil déjà vieux (et éprouvé) analysant le code et le transformant pour permettre d'​effectuer pour nous ce travail de portage : PIPS.  
- 
-Ses avantages sont nombreux : 
-  * il est Open Source 
-  * il est simple à installer 
-  * il est simple à utiliser 
-  * il est français (voire breton) ​ 
- 
-===== 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. 
- 
-Récupération et expansion de l'​archive : 
-<​code>​ 
-cd /tmp 
-wget http://​download.par4all.org/​development/​ubuntu/​x86_64/​2012/​11/​2012-11-29/​par4all-1.4.3-e2355ae_src.tar.gz 
-tar xzf /​tmp/​par4all-1.4.3-e2355ae_src.tar.gz 
-cd /​tmp/​par4all-1.4.3_src/​ 
-</​code>​ 
- 
-Compilation & Installation dans ''/​opt''​ 
-<​code>​ 
-src/​simple_tools/​p4a_setup.py --prefix=/​opt/​par4all-1.4.3 -v --jobs=4 
-</​code>​ 
- 
-Paramétrage du lien : 
-<​code>​ 
-cd /opt 
-[ -d /​opt/​par4all ] && mv /​opt/​par4all /​opt/​par4all-$(date '​+%Y%m%d'​) 
-cd /opt 
-ln -sf par4all-1.4.3 par4all 
-</​code>​ 
- 
-===== Utilisation ===== 
- 
- 
-<note important>​ 
-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>​ 
- 
-==== Le code source ==== 
- 
-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 : 
-<​code>​ 
-#include <​stdio.h>​ 
- 
-#define SIZE 2048 
-#define FTYPE double 
- 
-int main(void) 
-{ 
-    FTYPE a[SIZE][SIZE];​ 
-    FTYPE b[SIZE][SIZE];​ 
-    FTYPE c[SIZE][SIZE];​ 
-    FTYPE trace=0.; 
- 
-    for (unsigned int i = 0; i < SIZE; ++i) { 
-        for (unsigned int j = 0; j < SIZE; ++j) { 
-            a[i][j] = (FTYPE)(i + j); 
-            b[i][j] = (FTYPE)(i - j); 
-            c[i][j] = 0.0f; 
-        } 
-    } 
- 
-    for (unsigned int i = 0; i < SIZE; ++i) { 
-        for (unsigned int j = 0; j < SIZE; ++j) { 
-            for (unsigned int k = 0; k < SIZE; ++k) { 
-                c[i][j] += a[i][k] * b[k][j]; 
-            } 
-        } 
-    } 
- 
-    for (unsigned int i = 0; i < SIZE; ++i) { 
-      trace+=c[i][i];​ 
-    } 
-    ​ 
-    printf("​La trace de la matrice est %.2f\n",​trace);​ 
- 
-  return 0; 
-} 
-</​code>​ 
- 
-==== Compilation standard & Exécution ==== 
- 
-Si nous appelons ce code ''​matrix.c'',​ pour le compiler simplement avec GCC, nous avons :<​code>​ 
-gcc -std=c99 -o matrix matrix.c 
-</​code>​ 
- 
-En exécutant directement **matrix** par ''/​usr/​bin/​time ./​matrix'',​ nous obtenons un superbe ''​Segmentation fault''​. ​ 
-<​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>​ 
- 
-Pour y remédier, nous étendons la taille de la pile (//stack// en langue de Shakespeare) à l'​infini : 
-<​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 ==== 
- 
-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 
-<​code>​ 
-p4a --simple -vv matrix.c -o matrix-simple 
-</​code>​ 
- 
-L'​exécution précédente de matrix par la commande ''/​usr/​bin/​time ./​matrix-simple''​ donne alors :  
-<​code>​ 
-La trace de la matrice est 18428734073246580736.00 
-40.73user 0.03system 0:​40.85elapsed 99%CPU (0avgtext+0avgdata 98796maxresident)k 
-0inputs+0outputs (0major+24740minor)pagefaults 0swaps 
-</​code>​ 
- 
- 
-==== Pour utiliser P4A en mode OpenMP ==== 
- 
-Utilisation directe 
-<​code>​ 
-p4a --openmp -vv matrix.c --fine -o matrix-OpenMP 
-</​code>​ 
- 
-Utilisation en 2 étapes 
-<​code>​ 
-p4a --openmp -vv matrix.c 
-gcc -fopenmp -O3 -mtune=native -o matrix-OpenMP matrix.p4a.c 
-</​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 ==== 
- 
-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>​ 
-export CUDA_DIR=/​usr/​lib/​nvidia-cuda-toolkit/​ 
-p4a --cuda -vv matrix.c --fine -o matrix-cuda 
-</​code>​ 
- 
-Nous allons explorer une autre solution : 
- 
-Utilisation avec compilation séparée 
-<​code>​ 
-# Appel de Par4all 
-p4a --fine --cuda -vv matrix.c 
-# Compilation des sources CUDA avec le compilateur Nvidia 
-nvcc --cuda -I/​usr/​include -DP4A_ACCEL_CUDA -I/​opt/​par4all/​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 p4a_accel.cpp /​opt/​par4all/​share/​p4a_accel/​p4a_accel.cu 
-# Compilation des deux sources 
-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/​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 
-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 
-rm p4a_accel.o p4a_accel.cpp 
-</​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>​ 
- 
-Ainsi, sur  
-==== Pour utiliser P4A en mode OpenCL ==== 
- 
- 
-Utilisation simple passe 
-<​code>​ 
-p4a --opencl -vvv matrix.c -o matrix-OpenCL 
-</​code>​ 
- 
-Son exécution donne ''/​usr/​bin/​time ./​matrix-OpenCL''​ 
-<​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>​ 
- 
- 
-===== Exemple ===== 
- 
- --- //​[[emmanuel.quemener@ens-lyon.fr|Emmanuel Quemener]] 2011/11/06 17:38// 
developpement/activites/integration/par4all4wheezy.txt · Dernière modification: 2015/01/07 10:04 (modification externe)