OpenCL () est la combinaison d'une API et d'un langage de programmation dérivé du C, proposé comme un standard ouvert par le . OpenCL est conçu pour programmer des systèmes parallèles hétérogènes comprenant par exemple à la fois un CPU multi-cœur et un GPU. OpenCL propose donc un modèle de programmation se situant à l'intersection naissante entre le monde des CPU et des GPU, les premiers étant de plus en plus parallèles, les seconds étant de plus en plus programmables.

Présentation OpenCL distingue le processeur hôte (processeur central faisant office de chef d'orchestre) des périphériques (CPU, GPU, ou autre) dont la mission est d'exécuter des noyaux de calcul intensifs. OpenCL distingue donc d'un côté l'application tournant sur le processeur hôte (et qui va appeler l'API OpenCL), et de l'autre côté les noyaux qui sont programmés en OpenCL-C (et dont la vocation est d'être exécuté sur les périphériques).

OpenCL permet d'exprimer aisément du parallélisme de tâches mais aussi du parallélisme de données sous deux formes ; SPMD () et SIMD (), le tout de manière hiérarchique. Un graphe de tâches peut être créé dynamiquement via l'API OpenCL. Chaque tâche peut être représentée soit sous forme d'une instance unique (appelée tâche), soit sous forme d'une collection d'instances (appelée NDRange) d'un même noyau. Les NDRanges peuvent être de 1, 2 ou . Chaque instance de appartenant à un NDRange est appelée . Le NDrange peut lui-même être structuré en , ce qui permet aux à l’intérieur des de partager des données et de se synchroniser via des barrières.

Si parmi certains de ses objectifs techniques, OpenCL semble se rapprocher de C pour CUDA, modèle de programmation propriétaire de la société Nvidia, OpenCL a des objectifs plus larges car n'étant pas uniquement dédié aux GPU. Dans le monde du calcul haute performance ou du jeu, OpenCL permettra de tirer parti de la puissance des processeurs graphiques, des CPU multi-cœurs ou d'autres systèmes de calcul intensifs tels le CELL d'IBM, qui équipe notamment la de Sony. Dans le monde des systèmes embarqués sur puce (), tels qu'on les trouve dans les , OpenCL permettra l'accès, via une infrastructure de programmation unique, au processeur central, ainsi qu'aux différents sous-systèmes multimédia embarqués (GPU, , ou autres).

Il existe actuellement peu de moyens de déboguer des noyaux OpenCL. Tout d'abord, le débogueur NVIDIA , capable de déboguer CUDA thread par thread, ne supporte actuellement pas OpenCL, mais permet seulement de traquer les appels à l'API.. Ensuite, AMD propose une extension permettant de mettre des traces directement dans le code OpenCL (cl_amd_printf). Enfin, un programme appelé gDebugger (par Gremedy puis par AMD.) permet de suivre le déroulement de l'algorithme thread par thread. gDebugger a évolué, se nomme maintenant CodeXL et est hébergé. par l'initiative GPUOPEN.

OpenCL est également utilisé comme langage de description de matériel, pour la programmation des FPGA.

Historique OpenCL a été initialement conçu par Apple (qui en a déposé la marque), et affiné dans le cadre d'une collaboration avec AMD, Intel et Nvidia. Apple soumet d'abord sa proposition initiale au . Le , le est formé, comprenant des représentants des fabricants de matériel informatique et de logiciels. Celui-ci travaille durant cinq mois à boucler les détails techniques de la spécification . La spécification est révisée par les membres de Khronos et approuvée pour une version d'essai le . Une nouvelle version, , est publiée en par le . clarifie certains aspects de la spécification précédente et apporte de nouvelles fonctionnalités telles que les sous-, les vecteurs à , les événements utilisateur, de nouvelles fonctions , le support en standard d'extensions (telles que les fonctions atomiques ).

OpenCL est intégré dans Mac OS X 10.6. (). AMD décide de supporter OpenCL et plutôt que dans son . annonce l'adoption de OpenCL sous sa plate-forme de développement, afin de supporter les processeurs graphiques de plusieurs fabricants avec une interface unique. Nvidia confirme également le le support complet de la dans son ..

Le , le a publié les spécifications d'. On y trouve notamment des fonctionnalités liées à la mobilité et à la portabilité, avec par exemple la possibilité de dissocier compilation et édition de liens des noyaux.. WebCL

Le Khronos Group a également développé une intégration d'OpenCL, bibliothèque de calcul parallèle, dans l'ensemble des interfaces de programmation d'HTML5. Actuellement, les navigateurs utilisent des extensions pour gérer OpenCL.

Nokia et Mozillahttp://webcl.nokiaresearch.com/ ont développé des extensions pour Firefox. Samsung pour WebKit et Motorola pour Node.js.

Historique des implémentations Des implémentations d'OpenCL existent pour la majorité des plateformes aujourd'hui. IBM pour ses supercalculateurs sous GNU/Linux utilisant des processeurs Power, les processeurs X86 d'Intel et AMD et les GPU les accompagnant traditionnellement (ATI, nVidia, VIA), les processeurs ARM Cortex-A9 (parties SSE et fpu 128bits Neon), ainsi que les DSP, GPU et autres les accompagnant dans les nombreuses implémentations des (SoC) (nVidia Tegra2, Qualcomm Snapdragon, Apple A4, Marvell Armada). Mesa (Implémentation OpenGL/OpenVG sous GNU/Linux) contient un OpenCL pour Gallium3D en cours de développement, nommé ..

Le , AMD et Nvidia font la première démonstration publique d'OpenCL, une présentation de à SIGGRAPH Asia 2008. AMD effectue une démonstration d'OpenCL accélérée sur CPU et explique la scalabilité d'OpenCL sur un ou plusieurs cœurs tandis qu'Nvidia fait une démonstration accélérée par GPU...

Le , à la , AMD et Havok font une démonstration de la première implémentation accélérée par OpenCL, Havok Cloth sur un GPU de la série Radeon d'AMD..

Le , Nvidia annonce la sortie de son pilote OpenCL et du aux développeurs participant à son ..

Le , AMD révèle les premiers outils de développement pour sa plateforme OpenCL comme partie de son programme ..

Le , Apple sort Mac OS X , qui contient une implémentation complète d'OpenCL..

Dans , OpenCL est initialement supporté sur les puces ATI Radeon , ATI Radeon ainsi que les puces Nvidia Geforce 8600M GT, GeForce 8800 GS, GeForce 8800 GT, GeForce 8800 GTS, Geforce 9400M, GeForce 9600M GT, GeForce , GeForce , GeForce , Quadro , et Quadro ..

Le , Nvidia sort ses propres pilotes OpenCL et son implémentation du SDK.

Le , AMD sort la quatrième bêta du , qui fournit une implémentation OpenCL complète sur tous les GPU des familles R700/R800, utilisant également les unités SSE3 des CPUs. Le SDK est disponible à la fois pour GNU/Linux et Windows..

Le , IBM sort la de son SDK OpenCL pour GNU/Linux sur l'architecture Power utilisé dans une majorité des plus puissants supercalculateurs au monde..

Le , Nvidia sort des pilotes pour l'implémentation OpenCL 1.0 (rev 48).

Les implémentations OpenCL d'Apple., Nvidia., . et Mesa Gallium3D. sont toutes basées sur la technologie de compilation LLVM et utilisent le compilateur Clang comme .

Le , VIA sort son premier produit supportant - Le processeur vidéo inclus dans les puces VN1000..

Le , AMD sort la version de production de l’., qui fournit un support d' pour les GPU R800 et un support bêta pour R700.

Le , Intel sort la version finale de son kit de développement supportant OpenCL ..

Le , AMD annonce son kit de développement ., qui améliore, entre autres, la bande passante CPU/GPU pour tirer un meilleur parti de ses récents APU.

Chez Intel, les processeurs graphiques inclus dans sa gamme de processeurs , sortis le , Intel ainsi que et supérieurs, sont les premières architectures à supporter matériellement OpenCL, en ..

La bibliothèque Beignet. est une bibliothèque OpenCL libre pour les processeurs Intel GT2, dans le cadre du projet freedesktop.org, et développé principalement par Intel. Il utilise principalement LLVM, mais est également compatible avec GCC.

Fin 2013, ARM annonce à son tour son « Mali OpenCL SDK », pour ses processeurs graphiques Mali T600 et supérieurs, dont les premiers modèles sont sortis en 2012. Les sources sont disponibles, mais la licence est propriétaire et contraignante quant à la redistribution..

Implémentations Open-source Clover et libCLC pour les fonctions de la bibliothèque standard OpenCL POCL (Portable OpenCL)

Exemple Cet exemple calcule une Transformée de Fourier rapide :

/* creation d'un contexte de calcul sur GPU */ context = clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU, NULL, NULL, NULL);

/* récupération de la liste des cartes disponibles */ clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &nb_devices); clGetContextInfo(context, CL_CONTEXT_DEVICES, nb_devices, devices, NULL);

/* creation d'une queue de commande sur le premier GPU */ queue = clCreateCommandQueue(context, devices, 0, NULL);

/* allocation des tampons mémoire */ memobjs = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float)*2*num_entries, srcA, NULL); memobjs = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float)*2*num_entries, NULL, NULL);

