Primeros pasos con opencl

¿Qué es OpenCL?

OpenCL es la abreviatura de Open Ccomputing Llanguage. OpenCL es un marco para la programación paralela en plataformas heterogéneas, llamadas dispositivos informáticos, que van desde CPU sobre GPU hasta plataformas más especiales como FPGA. OpenCL proporciona una interfaz estándar para computación paralela en estos dispositivos informáticos, pero también paralelismo entre dispositivos. Especifica un lenguaje de programación, basado en C99, y requisitos mínimos de funciones básicas implementadas en dispositivos compatibles con OpenCL. OpenCL además describe un modelo abstracto de computación y memoria, siendo lo más general posible para simplificar la reutilización de código entre diferentes plataformas.

Requisitos previos

Si tiene una CPU moderna o una tarjeta gráfica (GPU) dentro de su máquina, es probable que tenga todo listo para los primeros pasos en OpenCL. Averiguar si su procesador es compatible con OpenCL generalmente se puede hacer a través de la página de inicio del fabricante, un buen primer comienzo es la documentación oficial en

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

¿Qué es OpenCL?

Open Computing Language (OpenCL) es un marco para escribir programas que se ejecutan en CPU, GPU y otros procesadores y aceleradores paralelos.

OpenCL especifica un lenguaje de programación (basado en C) que brinda acceso a la memoria en chip con nombre, un modelo para ejecutar tareas en paralelo y la capacidad de sincronizar esas tareas.

Implementación en C# de OpenCL 1.2: número de plataformas para un sistema AMD en ventanas de 64 bits

OpenCL es una API de bajo nivel, por lo que debe implementarse primero en el “espacio C”. Para eso, uno necesita descargar los archivos de encabezado del sitio de Khronos. Mi hardware es AMD y compatible con la versión 1.2, descargando

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 esta página

debería ser suficiente para los enlaces de C ++, así que después de agregar estos archivos a su proyecto y configurar las ubicaciones adecuadas de archivos binarios (y bibliotecas) (

$(AMDAPPSDKROOT)\lib\x86_64 para biblioteca amd de 64 bits (se prefieren las bibliotecas de amd app sdk)

,

C:\Windows\SysWOW64 para opencl.dll de 64 bits (archivo .so si ICD es de un sistema Linux)

por ejemplo, pero diferente para Intel-Nvidia), puede comenzar a consultar una lista de plataformas (amd, intel, xilinx, nvidia) después de instalar los controladores adecuados (como carmesí para amd). Los controladores son para ejecutar la aplicación opencl (usando ICD), las bibliotecas y los archivos de encabezado son para que el desarrollo sea breve.

Para consultar plataformas:

#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;
        }


    }

podría integrarse en un dll (como OCLImplementation.dll)

y para usarlo desde el lado de 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);
    }
}

por supuesto, el dll debe ser visto por el proyecto C #, simplemente colocándolo cerca del ejecutable del proyecto lo resuelve.

Ahora, si la computadora de muestra tiene al menos una plataforma compatible con 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 debe tener al menos el valor “1”. Luego, puede usar la variable de plataformas en C-space usando funciones adicionales para iterar a través de todas las plataformas para consultar todos los dispositivos como CPU, GPU y aceleradores de propósito especial como phi o algunos fpga.

Uno no simplemente escribe todos estos contenedores de C++ a C# para proyectos de tiempo crítico. Hay muchos contenedores escritos para C#, Java y otros lenguajes. Para Java, existe “Aparapi”, que es la API convertidora de “código de bytes de Java a opencl-c” que lleva lo que escribe puramente en Java a una versión paralela de GPU sobre la marcha, por lo que es algo portátil.

OpenCL y C#

Para C# existen muchos contenedores que ofrecen una interfaz para comunicarse con OpenCL.

-OpenCL.NET: Este es uno de los envoltorios de más bajo nivel que existen. Ofrece una implementación completa de la API de OpenCL para C# sin agregar abstracción alguna. Por lo tanto, los ejemplos de C\C++ se adaptan fácilmente a esta biblioteca. La única página del proyecto está actualmente en codeplex, que se cierra el 15/12/2017 pero el paquete está disponible en NuGet

https://openclnet.codeplex.com/

  • NOpenCL: Esta biblioteca ofrece una interfaz abstracta entre C# y OpenCL.

El objetivo a corto plazo es proporcionar una capa abstracta fácil de usar que proporcione acceso a la capacidad completa de OpenCL sin sacrificar el rendimiento.

https://github.com/tunnelvisionlabs/NOpenCL -Cloo:

Cloo es una biblioteca administrada de código abierto y fácil de usar que permite que las aplicaciones .NET/Mono aprovechen al máximo el marco OpenCL.

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