Compilation efficace d’applications de traitement d’images pour processeurs manycore CEA LIST, Saclay Pierre Guillou mardi 6 décembre 2016 MINES ParisTech, PSL Research University Évolution des capacités de calcul 1987 2000 2016 2/52 De nouvelles architectures Limitations des processeurs monocœurs • fréquence d’horloge bloquée depuis 2005 • consommation d’énergie systèmes embarqués • utilisation efficace des transistors ? Nouvelles architectures parallèles • processeurs multicœurs • GPGPUs • processeurs manycores jusqu’à 10 cœurs… SIMD, 30 — 4000 cœurs 60 — 300 cœurs The free lunch is over. Now welcome to the hardware jungle. — Herb Sutter, 2011 3/52 Les processeurs manycore : le MPPA de Kalray 256 cœurs de calcul, 10 W 2 générations : Andey (400 MHz), Bostan (600 MHz) 4/52 L’architecture du processeur MPPA Cluster d’E/S Machine hôte PCI-E 16 Go/s DDR Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster de calcul Cluster d’E/S Cluster d’E/S Mémoire locale (3 Go) Cluster de calcul 13 Go/s Cluster d’E/S 16 clusters × (16 cœurs + 2 Mo) 5/52 Le traitement d’images, un domaine innovant et dynamique 6/52 Une branche : la morphologie mathématique Propriétés géométriques • détection, extraction Algèbre d’opérateurs images • réguliers, parallèles • arithmétiques unaires & binaires • « morphologiques » érosion, dilatation, convolution • réductions min, max, somme 7/52 Application de traitement d’images sûreté licensePlate : détection de plaque d’immatriculation 8/52 Application de traitement d’images santé retina : détection des lésions de la rétine 9/52 Difficultés du développement logiciel Applications −→ matériels • fonctionnalités • matériels cibles • optimisations temps de développement travail de portage fluidité, temps de réponse, autonomie Enjeux : les 3P • programmabilité • portabilité • performance temps de développement, maintenance cibles matérielles temps d’exécution, énergie 10/52 distribuée MPI PGAS Flot de données OpenCL TPP Flot de données partagée Mémoire Classes d’architectures et modèles de programmation OpenMP OpenCL kernels Pthreads OpenCL 2.0 SVM homogène hétérogène Architecture 11/52 Plan 1 Méthodologie de recherche 2 I — Le modèle OpenMP 3 II — Le modèle flot de données 4 III — Le modèle OpenCL 5 Quel modèle choisir ? 6 Conclusions & Perspectives 12/52 Méthodologie de recherche Méthodologie de recherche Sujet • compilation efficace 1 programme −→ 3P • traitement d’images utile, parallèle • architectures manycore complexité vs. énergie Étude de cas • le processeur manycore MPPA de Kalray • le traitement d’images par morphologie mathématique • des langages de traitement d’images (DSLs → 3P) 13/52 Contributions principales Comparaisons expérimentales sur MPPA • 3 modèles de programmation parallèle • 2 générations de processeurs Preuve de la possibilité d’atteindre les 3P • développement d’un environnement logiciel intégré • regroupant plusieurs chaînes de compilation • restreint au traitement d’images 14/52 SMIL : Simple (but efficient) Morphological Image Library SMIL app.cpp SMIL app.py applications runtimes SMIL Python (wrapper Swig) SMIL lib matériels Processeurs multicœurs 15/52 Exemple de code SMIL import smilPython as smil imin = smil.Image("input.png") imout = smil.Image(imin) smil.gradient(imin, imout) imout.save("output.png") # # # # lecture sur le disque allocation de imout gradient morphologique écriture sur le disque 16/52 FREIA : FRamework for Embedded Image Applications FREIA app.c DSL & API Optimisations à la compilation applications runtimes FREIA common runtime Fulguro OpenCL SPoC Terapix matériels Processeurs multicœurs GPUs FPGAs 17/52 PIPS pour FREIA Compilateur source-à-source • entrée DSL : code C + appels FREIA • optimisations spécifiques traitement d’images : • • • • • décomposition des opérateurs complexes élimination des temporaires élimination des sous-expressions communes propagation des copies fusion d’opérateurs • sortie, génération de code : • • • • FREIA simplifié SPoC, Terapix (FPGAs) OpenCL Sigma-C 18/52 I — Le modèle OpenMP OpenMP, un modèle pour architectures à mémoire partagée Mémoire principale Cœur 0 Cœur 1 Cœur 2 Cœur 3 19/52 Addition de vecteurs en OpenMP void vecAdd(float *a, float *b, float *c, const unsigned int n) { unsigned int i; #pragma omp parallel for for (i = 0; i < n; i++) c[i] = a[i] + b[i]; } 20/52 Environnement d’exécution OpenMP : 1 cluster Cluster E/S Processeur hôte Cluster de calcul Transferts NoC Lectures Écritures PCIe Application Bibliothèque OpenMP 21/52 Portage SMIL sur 1 cluster MPPA SMIL bibliothèque C++, OpenMP CMake compilation croisée transferts avec l’hôte mémoire très limitée : 2 Mo standard portage rapide 3 environnements imagettes 22/52 Évaluation : passage à l’échelle de SMIL avec OpenMP Speedup (1 cluster) → 6 anr999 licensePlate antibio retina burner toggle deblocking GMEAN 4 2 0 1 2 4 6 8 10 12 14 16 Nombre de threads OpenMP petites images 23/52 Bibliothèque OpenMP sur MPPA SMIL −→ MPPA • portage direct et rapide compilation croisée • 1 cluster de calcul / 16 • environnements d’exécution modèle mémoire transferts de données • passage à l’échelle • limitations mémoire imagettes −→ mixer avec des communications inter-clusters −→ réduire l’empreinte mémoire 24/52 II — Le modèle flot de données Le flot de données vol < w1_0 E8 E8 imIn Le modèle et les langages D8 E8 E8 w2 • graphe producteurs/consommateurs • années 1970 • adapté aux exigences industrielles • adapté aux architectures parallèles KPN Lustre/SCADE StreamIt Sigma-C, un langage flot de données • développé pour le MPPA Andey, Bostan • CEA List 25/52 Agents Sigma-C entrée 0 sortie entrée 1 Agent interleave agent interleave() { interface { in<int> in0, in1; out<int> out0; spec{ in0[2], in1, out0[3] }; } void start() exchange(in0 i0[2], in1 i1, out0 o[3]) { o[0] = i0[0], o[1] = i1, o[2] = i0[1]; } } 26/52 Subgraphs Sigma-C Agent 2 Agent 1 Agent 4 Agent 5 Subgraph 3 Subgraph bar subgraph bar() { interface { in<int> in0[2]; out<int> out0, out1; spec { { in0[][3]; out0 }; { out1[2] } }; } map { agent a1 = new Agent1(); agent a3 = new Subgraph3(); connect(in0[0], a1.input0); connect(a5.output, out1); connect(a1.output0, a2.input); connect(a3.output, a5.input1); } } 27/52 Conversion de FREIA en Sigma-C À partir de code FREIA séquentiel freia_aipo_threshold(im1, im0, 50, 150, true); // arithmétique freia_aipo_erode_8c(im2, im1, kernel); // morphologique freia_aipo_dilate_8c(im3, im2, kernel); // morphologique Générer automatiquement des subgraphs Sigma-C 3 im 0 im subgraph foo() { int16_t kernel[9] = {0,1,0, 0,1,0, 0,1,0}; ... agent thr = new img_threshold_img(); agent ero = new img_erode(kernel); im1 im2 agent dil = new img_dilate(kernel); ero thr dil ... connect(thr.output, ero.input); connect(ero.output, dil.input); ... } 28/52 Contraintes sur les applications Sigma-C Agents • 1 agent → 1 cœur de calcul utilisation partielle • 2 Mo pour 16 cœurs mem(1 agent) ≤ 128 ko • coût d’itération fixe grouper les pixels par lignes Graphes • débit : nœud le plus lent équilibrage fusion/fission • placement : communications inter-clusters • temps d’activation constant peu de clusters gros graphes 29/52 Fusion des opérateurs arithmétiques ero +1 × dil /2 30/52 Fusion des opérateurs arithmétiques ero (_ + 1) × (_/2) dil 30/52 Optimisation : réduction des communications void freia_cipo_geodesic_reconstruct(freia_data2d *immarker, freia_data2d *immask) { int32_t volcurrent, volprevious; freia_global_vol(immarker, &volcurrent); do { volprevious = volcurrent; freia_dilate(immarker, immarker); freia_inf(immarker, immarker, immask); freia_global_vol(immarker, &volcurrent); } while (volcurrent != volprevious); } • pas de boucle dynamique en Sigma-C −→ while sur hôte • reconstruction géodésique : suite stationnaire d’itérations =⇒ déroulement partiel 31/52 Chaîne de compilation FREIA → Sigma-C FREIA app.c compilateur source-à-source code de contrôle subgraphs Sigma-C bibliothèque d’agents Sigma-C compilateur hôte compilateur Kalray binaire de contrôle sur hôte binaires de calcul sur accélérateur 32/52 Environnement d’exécution Sigma-C Agents Sigma-C hôte lecture réception écriture transfert traitement 1 transfert transfert envoi PCIe lancement calcul Clusters de calcul écriture Unix pipes envoi Clusters E/S NoC Code de contrôle traitement i réception lecture traitement n 33/52 Évaluation : Sigma-C sur multicœur et MPPA 8 6 4 2 N GM EA le to gg a in re t at e lic en se Pl ki ng r bl oc rn e de bu io an tib r9 99 0 an Speedups → Sigma-C sur i7 Sigma-C sur MPPA 34/52 Flot de données et processeurs manycore vol FREIA → Sigma-C → MPPA < w1_0 E8 E8 imIn D8 E8 E8 w2 • bibliothèque d’opérateurs • compilation source-à-source FREIA → Sigma-C • environnement d’exécution pour E/S • optimisations pour le processeur MPPA Résultats • modèle strict • compilation automatique • bonnes performances sur MPPA morceaux d’applications 3P malgré usage partiel • publication LCPC 2014 35/52 III — Le modèle OpenCL Modèles pour architectures hétérogènes OpenCL Host ... ... ... Processing Element ... ... ... ... ... ... ... ... ... Compute Unit Compute Device 36/52 Addition de vecteurs en OpenCL : noyau de calcul __kernel void vecAdd(__global float __global float __global float const unsigned *a, *b, *c, int n) { unsigned int id = get_global_id(0); if (id < n) c[id] = b[id] + a[id]; } 37/52 Addition de vecteurs en OpenCL : code hôte // Initializations clGetPlatformIDs(1, &cpPlatform, NULL); clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); ctx = clCreateContext(0, 1, &device_id, NULL, NULL, &err); q = clCreateCommandQueue(ctx, device_id, 0, &err); // Create the compute program from the source buffer prgm = clCreateProgramWithSource(ctx, 1, (const char **)&kernelSource, NULL, &err); clBuildProgram(prgm, 0, NULL, NULL, NULL, NULL); // Create the compute kernel in the program we wish to run knl = clCreateKernel(prgm, "vecAdd", &err); // Create the input and output arrays in device memory d_a = clCreateBuffer(ctx, CL_MEM_READ_ONLY, bytes, NULL, NULL); d_b = clCreateBuffer(ctx, CL_MEM_READ_ONLY, bytes, NULL, NULL); d_c = clCreateBuffer(ctx, CL_MEM_WRITE_ONLY, bytes, NULL, NULL); // Write our data set into the input array in device memory err = clEnqueueWriteBuffer(q, d_a, CL_TRUE, 0, bytes, h_a, 0, NULL, NULL); err |= clEnqueueWriteBuffer(q, d_b, CL_TRUE, 0, bytes, h_b, 0, NULL, NULL); // Set err |= err |= err |= err |= the arguments to our compute kernel clSetKernelArg(knl, 0, sizeof(cl_mem), clSetKernelArg(knl, 1, sizeof(cl_mem), clSetKernelArg(knl, 2, sizeof(cl_mem), clSetKernelArg(knl, 3, sizeof(unsigned &d_a); &d_b); &d_c); int), &n); // Execute the kernel over the entire range of the data set err = clEnqueueNDRangeKernel(q, knl, 1, NULL, &globalSize, &localSize, 0, NULL, NULL); clFinish(q); // Read the results from the device clEnqueueReadBuffer(q, d_c, CL_TRUE, 0, bytes, h_c, 0, NULL, NULL); 38/52 Chaîne de compilation FREIA → OpenCL FREIA app.c compilateur source-à-source FREIA app'.c code de contrôle kernels OpenCL générés compilateur hôte compilateur accélérateur binaire de contrôle sur hôte binaires de calcul sur accélérateur 39/52 OpenCL sur le MPPA, multicœur et GPU : temps d’exécution Bostan Quadro 600 i7 Tesla C 2050 101 100 N GM EA gl e to g a in re t at e Pl se en lic bl oc ki ng er de bu rn io tib an r9 99 10−1 an ← ns/#op/pixel 102 40/52 OpenCL sur le MPPA, multicœur et GPU : énergie Bostan Quadro 600 i7 Tesla C 2050 102 EA N GM gl e to g a in re t se Pl at e ng lic en ki er rn de bl oc bu io tib an 99 9 101 an r ← nJ/#op/pixel 103 41/52 Le modèle OpenCL OpenCL −→ MPPA • modèle répandu • E/S gérées par le modèle • support partiel d’OpenCL évolutions de la pile logicielle • performances à améliorer accès à la mémoire globale ? −→ à éviter actuellement sur MPPA pour ce type d’applications 42/52 Quel modèle choisir ? Andey vs. Bostan : OpenMP sur 1 cluster 30 Andey (OpenMP 1 thread) Bostan (OpenMP 1 thread) Andey (OpenMP 16 threads) Bostan (OpenMP 16 threads) 20 10 EA N GM a gl e to g Pl se en re tin at e ng ki lic r rn e de bl oc bu io ib an t 99 9 0 an r Speedups → 40 43/52 OpenCL sur MPPA : Andey vs. Bostan Andey (OpenCL) Bostan (OpenCL) 1.5 1 0.5 EA N GM le a in to gg Pl se lic en re t at e ng ki er rn de bl oc bu io ib an t r9 99 0 an Speedups → 2 44/52 Le meilleur modèle de programmation sur MPPA ? 102 OpenCL (Bostan) Sigma-C (Andey) 101 N EA GM gl e a in to g Pl se lic en re t at e ng ki er de bl oc bu rn io tib an 99 9 100 an r Speedups → OpenMP (Bostan 1 cluster) 45/52 Comparaison des modèles Modèle Avantages Inconvénients OpenMP • répandu • portage rapide • 16 cœurs sur 256 • mémoire : 2 Mo (code, données) • transferts depuis l’hôte • performant • communications • • • • OpenCL • répandu • portage rapide • implémentation en cours • accès mémoire • performances ? OpenMP + IPC • 256 cœurs • performances ? • tuilage • communications Sigma-C trop statique contrôle hôte nouveau langage abandonné 46/52 Sigma-C (Andey) Quadro 600 103 SPoC SMIL (i7) Tesla C 2050 102 EA N GM gl e to g a in re t se Pl at e ng lic en ki er de bl oc bu rn io tib an 99 9 101 an r ← nJ/#op/pixel Comparaison avec d’autres accélérateurs 47/52 Conclusions & Perspectives Contributions principales Comparaisons expérimentales sur MPPA • 3 modèles de programmation parallèle • 2 générations de processeurs Preuve de la possibilité d’atteindre les 3P • développement d’un environnement logiciel intégré • regroupant plusieurs chaînes de compilation • restreint au traitement d’images • publication CPC 2016 48/52 Les piles logicielles SMIL et FREIA smiltofreia FREIA app.c SMIL app.py Optimisations à la compilation applications runtimes SMIL Python Swig wrapper FREIA common runtime smilc SMIL lib Fulguro Sigma-C OpenCL SPoC Terapix matériels Processeurs multicœurs Processeurs manycore GPUs FPGAs 49/52 Environnement logiciel : freiacc 1 app −→ 3P FREIA app.c SMIL app.py X Programmabilité freiacc ? Performance X Portabilité SMIL Sigma-C OpenCL SPoC/Terapix Processeurs multicœurs MPPA GPUs FPGAs 50/52 Perspective : autre modèle pour le MPPA Objectif : utiliser tous les cœurs du MPPA • OpenMP sur les clusters en C : réécriture des noyaux • environnement d’exécution : transferts, tuilage, recouvrements • communications inter-clusters (à la MPI) • optimisations via PIPS (fusion d’opérateurs, etc.) Processeur hôte Lectures Écritures Cluster E/S Clusters de calcul Application Noyaux OpenMP Runtime Noyaux OpenMP Noyaux OpenMP 51/52 Perspective : DSLs et nouvelles architectures Le processeur MPPA • potentiel embarqué vs. complexité architecturale ok ! • mémoire : taille SMEM, accès DDR… Traitement d’image • portage d’algorithmes non locaux segmentation Langages spécifiques à un domaine — DSLs • 3P : programmabilité, portabilité, performance • normalisation, basés sur des langages généralistes 52/52 Compilation efficace d’applications de traitement d’images pour processeurs manycore CEA LIST, Saclay Pierre Guillou mardi 6 décembre 2016 MINES ParisTech, PSL Research University Bibliographie personnelle I Pierre Guillou. Compilation d’applications de traitement d’ images sur architecture MPPA-Manycore. Conférence d’ informatique en Parallélisme, Architecture et Système (ComPAS 2014). Poster. Avr. 2014. url : https://hal-minesparistech.archives-ouvertes.fr/hal-01096993. Pierre Guillou. Compiling Image Processing Applications for Many-Core Accelerators. ACACES Summer School : Eleventh International Summer School on Advanced Computer Architecture and Compilation for High-Performance and Embedded Systems. Poster. Juil. 2015. url : https://hal-mines-paristech.archivesouvertes.fr/hal-01254412. Bibliographie personnelle II Pierre Guillou. smilc : A C wrapper for SMIL. url : https://scm.cri.ensmp.fr/git/smilc.git. Pierre Guillou, Fabien Coelho et François Irigoin. « Languages and Compilers for Parallel Computing : 27th International Workshop, LCPC 2014, Hillsboro, OR, USA, September 15-17, 2014, Revised Selected Papers ». In : sous la dir. de James Brodman et Peng Tu. Cham : Springer International Publishing, 2015. Chap. Automatic Streamization of Image Processing Applications, p. 224–238. isbn : 978-3-319-17473-0. doi : 10.1007/978-3-319-17473-0_15. url : http://dx.doi.org/10.1007/978-3-319-17473-0_15. Bibliographie personnelle III Pierre Guillou et al. « A Dynamic to Static DSL Compiler for Image Processing Applications ». In : 19th Workshop on Compilers for Parallel Computing. Valladolid, Spain, juil. 2016. url : https://hal-mines-paristech.archivesouvertes.fr/hal-01352808. Nelson Lossing, Pierre Guillou et François Irigoin. « Effects Dependence Graph : A Key Data Concept for C Source-to-Source Compilers ». In : 2016 IEEE 13th International Working Conference on Source Code Analysis and Manipulation (SCAM) (oct. 2016). Benoît Pin, Pierre Guillou et Fabien Coelho. smiltofreia : A SMIL Python to FREIA C compiler. url : https://scm.cri.ensmp.fr/git/smilpyc.git.