/* création du programme de calcul (le programme qui s'execute sur le GPU) */ program = clCreateProgramWithSource(context, 1, &fft1D_1024_kernel_src, NULL, NULL);

/* compilation du programme */ clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

/* création du noyau de calcul */ kernel = clCreateKernel(program, "fft1D_1024", NULL);

/* mise en place des paramètres */ clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobjs); clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobjs); clSetKernelArg(kernel, 2, sizeof(float)*(local_work_size+1)*16, NULL); clSetKernelArg(kernel, 3, sizeof(float)*(local_work_size+1)*16, NULL);

/* création des objets de travail et lancement du calcul */ global_work_size = num_entries; local_work_size = 64; clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size, local_work_size, 0, NULL, NULL);

Le calcul : (basé sur Fitting FFT onto the G80 Architecture) // This kernel computes FFT of length 1024. The 1024 length FFT is decomposed into // calls to a radix 16 function, another radix 16 function and then a radix 4 function

__kernel void fft1D_1024 (__global float2 *in, __global float2 *out, __local float *sMemx, __local float *sMemy) { int tid = get_local_id(0); int blockIdx = get_group_id(0) * 1024 + tid; float2 data; // starting index of data to/from global memory in = in + blockIdx; out = out + blockIdx; globalLoads(data, in, 64); // coalesced global reads fftRadix16Pass(data); // in-place radix-16 pass twiddleFactorMul(data, tid, 1024, 0); // local shuffle using local memory localShuffle(data, sMemx, sMemy, tid, (((tid & 15) * 65) + (tid >> 4))); fftRadix16Pass(data); // in-place radix-16 pass twiddleFactorMul(data, tid, 64, 4); // twiddle factor multiplication localShuffle(data, sMemx, sMemy, tid, (((tid >> 4) * 64) + (tid & 15))); // four radix-4 function calls fftRadix4Pass(data); fftRadix4Pass(data + 4); fftRadix4Pass(data + 8); fftRadix4Pass(data + 12); // coalesced global writes globalStores(data, out, 64); }

Références

Bibliographie

Voir aussi Articles connexes GPGPU OpenHMPP New Standard for manycore Vulkan PoCL, bibliothèque OpenCL utilisant principalement les microprocesseurs Liens externes

Catégorie:Interface de programmation Catégorie:Langage de programmation Catégorie:Norme ou standard informatique Catégorie:Calcul parallèle