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 Prochaine révision Les deux révisions suivantes | ||
formation:gpu4cbp [2023/03/10 13:50] equemene [Comparaison de toutes les implémentations : victoire incontestée de OpenCL] |
formation:gpu4cbp [2023/03/13 08:54] equemene [Implémenter une fonction coûteuse, la Transformée de Fourier] |
||
---|---|---|---|
Ligne 741: | Ligne 741: | ||
- la OpenACC reste supérieure aux implémentations OpenCL/CPU et OpenCL/GPU d'un facteur 3 | - la OpenACC reste supérieure aux implémentations OpenCL/CPU et OpenCL/GPU d'un facteur 3 | ||
- | Se contenter uniquement de ce test inviterait à fuire Python/OpenCL. Cependant, nous avons vu dans sur ''MySteps_2.py'' que la charge calculatoire doit être "vraiement" significative pour que le Python/OpenCL l'emporte de manière significative. Nous reviendrons donc dans la suite sur des versions modifiées de ces programmes C intégrant la fonction de Mylq ''MySillyFunction'', appelée plusieurs fois, pour juger si "vraiment" Python/OpenCL reste compétitif face à OpenMP et OpenACC. | + | Se contenter uniquement de ce test inviterait à fuire Python/OpenCL. Cependant, nous avons vu dans sur ''MySteps_2.py'' que la charge calculatoire doit être "vraiment" significative pour que le Python/OpenCL l'emporte de manière significative. Nous reviendrons donc dans la suite sur des versions modifiées de ces programmes C intégrant la fonction de Mylq ''MySillyFunction'', appelée plusieurs fois, pour juger si Python/OpenCL reste compétitif face à OpenMP et OpenACC. |
===== Un intermède CUDA et son implémentation PyCUDA ===== | ===== Un intermède CUDA et son implémentation PyCUDA ===== | ||
Ligne 1005: | Ligne 1005: | ||
Pour obtenir de tels gains, nous avons la conjonction des 2 facteurs : l'exploitation massive de tous les //cudacores// (les ALU de la GPU) et l'utilisation de toute la bande passante mémoire de la GPU (10x supérieure généralement à la bande passante mémoire). | Pour obtenir de tels gains, nous avons la conjonction des 2 facteurs : l'exploitation massive de tous les //cudacores// (les ALU de la GPU) et l'utilisation de toute la bande passante mémoire de la GPU (10x supérieure généralement à la bande passante mémoire). | ||
+ | |||
+ | L'objectif de cette partie TP est donc de retrouver, par soi-même, les facteurs d'accélération de OpenCL pour des charges croissantes par l'application de 0, 1, 10, 100, 1000 fois la fonction de Mylq. | ||
+ | |||
+ | La difficulté viendra du temps d'exécution de la version séquentielle qui atteint son pallier de performances pour une taille croissante de vecteurs assez rapidement et du choix judicieux de l'inhibition de l'exécution séquentielle pour permettre d'atteindre des tailles de vecteurs significatives. | ||
+ | |||
+ | <note warning>**Exercice #4.1 : exécution des différentes implémentations** | ||
+ | - Compilez ''MySteps_6.c'' en ''MySteps_6'' | ||
+ | - Compilez ''MySteps_6_openmp.c'' en ''MySteps_6_openmp'' | ||
+ | - Compilez ''MySteps_6_openacc.c'' en ''MySteps_6_openacc'' | ||
+ | - Compilez ''MySteps_6_openmp.c'' en ''MySteps_6_openmp_NoSerial'', sans exécution séquentielle | ||
+ | - Compilez ''MySteps_6_openacc.c'' en ''MySteps_6_openacc_NoSerial'', sans exécution séquentielle | ||
+ | - Exécutez ''MySteps_6'' sur des tailles de 32768 et 65536, pour les différentes charges ci-dessus | ||
+ | - Relevez les **NativeRate** pour les différentes charges : que constatez vous ? | ||
+ | - Exécutez ''MySteps_6_openmp'' sur des tailles de 32768 et 65536, pour les mêmes charges | ||
+ | - Relevez les **NativeRate**, **OMPRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6_openacc'' sur des tailles de 32768 et 65536, pour les mêmes charges | ||
+ | - Relevez les **NativeRate**, **ACCRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL/CPU avec l'Intel sur des tailles de 32768 et 65536 | ||
+ | - Relevez les **NativeRate**, **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL/GPU sur le plus gros GPU sur des tailles de 32768 et 65536 | ||
+ | - Relevez les **NativeRate**, **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en CUDA/GPU sur le plus gros GPU sur des tailles de 32768 et 65536 | ||
+ | - Relevez les **NativeRate**, **CUDARate** pour les différentes charges | ||
+ | - Placez dans un tableau les différentes valeurs : que constatez-vous ? | ||
+ | - Exécutez ''MySteps_6_openmp_NoSerial'' sur des tailles de 1048576 et 2097152, pour les mêmes charges | ||
+ | - Relevez **OMPRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6_openacc_NoSerial'' sur des tailles de 1048576 et 2097152, pour les mêmes charges | ||
+ | - Relevez **ACCRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL Intel sur des tailles de 1048576 et 2097152, avec l'option ''-n'' | ||
+ | - Relevez **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL sur le même GPU sur des tailles de 1048576 et 2097152 | ||
+ | - Relevez **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en CUDA/GPU sur le même GPU sur des tailles de 1048576 et 2097152 | ||
+ | - Relevez **CUDARate** pour les différentes charges | ||
+ | - Placez dans un tableau les différentes valeurs : que constatez-vous comme gain en performance en OpenCL ? | ||
+ | </note> | ||
+ | |||
+ | Vous pouvez juger, du fait de lancement pour des tailles doublées, et pour les différentes charges, que vous avez obtenu des optimums pour certaines implémentations, mais pas encore pour d'autres, notamment OpenCL et CUDA. | ||
+ | |||
+ | Si la performance pour une taille de 2097152 est moins de 5% supérieure à la performance pour une taille de 1048576, vous pouvez considérer que vous avez atteint le quasi-optimum de performance. L'objectif est d'atteindre cette limite. | ||
+ | |||
+ | <note warning>**Exercice #4.2 : exploration de la meilleure performance OpenCL et CUDA** | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL Intel sur des tailles croissantes avec l'option ''-n'' | ||
+ | - Relevez **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en OpenCL sur le même GPU sur des tailles de 1048576 et 2097152 | ||
+ | - Relevez **OpenCLRate** pour les différentes charges | ||
+ | - Exécutez ''MySteps_6.py'' en CUDA/GPU sur le même GPU sur des tailles de 1048576 et 2097152 | ||
+ | - Relevez **CUDARate** pour les différentes charges | ||
+ | - Placez dans un tableau les différentes valeurs : que constatez-vous comme gain en performance en OpenCL ? | ||
+ | </note> | ||
Ligne 1041: | Ligne 1091: | ||
Il sera alors possible d'estimer l'erreur numérique à ce calcul. | Il sera alors possible d'estimer l'erreur numérique à ce calcul. | ||
- | <note warning>**Exercice #4.1 : implémentation Python "naïve"** | + | <note warning>**Exercice #5.1 : implémentation Python "naïve"** |
- Modifiez ''MyDFT_1.py'' suivant les 7 spécifications ci-dessus | - Modifiez ''MyDFT_1.py'' suivant les 7 spécifications ci-dessus | ||
- Exécutez le programme pour une taille de **16** et contrôler la cohérence | - Exécutez le programme pour une taille de **16** et contrôler la cohérence | ||
Ligne 1074: | Ligne 1124: | ||
- comparer les résultats entre les deux avec ''linalg.norm'' | - comparer les résultats entre les deux avec ''linalg.norm'' | ||
- | <note warning>**Exercice #4.2 : implémentation Python Numpy** | + | <note warning>**Exercice #5.2 : implémentation Python Numpy** |
- Copiez le programme ''MyDFT_1.py'' en ''MyDFT_2.py'' | - Copiez le programme ''MyDFT_1.py'' en ''MyDFT_2.py'' | ||
- Modifiez ''MyDFT_2.py'' suivant les 7 spécifications ci-dessus | - Modifiez ''MyDFT_2.py'' suivant les 7 spécifications ci-dessus | ||
Ligne 1101: | Ligne 1151: | ||
- changer le domaine d'itération pour la boucle : ''range()'' par ''numba.prange()'' | - changer le domaine d'itération pour la boucle : ''range()'' par ''numba.prange()'' | ||
- | <note warning>**Exercice #4.3 : implémentation Python Numpy** | + | <note warning>**Exercice #5.3 : implémentation Python Numpy** |
- Copiez le programme ''MyDFT_2.py'' en ''MyDFT_3.py'' et exploitez ce dernier | - Copiez le programme ''MyDFT_2.py'' en ''MyDFT_3.py'' et exploitez ce dernier | ||
- Copiez la fonction ''NumpyDFT'' en ''NumbaDFT'' | - Copiez la fonction ''NumpyDFT'' en ''NumbaDFT'' | ||
Ligne 1131: | Ligne 1181: | ||
Pour l'implémentation OpenCL, la version "naïve" de l'implémentation va servir. Pour cela, il suffit de reprendre la définition de la méthode naïve et de l'implémenter en C dans un noyau OpenCL. A noter que Pi n'étant dans une variable définie, il faut explicitement la détailler dans le noyau OpenCL. Autre détail important : le //cast//. De manière a éviter tout effet de bord, il est fortement recommandé de //caster// les opérations dans la précision flottante souhaitée pour des opérations sur des indices entiers. | Pour l'implémentation OpenCL, la version "naïve" de l'implémentation va servir. Pour cela, il suffit de reprendre la définition de la méthode naïve et de l'implémenter en C dans un noyau OpenCL. A noter que Pi n'étant dans une variable définie, il faut explicitement la détailler dans le noyau OpenCL. Autre détail important : le //cast//. De manière a éviter tout effet de bord, il est fortement recommandé de //caster// les opérations dans la précision flottante souhaitée pour des opérations sur des indices entiers. | ||
- | <note warning>**Exercice #4.4 : implémentation Python OpenCL** | + | <note warning>**Exercice #5.4 : implémentation Python OpenCL** |
- Copiez le programme ''MyDFT_3.py'' en ''MyDFT_4.py'' et exploitez ce dernier | - Copiez le programme ''MyDFT_3.py'' en ''MyDFT_4.py'' et exploitez ce dernier | ||
- Copiez la fonction python ''OpenCLAddition'' en ''OpenCLDFT'' | - Copiez la fonction python ''OpenCLAddition'' en ''OpenCLDFT'' | ||
Ligne 1206: | Ligne 1256: | ||
* modifier les vecteurs en sortie (2 vecteurs) | * modifier les vecteurs en sortie (2 vecteurs) | ||
- | <note warning>**Exercice #4.5 : implémentation Python CUDA** | + | <note warning>**Exercice #5.5 : implémentation Python CUDA** |
- Copiez le programme ''MyDFT_4.py'' en ''MyDFT_5.py'' et exploitez ce dernier | - Copiez le programme ''MyDFT_4.py'' en ''MyDFT_5.py'' et exploitez ce dernier | ||
- Copiez la fonction python ''CUDAAddition'' en ''CUDADFT'' | - Copiez la fonction python ''CUDAAddition'' en ''CUDADFT'' |