opencl Getting started with opencl C# implementation of OpenCL 1.2: number of platforms for an AMD system in 64-bit windows


Example

OpenCL is low level api so it must be implemented in "C space" first. For that, one needs to download header files from Khronos' site. My hardware is AMD and capable of version 1.2, downloading

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

from this page

should be enough for C++ bindings so after adding these files to your project and setting proper binary(and library) file locations(

$(AMDAPPSDKROOT)\lib\x86_64 for 64-bit amd library (amd app sdk's libraries are preferred)

,

C:\Windows\SysWOW64 for 64-bit opencl.dll (.so file if ICD is of a Linux system)

for example but different for Intel-Nvidia), you can start querying a list of platforms(amd,intel,xilinx,nvidia) after installing proper drivers(such as crimson for amd). Drivers are for running opencl application(using ICD), libraries and header files are for development to be in short.

To query platforms:

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


    }

could be built into a dll(such as OCLImplementation.dll)

and to use it from C# side,

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

ofcourse the dll must be seen by the C# project, simply putting it near executable of project solves it.

Now, if sample computer has at least one opencl-capable platform,

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

totalPlatforms variable must have at least "1" value. Then you can use platforms variable in C-space using additional functions to iterate through all platforms to query all devices such as CPU,GPU and special purpose accelerators such as phi or some fpga.

One does not simply write all these C++ to C# wrappers for time-critical projects. There are many wrappers written for C#, Java and other languages. For java, there is "Aparapi" that is the "java bytecode to opencl-c" converter api that takes what you write purely in java to a gpu-parallel version on the fly so it is somewhat portable.