NmdMystery
NmdMystery

Reputation: 2868

Handling Multiple OpenCL Versions and Platforms

Intel recently updated its OpenCL SDK to the 2.0 specification. AMD is still on 1.2, and Nvidia on 1.1. Essentially, this means each GPU platform is now on its own version.

OpenCL does not appear to be designed in the same way OpenGL is in terms of how deprecation works. As far as I know there's no way to request a compatibility version, and Intel even incorporates build errors in its SDK preventing you from calling deprecated functions.

If I want to support every platform using a minimum version (1.1, most likely), what is required of me?

Upvotes: 2

Views: 1778

Answers (3)

Andrii Logan Zvorygin
Andrii Logan Zvorygin

Reputation: 21

Making only ifdef statements unfortunately doesn't work if you have more than one platform, and they support different OpenCL versions. For instance POCL which installs on the CPU supports 2.0, so you need to have the 2.0 OpenCL headers, but most GPU's and open source drivers, only support OpenCL 1.1 or 1.2.

The best option seems to be to get the OpenCL platform version info, and base what commands are called based on that. Unfortunately it is a char[] so may have to parse it out.

Here is an example of how to get the platform info string.

clGetPlatformInfo(platforms[platform_indexFinger], CL_PLATFORM_VERSION, INFO_LENGTH, &platformInfo, &realSize);

Typically the version info is of the form: "OpenCL 1.2 implementation name"

Here is a little function I made to diagnose the current opencl number


    float diagnoseOpenCLnumber(cl_platform_id platform) {
    #define VERSION_LENGTH 64
      char complete_version[VERSION_LENGTH];
      size_t realSize = 0;
      clGetPlatformInfo(platform, CL_PLATFORM_VERSION, VERSION_LENGTH,
                        &complete_version, &realSize);
      char version[4];
      version[3] = 0;
      memcpy(version, &complete_version[7], 3);
      // printf("V %s %f\n", version, version_float);
      float version_float = atof(version);
      return version_float;
    }

Can then use it like so, for example with command queue function which were modified for 2.0



        float version_float = diagnoseOpenCLnumber(platform_id);
        if (version_float >= 2.0) {
          command_waiting_line =
              clCreateCommandQueueWithProperties(context, device_id, 0, &return_number);
        else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

          command_waiting_line =
              clCreateCommandQueue(context, device_id, 0, &return_number);
#pragma GCC diagnostic pop
        }

Upvotes: 2

Giuseppe Salvatore
Giuseppe Salvatore

Reputation: 726

In the header cl.h you'll find a list of definitions like the following:

...
#define CL_VERSION_1_0   1
#define CL_VERSION_1_1   1
#define CL_VERSION_1_2   1
#define CL_VERSION_2_0   1
...

In my case I had annoying warnings about a deprecated function if I was using OpenCL 2.0 to build. So my quick/dirty solution was to do

#ifdef CL_VERSION_2_0 
    //call 2.0 Function
#else
    //call deprecated Function
#endif

Although this might require several fix in your code it's the way to me if you want to compile based on the opencl library available.
Note that if you are using opencl 1.2 you'll get the definition of all the previous versions (so like in the example above CL_VERSION_1_1 and CL_VERSION_1_0 will be defined as well)
Hope this helps

Upvotes: 0

chippies
chippies

Reputation: 1615

AFAIK deprecated functions do not have to be implemented, hence code should check the OpenCL platform version number and avoid calling deprecated functions on that platform. See this earlier discussion: http://www.khronos.org/message_boards/showthread.php/8514-clCreateImage-2D-3D-vs-the-ICD-loader. At present, calling deprecated OpenCL 1.1 functions on AMD or Intel platforms (OpenCL 1.2) still works, but there are no guarantees that this will remain true in the future or on other platforms. I guess that as soon as supporting those deprecated functions becomes too much hassle for the maintainers of an implementation, they'll be removed.

Admittedly, I'm naughty as I have just ignored the problem and continued to use OpenCL 1.1 functions. However, if you are starting a new project (and have the time) then rather wrap the deprecated functions in some sort of generic function that has paths for each version of OpenCL - faster to do it now than later in my opinion. There is a list of frameworks and libraries at http://www.khronos.org/opencl/resources. Perhaps you will find that one of them solves this problem well enough. If not, and if you have enough time then you could build a framework that hides most of the OpenCL functions from your program. Then, as more functions get deprecated you will hopefully only need to change your framework, but not the programs that use it. At the moment, I don't know of any framework that does this for one in C++.

Upvotes: 1

Related Questions