Premiers pas avec opencl

Qu’est-ce qu’OpenCL ?

OpenCL est l’abréviation de Open Ccomputing Llangage. OpenCL est un cadre de programmation parallèle sur des plates-formes hétérogènes, appelées * dispositifs de calcul *, allant des processeurs aux GPU en passant par des plates-formes plus spéciales comme les FPGA. OpenCL fournit une interface standard pour le calcul parallèle sur ces appareils de calcul mais également le parallélisme inter-appareils. Il spécifie un langage de programmation, basé sur C99, et les exigences minimales des fonctions de base mises en œuvre sur les appareils compatibles OpenCL. OpenCL décrit en outre un modèle abstrait de calcul et de mémoire, étant aussi général que possible pour faciliter la réutilisation du code entre différentes plates-formes.

Conditions préalables

Si vous avez un processeur ou une carte graphique (GPU) moderne à l’intérieur de votre machine, il y a de fortes chances que tout soit prêt pour les premiers pas dans OpenCL. Découvrir si votre processeur est compatible OpenCL peut généralement être fait via la page d’accueil du fabricant, un bon premier départ est la documentation officielle sur

https://www.khronos.org/conformance/adopters/conformant-products#opencl

Qu’est-ce qu’OpenCL ?

Open Computing Language (OpenCL) est un framework pour écrire des programmes qui s’exécutent sur des CPU, des GPU et d’autres processeurs et accélérateurs parallèles.

OpenCL spécifie un langage de programmation (basé sur C) qui donne accès à une mémoire sur puce nommée, un modèle pour exécuter des tâches en parallèle et la possibilité de synchroniser ces tâches.

Implémentation C# d’OpenCL 1.2 : nombre de plates-formes pour un système AMD dans des fenêtres 64 bits

OpenCL est une API de bas niveau, elle doit donc d’abord être implémentée dans “l’espace C”. Pour cela, il faut télécharger les fichiers d’en-tête du site de Khronos. Mon matériel est AMD et compatible avec la version 1.2, en téléchargeant

opencl.h 
cl_platform.h 
cl.h 
cl_ext.h 
cl_egl.h 
cl_dx9_media_sharing.h 
cl_d3d10.h 
cl_d3d11.h 
cl_gl.h 
cl_gl_ext.h 
cl.hpp

de [cette page][1]

devrait être suffisant pour les liaisons C++, donc après avoir ajouté ces fichiers à votre projet et défini les emplacements de fichiers binaires (et de bibliothèque) appropriés (

$(AMDAPPSDKROOT)\lib\x86_64 pour la bibliothèque AMD 64 bits (les bibliothèques du SDK d’application AMD sont préférées)

,

C:\Windows\SysWOW64 pour opencl.dll 64 bits (fichier .so si ICD est d’un système Linux)

par exemple mais différent pour Intel-Nvidia), vous pouvez commencer à interroger une liste de plates-formes (amd, intel, xilinx, nvidia) après avoir installé les pilotes appropriés (tels que crimson pour amd). Les pilotes sont destinés à exécuter l’application opencl (à l’aide d’ICD), les bibliothèques et les fichiers d’en-tête sont destinés au développement en bref.

Pour interroger les plates-formes :

#define __CL_ENABLE_EXCEPTIONS
#include "stdafx.h"
#include <vector>
#include <CL/cl.hpp>

extern "C"
    {
       // when this class is created, it contains a list of platforms in "platforms" field.
       class OpenClPlatformList
       {
           public:
               std::vector<cl::Platform> platforms;
               int platformNum;
               OpenClPlatformList()
               {
                   platforms= std::vector< cl::Platform>();
                   cl::Platform::get(&platforms);
                   platformNum= platforms.size();
               }
        };


        // this is seen from C# when imported. Creates an object in memory.
        __declspec(dllexport)
            OpenClPlatformList * createPlatformList()
        {
            return new OpenClPlatformList();
        }

        __declspec(dllexport)
            int platformNumber(OpenClPlatformList * hList)
        {
            return hList->platformNum;
        }


        __declspec(dllexport)
            void deletePlatformList(OpenClPlatformList * p)
        {
            if (p != NULL)
                delete p;
            p = NULL;
        }


    }

pourrait être intégré dans une dll (telle que OCLImplementation.dll)

et pour l’utiliser du côté C#,

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;


namespace WrapperCSharp
{
    public class WrapperCSharp
    {
        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr createPlatformList();

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern int platformNumber(IntPtr hList);

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern void deletePlatformList(IntPtr hList);
    }
}

Bien sûr, la dll doit être vue par le projet C #, il suffit de la placer près de l’exécutable du projet pour la résoudre.

Maintenant, si l’exemple d’ordinateur a au moins une plate-forme compatible opencl,

IntPtr platformList = createPlatformList(); // just an address in C-space
int totalPlatforms = platformNumber(platformList); // AMD+NVIDIA systems should have "2"
deletePlatformList(platformList); //

La variable totalPlatforms doit avoir au moins la valeur “1”. Ensuite, vous pouvez utiliser des plates-formes variables dans l’espace C en utilisant des fonctions supplémentaires pour parcourir toutes les plates-formes pour interroger tous les périphériques tels que le CPU, le GPU et les accélérateurs à usage spécial tels que phi ou certains fpga.

On ne se contente pas d’écrire tous ces wrappers C++ vers C# pour des projets urgents. Il existe de nombreux wrappers écrits pour C#, Java et d’autres langages. Pour java, il y a “Aparapi” qui est l’api de conversion “java bytecode to opencl-c” qui prend ce que vous écrivez purement en java vers une version gpu-parallèle à la volée, donc c’est quelque peu portable.

[1] : https://www.khronos.org/registry/cl/

OpenCL et C#

Pour C#, il existe de nombreux wrappers qui offrent une interface pour communiquer avec OpenCL.

  • OpenCL.NET : C’est l’un des emballages les plus bas de gamme. Il offre une implémentation complète de l’API OpenCL pour C# sans ajouter aucune abstraction. Ainsi, les exemples C\C++ sont facilement portés pour cette bibliothèque. La seule page de projet est actuellement sur codeplex, qui se ferme le 15.12.2017 mais le package est disponible sur NuGet

https://openclnet.codeplex.com/

  • NOpenCL : Cette bibliothèque offre une interface abstraite entre C# et OpenCL.

L’objectif à court terme est de fournir une couche abstraite facile à utiliser qui donne accès à toutes les fonctionnalités d’OpenCL sans sacrifier les performances.

https://github.com/tunnelvisionlabs/NOpenCL

  • Cloo :

Cloo est une bibliothèque open source, facile à utiliser et gérée qui permet aux applications .NET/Mono de tirer pleinement parti du framework OpenCL.

https://sourceforge.net/projects/cloo/