Différences

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

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
formation:insa2020gpu [2020/12/03 10:03]
equemene [Implémentation Python/OpenCL Python/CUDA]
formation:insa2020gpu [2020/12/07 11:05] (Version actuelle)
equemene [Déroulement de la session]
Ligne 25: Ligne 25:
   * Exploration de "codes métier"​ : [[https://​www.tensorflow.org/​|TensorFlow]],​ [[https://​www.r-ccs.riken.jp/​labs/​cbrt/​|GENESIS]] et [[http://​www.gromacs.org/​|Gromacs]]   * Exploration de "codes métier"​ : [[https://​www.tensorflow.org/​|TensorFlow]],​ [[https://​www.r-ccs.riken.jp/​labs/​cbrt/​|GENESIS]] et [[http://​www.gromacs.org/​|Gromacs]]
  
 +De manière à disposer d'une trace de votre travail et de pouvoir l'​évaluer,​ il est demandé de rédiger un compte-rendu sur la base des questions posées. N'​hésitez pas à faire des copies d'​écran et à les intégrer dans votre rapport. Le rapport devra être rendu le vendredi suivant la seconde séance de travaux pratiques.
 ===== Démarrage de la session ===== ===== Démarrage de la session =====
    
Ligne 375: Ligne 376:
   * ''​Pi''​ : implémentation multiples d'un [[https://​fr.wikipedia.org/​wiki/​M%C3%A9thode_de_Monte-Carlo|Pi Monte Carlo]]   * ''​Pi''​ : implémentation multiples d'un [[https://​fr.wikipedia.org/​wiki/​M%C3%A9thode_de_Monte-Carlo|Pi Monte Carlo]]
   * ''​Splutter''​ : un modèle de ''​postillonneur mémoire'',​ très utile pour évaluer les //fonctions atomiques//   * ''​Splutter''​ : un modèle de ''​postillonneur mémoire'',​ très utile pour évaluer les //fonctions atomiques//
 +  * ''​TrouNoir''​ : un exemple de portage de code de 1994, porté en C en 1997 puis en Python/​OpenCL et Python/CUDA en 2019
  
 De tous ces programmes, seuls ceux présents dans ''​BLAS'',​ ''​NBody''​ et ''​Pi''​ seront exploités dans le cadre de ces travaux pratiques. De tous ces programmes, seuls ceux présents dans ''​BLAS'',​ ''​NBody''​ et ''​Pi''​ seront exploités dans le cadre de ces travaux pratiques.
Ligne 402: Ligne 404:
  
 Nous avons alors 12 exécutables de la forme ''​xGEMM_SP_<​version>''​ ou ''​xGEMM_DP_<​version>''​ :  ​ Nous avons alors 12 exécutables de la forme ''​xGEMM_SP_<​version>''​ ou ''​xGEMM_DP_<​version>''​ :  ​
-  * ''​fblas''​ utilisant la librairie ATLAS, pour CPU 
   * ''​openblas''​ utilisant la librairie OpenBLAS, pour CPU   * ''​openblas''​ utilisant la librairie OpenBLAS, pour CPU
   * ''​gsl''​ utilisant la librairie GSL (pour //GNU Scientific Librairies//​)   * ''​gsl''​ utilisant la librairie GSL (pour //GNU Scientific Librairies//​)
 +  * ''​fblas''​ utilisant la librairie OpenBLAS mais pour des appels fortran, pour CPU
   * ''​cublas''​ utilisant la librairie cuBLAS avec une gestion externe de la mémoire   * ''​cublas''​ utilisant la librairie cuBLAS avec une gestion externe de la mémoire
   * ''​thunking''​ utilisant la librairie cuBLAS avec une gestion interne de la mémoire   * ''​thunking''​ utilisant la librairie cuBLAS avec une gestion interne de la mémoire
Ligne 1077: Ligne 1079:
  
 La seule manière de retrouver une performance comparable en CUDA est de solliciter le second étage de parallélisme des GPU, les //​Threads//​. Avec la commande suivante, avec 1024 Threads, nous plafonnons à **198 Gitops** :<​code>​python3 PiXPU.py -g CUDA -d 0 -b $((3584*4)) -e $((3584*4)) -f 1024 -l 1024 -r 3 -i 1000000000000</​code>​ La seule manière de retrouver une performance comparable en CUDA est de solliciter le second étage de parallélisme des GPU, les //​Threads//​. Avec la commande suivante, avec 1024 Threads, nous plafonnons à **198 Gitops** :<​code>​python3 PiXPU.py -g CUDA -d 0 -b $((3584*4)) -e $((3584*4)) -f 1024 -l 1024 -r 3 -i 1000000000000</​code>​
- 
-Et ce n'est pas tout ! La distribution Debian utilisée intègre par défaut un CUDA version 8. Pour l'​intégration d'​applications de //Deep Learning//, nous avons été obligé d'​intégrer un CUDA version 9. Nous pouvons charger l'​environnement pour exploiter cette version avec la commande :<​code>​module load cuda/​9.0</​code>​ 
  
 En relançant le calcul précédent,​ nous parvenons à **271 Gitops** soit plus que l'​implémentation OpenCL. En relançant le calcul précédent,​ nous parvenons à **271 Gitops** soit plus que l'​implémentation OpenCL.
Ligne 1111: Ligne 1111:
 Le code de test **Pi Monte Carlo** avait pour avantage de ne solliciter que très peu la mémoire. La seule mémoire sollicitée sur les périphériques se résumait au nombre de tirages dans le quadrant de cercle. De plus, l'​opération de parallélisation divisait un nombre total d'​itérations en un nombre équivalent pour chaque //work item//, chaque //block// ou chaque //thread//. Chaque calcul était indépendant des autres : nous avions non seulement un **code ALU** (ne sollicitant que les unités de traitement) mais aussi un **code gros grain** (indépendance des calculs). Le code de test **Pi Monte Carlo** avait pour avantage de ne solliciter que très peu la mémoire. La seule mémoire sollicitée sur les périphériques se résumait au nombre de tirages dans le quadrant de cercle. De plus, l'​opération de parallélisation divisait un nombre total d'​itérations en un nombre équivalent pour chaque //work item//, chaque //block// ou chaque //thread//. Chaque calcul était indépendant des autres : nous avions non seulement un **code ALU** (ne sollicitant que les unités de traitement) mais aussi un **code gros grain** (indépendance des calculs).
  
-Dans le code ''​NBody.py'',​ le principe est de déterminer dans un modèle newtonien la position et la vitesse de chaque particule en intéraction avec toutes les autres. A chaque itération, chaque position et chaque vitesse de chaque particule vont être modifiées par la proximité de toutes les autres : nous disposons d'un **code grain fin**. De plus, la détermination de la vitesse et la position de chaque particule à chaque instant nécessite un accès à la position de chacune des autres : un accès permanent à la mémoire est donc indispensable.+Dans le code ''​NBody.py'',​ situé dans ''​bench4gpu/​NBody'',​ le principe est de déterminer dans un modèle newtonien la position et la vitesse de chaque particule en intéraction avec toutes les autres. A chaque itération, chaque position et chaque vitesse de chaque particule vont être modifiées par la proximité de toutes les autres : nous disposons d'un **code grain fin**. De plus, la détermination de la vitesse et la position de chaque particule à chaque instant nécessite un accès à la position de chacune des autres : un accès permanent à la mémoire est donc indispensable.
  
 Le programme ''​NBody.py''​ n'est disponible qu'en OpenCL. Son invocation avec l'​option ''​-h''​ offre la sortie suivante : Le programme ''​NBody.py''​ n'est disponible qu'en OpenCL. Son invocation avec l'​option ''​-h''​ offre la sortie suivante :
-<​code>​ +<​code>​$ cd $HOME/​bench4gpu/​NBody 
-python3 NBody.py -h+python3 NBody.py -h
 NBody.py -h [Help] -r [InitialRandom] -g [OpenGL] -e [VirielStress] -o [Verbose] -p [Potential] -x <​None|NegExp|CorRad>​ -d <​DeviceId>​ -n <​NumberOfParticules>​ -i <​Iterations>​ -z <​SizeOfBoxOrBall>​ -v <​Velocity>​ -s <​Step>​ -b <​Ball|Box>​ -m <​ImplicitEuler|RungeKutta|ExplicitEuler|Heun>​ -t <​FP32|FP64>​ NBody.py -h [Help] -r [InitialRandom] -g [OpenGL] -e [VirielStress] -o [Verbose] -p [Potential] -x <​None|NegExp|CorRad>​ -d <​DeviceId>​ -n <​NumberOfParticules>​ -i <​Iterations>​ -z <​SizeOfBoxOrBall>​ -v <​Velocity>​ -s <​Step>​ -b <​Ball|Box>​ -m <​ImplicitEuler|RungeKutta|ExplicitEuler|Heun>​ -t <​FP32|FP64>​
  
Ligne 1203: Ligne 1203:
 </​code>​ </​code>​
  
-Les éléments de sortie sont les statistiques de chaque itération, exprimées en **squertz**,​ contraction de **square** avec **Hertz**. En effet, le nombre de calculs élémentaires évolue suivant une loi en **N(N-1)** (chaque particule parmi **N** intéragit avec les **N-1** autres particules).+Les éléments de sortie sont les statistiques de chaque itération, exprimées en **squertz**,​ contraction de **square** ​(pour "​carré"​) ​avec **Hertz**. En effet, le nombre de calculs élémentaires évolue suivant une loi en **N(N-1)** (chaque particule parmi **N** intéragit avec les **N-1** autres particules).
  
 === Analyse du programme === === Analyse du programme ===
Ligne 1449: Ligne 1449:
   * Comparez les résultats   * Comparez les résultats
     * Qu'​apporte le GPU comme gain de performance par rapport au processeur ?     * Qu'​apporte le GPU comme gain de performance par rapport au processeur ?
 +</​note>​
 +
 +==== Intégration et exploitation du code GENESIS ====
 +
 +Le code [[https://​www.r-ccs.riken.jp/​labs/​cbrt/​|GENESIS]] de l'​institut [[https://​www.r-ccs.riken.jp/​en/​|RIKEN Center for Computational Science]] est un logiciel de [[https://​fr.wikipedia.org/​wiki/​Dynamique_mol%C3%A9culaire|dynamique moléculaire]]. ​
 +Présenté comme exploitant massivement les GPU, il est disponible sur [[https://​bitbucket.org/​dpotter/​pkdgrav3/​|bitbucket]].
 +C'est un programme //hybride// (exploitant 2 stratégies de parallélisation),​ et même //​trhybride//​ dans la mesure où il exploite les GPU de type Nvidia avec CUDA, la distribution sur les coeurs via [[https://​fr.wikipedia.org/​wiki/​OpenMP|OpenMP]] et la distribution sur des noeuds différents via [[https://​fr.wikipedia.org/​wiki/​Message_Passing_Interface|passage de messages MPI]].
 +Le code source est accessible à l'​adresse : https://​www.r-ccs.riken.jp/​labs/​cbrt/​download/​genesis-version-1-5/ ​
 +
 +<note warning>​Exercice #27 : Récupérez et compilez le code suivant la documentation fournie
 +  * Lisez la [[https://​www.r-ccs.riken.jp/​labs/​cbrt/​installation/​|documentation]] d'​installation
 +  * Placez les sources dans le dossier ''/​local/​$USER/​GENESIS''​ créé pour l'​occasion
 +  * Préparez une compilation pour GPU en simple précision dans le dossier ''/​local/​$USER/​GENESIS/​gpu-single''​
 +  * Compilez et installez le programme
 +  * Purgez la compilation précédente
 +  * Préparez une compilation pour CPU en simple précision dans le dossier ''/​local/​$USER/​GENESIS/​cpu-single''​
 +  * Compilez et installez le programme
 +</​note>​
 +
 +L'​exécution du programme est évaluée en comparant son exécution dans différentes configurations d'​exploitation des CPU et des GPU. 
 +Pour cela, l'​exemple de la base de [[https://​www.r-ccs.riken.jp/​labs/​cbrt/?​smd_process_download=1&​download_id=14619|tests de régression]]. Le test  ''​test_rpath_spdyn/​alad_water''​ a été modifié pour durer un peu plus longtemps à l'​exécution.
 +
 +De plus, **GENESIS** étant //​trhybride//,​ il est programmé pour se distribuer sur des machines indépendantes qui communiquent par //échanges de messages//. Le test  [[http://​www.cbp.ens-lyon.fr/​emmanuel.quemener/​documents/​alad_water.tgz|''​alad_water''​]] exige, par construction de la simulation, quatre exécutions concurrentes lesquelles vont communiquer par MPI. Il faudra donc préfixer l'​exécutable de ''​mpirun -np 4''​ pour exécuter ces quatre tâches.
 +
 +De plus, ce programme est aussi parallélisé avec OpenMP : il va donc "​aussi"​ exploiter les coeurs disponibles. Le souci, c'est que, par défaut, il va lancer pour chaque tâche MPI autant de sous-tâches OpenMP que de coeurs (même "​virtuels"​) disponibles sur la machine. Ainsi, en exécutant l'​exemple ''​alad_water''​ sur une machine disposant de 8 coeurs Hyperthreadés (donc disposant au total de 16 coeurs logiques), il va lancer 4*16 soit 64 tâches pour seulement 8 "​vrais"​ coeurs : de quoi surcharger la machine.
 +
 +Pour finir, dans comme ce programme est "​aussi"​ //​gépufié//​ (porté sur GPU), il risque d'y avoir un goulet d'​étranglement pour l'​accès au GPU pour les 64 tâches simultanées. Ainsi, les programmes "​fortement"​ parallélisés exigent de choisir judicieusement les différents paramètres de parallélisation tout comme nous avons vue que, pour les GPU, il fallait découper la tâche en un nombre optimal de sous-tâches.
 +
 +<note warning>​Exercice #28 : Exécutez l'​exemple ''​alad_water''​
 +  * Récupérez [[http://​www.cbp.ens-lyon.fr/​emmanuel.quemener/​documents/​alad_water.tgz|l'​exemple d'​exécution]]
 +  * Décompressez l'​archive dans ''/​local/​$USER/​GENESIS''​
 +  * Exécutez le programme sur l'​exemple avec la version CPU 
 +    * ''/​usr/​bin/​time mpirun -np 4 /​local/​$USER/​GENESIS/​cpu-single/​bin/​spdyn inp''​
 +  * Observez pendant l'​exécution l'​activité des coeurs
 +  * Notez le ''​Elapsed Time''​ et le ''​System Time''​
 +  * Effacez les résultats ''​test*''​ avec ''​rm test*'' ​
 +  * Exécutez le programme sur l'​exemple avec la version GPU 
 +    * Exécutez la commande ''/​usr/​bin/​time mpirun -np 4 /​local/​$USER/​GENESIS/​gpu-single/​bin/​spdyn inp''​
 +  * Observez pendant l'​exécution l'​activité des coeurs et des GPU
 +  * Notez le ''​Elapsed Time''​ et le ''​System Time''​
 +  * Effacez les résultats ''​test*''​ avec ''​rm test*'' ​
 +  * Déterminez,​ sachant que 4 tâches MPI simultanément,​ combien de //threads// lancer
 +  * Définissez ce nombre pour le système avec la fonction suivante :
 +    * ''​export OPTIMAL_THREADS=<​MonCHoixJudicieux>''​
 +  * Exécutez la commande ''/​usr/​bin/​time mpirun -np 4 -x OMP_NUM_THREADS=$OPTIMAL_THREADS /​local/​$USER/​GENESIS/​cpu-single/​bin/​spdyn inp''​
 +  * Notez le ''​Elapsed Time''​ et le ''​System Time''​
 +  * Effacez les résultats ''​test*''​ avec ''​rm test*'' ​
 +  * Exécutez la commande ''/​usr/​bin/​time mpirun -np 4 -x OMP_NUM_THREADS=$OPTIMAL_THREADS /​local/​$USER/​GENESIS/​gpu-single/​bin/​spdyn inp''​
 +  * Notez le ''​Elapsed Time''​ et le ''​System Time''​
 +  * Concluez sur la pertinence de l'​utilisation de l'​option ''​-x OMP_NUM_THREADS=$OPTIMAL_THREADS''​
 </​note>​ </​note>​
  
Ligne 1455: Ligne 1505:
 Nous allons tenter de reproduire une [[https://​www.nvidia.com/​en-us/​data-center/​gpu-accelerated-applications/​gromacs/​|expérience de Nvidia]] vantant l'​efficacité des GPGPU pour le logiciel de [[https://​fr.wikipedia.org/​wiki/​Dynamique_mol%C3%A9culaire|dynamique moléculaire]] [[http://​www.gromacs.org/​|Gromacs]]. Nous allons tenter de reproduire une [[https://​www.nvidia.com/​en-us/​data-center/​gpu-accelerated-applications/​gromacs/​|expérience de Nvidia]] vantant l'​efficacité des GPGPU pour le logiciel de [[https://​fr.wikipedia.org/​wiki/​Dynamique_mol%C3%A9culaire|dynamique moléculaire]] [[http://​www.gromacs.org/​|Gromacs]].
  
-<note warning>​Exercice #27 : appliquez la "​recette"​ de Nvidia+<note warning>​Exercice #29 : appliquez la "​recette"​ de Nvidia
   * La documentation offre ceci :   * La documentation offre ceci :
     - récupérez le source     - récupérez le source
Ligne 1468: Ligne 1518:
 </​note>​ </​note>​
  
-En cas de difficultés,​ appliquez la [[formation:​insa2018gpu:insa2018gromacs4stretch|recette de Gromacs pour Debian ​Stretch]] ;-)+En cas de difficultés,​ appliquez la [[formation:​insa2020gpu:insa2020gromacs4buster|recette de Gromacs pour Debian ​Buster]] ;-)
  
-<note warning>​Exercice #28 : Exécutez l'​exemple ''​1536'' ​+<note warning>​Exercice #30 : Exécutez l'​exemple ''​1536'' ​
   * Quel ''​Elapsed Time''​ avez-vous pour l'​exécution sur GPU (et CPU) ?   * Quel ''​Elapsed Time''​ avez-vous pour l'​exécution sur GPU (et CPU) ?
   * Quel ''​Elapsed Time''​ avez-vous pour l'​exécution uniquement sur CPU ?   * Quel ''​Elapsed Time''​ avez-vous pour l'​exécution uniquement sur CPU ?
Ligne 1476: Ligne 1526:
 </​note>​ </​note>​
  
-==== Intégration et exploitation du code PKDGRAV3 ==== 
- 
-Le code PKDGRAV3 est un logiciel de simulation hydrodynamique à la large couverture médiatique en juin 2017. Présenté comme exploitant massivement les GPU, il est disponible sur [[https://​bitbucket.org/​dpotter/​pkdgrav3/​|bitbucket]]. 
- 
-Le code source est accessible par ''​git''​ à l'​adresse : https://​bitbucket.org/​dpotter/​pkdgrav3.git 
- 
-<note warning>​Exercice #29 : Récupérez et compilez le code suivant la documentation fournie 
-  * La documentation offre ceci : 
-    - récupérez le source 
-    - étendez l'​archive 
-    - créez un dossier pour la construction 
-    - passez dans ce dossier 
-    - préparez la compilation 
-    - compilez le code 
-  * A quelle étape est-ce que cela bloque ? Quel message avez-vous ? 
-  * Nouvelle compilation : 
-    - nettoyez le dossier de construction 
-    - préparez la compilation en précisant un autre compilateur 
-    - compilez le code 
-</​note>​ 
- 
-L'​exécution du programme s'​effectue en associant l'​exécutable ''​pkdgrav3''​ au fichier de paramètres ''​cosmology.par''​ dans le dossiers ''​examples''​. 
- 
-<note warning>​Exercice #30 : Exécutez l'​exemple ''​cosmology.par'' ​ 
-  * Passez dans le dossier ''​examples''​ 
-  * Exécutez ''​pkdgrav3''​ sur ''​cosmology.par''​ 
-  * L'​exécution se déroule-t-elle correctement ? 
-</​note>​ 
- 
-En cas de difficultés,​ appliquez la [[formation:​cbp20190606gpu:​pkdgrav4stretch|recette d'un PKDGRAV3 pour Debian Stretch]] ;-) 
  
 ===== Conclusion ===== ===== Conclusion =====
Ligne 1513: Ligne 1533:
 L'​exploitation de "codes métier"​ vous aura aussi permis d'​entrevoir la difficulté d'​intégrer et d'​exécuter des programmes dans des environnements pourtant bien homogènes : toutes les stations exploitées ont exactement le même système d'​exploitation,​ [[developpement:​productions:​SIDUS|SIDUS]]. Les "​astuces"​ permettant de simplement pouvoir exécuter les programmes illustraient aussi que, sans expérience,​ difficile de s'en sortir. L'​exploitation de "codes métier"​ vous aura aussi permis d'​entrevoir la difficulté d'​intégrer et d'​exécuter des programmes dans des environnements pourtant bien homogènes : toutes les stations exploitées ont exactement le même système d'​exploitation,​ [[developpement:​productions:​SIDUS|SIDUS]]. Les "​astuces"​ permettant de simplement pouvoir exécuter les programmes illustraient aussi que, sans expérience,​ difficile de s'en sortir.
  
- --- //​[[emmanuel.quemener@ens-lyon.fr|Emmanuel Quemener]] 2020/01/01 19:44//+ --- //​[[emmanuel.quemener@ens-lyon.fr|Emmanuel Quemener]] 2020/12/05 23:24//
formation/insa2020gpu.1606986239.txt.gz · Dernière modification: 2020/12/03 10:03 par equemene