The Khronos Group - a non-profit industry consortium to develop, publish and promote open standard, royalty-free media authoring and acceleration standards for desktop and handheld devices, combined with conformance qualification programs for platform and device interoperability.

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

clCreateImage{,2D,3D} vs the ICD loader

Hi there,

As part of PyOpenCL, I am trying to supply one interface to clCreateImage{,2D,3D}. It turns out to be harder than I thought to figure out which one to call.

My first idea was that as long as the header you compiled against (and thereby the ICD loader) offered the 1.2 function clCreateImage, then you would call that, and the translation to the older functions would be done for you behind the scenes. Unfortunately, none of the ICD loaders I've tried behaves this way.

In fact, for implementations that don't supply the 1.2 function, calling clCreateImage leads to a crash.

The spec doesn't say anything about this topic. It would be good if it did. It would be even better if it specified that the loader has to do some translation.

The current situation is highly unpleasant--it means I have to go and parse version numbers just to figure out what functions are safe to call for each and every platform.

Re: clCreateImage{,2D,3D} vs the ICD loader

I have found the same issue with Nvidia. For my work, I'll just stick to OpenCL 1.0 for the moment. I don't see any evidence of code to handle this backwards compatibility in cl.hpp from either Khronos or the version 1.2 preview in AMD APP.

I think you will have to write code to check which version is supported and then provide a wrapper function that calls the appropriate clCreateImage variant. You will have to do that for all of the OpenCL 1.2 functions.

A suggestion to Khronos: please build in this sort of automatic translation into cl.hpp. A possible approach would be to have four versions of each class: a base class, e.g. cl::Platform, but then provide CL 1.0, 1.1 and 1.2 versions that inherit from cl::Platform. All the versions should try to provide the same functionality as the 1.2 version, hiding the implementation tricks from the user. If some function really cannot be provided, rather through an exception when someone tries to use that function instead of the program suffering a segfault.

Re: clCreateImage{,2D,3D} vs the ICD loader

Note that it is very difficult to know which functions are supported by which plate-form or even device.
I'm one of the author of the ocl-icd project, a free OpenCL ICD Loader (ie libOpenCL.so). It happens that ICDs have no way to tell the ICD Loader which functions are implemented.
The ICD Loader works by acting as a dispatcher, calling the ICD function from a table of function pointers. This table is increased when new functions (core or extensions) are added but the ICD Loader does not know the size of the table provided by the ICD. The result is that :
- the ICD Loader can deference memory past the end of a short table, jumping anywhere in memory (try to call an OpenCL 1.2 function with a ICD Loader supporting 1.2 but with a plate-form supporting only OpenCL 1.1 to test)
- the ICD Loader does not know which functions are implemented by each ICD
- so programs cannot know for sure which functions are available. The ICD Loader will present all of them, but it is not sure that underlining ICD (ie OpenCL implementation) support the same version of OpenCL as the ICD Loader (as explained before), or that the ICD support deprecated functions (for example, Intel ICD (OpenCL 1.1) does not implement the clSetCommandQueueProperty function (deprecated in OpenCL 1.1))

So, programs must rely on the declared OpenCL version (by calling clGetPlatformInfo) for each loaded ICD and expect they implement all of the listed function in the norm. The ICD Loader cannot help them more.

It would have been really better if the first entry of the table presented to the ICD Loader was the size of the table. For backward compatibility, this is not possible any more. But it would still be possible to put this field *just before* the actual table and tell it to the ICD Loader by declaring an extension (cl_khr_icd_size for example).
An other improvement would be to allow a program to ask if a plateform implements a function or not. Something like clGetExtensionFunctionAddressForPlatform but that would also be correct for core functions. If the feature in the previous paragraph were available, the ICD Loader would be able to answer is most cases correctly (is the table of the plateform long enough for the requested function and is the function pointer non null).

Re: clCreateImage{,2D,3D} vs the ICD loader

Thanks vdanjean for pointing out that OpenCL 1.1 implementations don't need to implement deprecated OpenCL 1.0 functions. I was going to try to get by with OpenCL 1.0, irrespective of the platform, but now I see that isn't guaranteed to be portable either.

Re: clCreateImage{,2D,3D} vs the ICD loader

vdanjean, I'm curious what happens when OpenCL 1.3 or whatever the next version number will be is released. Code written against OpenCL 1.0 - 1.2 specs could get by with parsing the OpenCL version string when the ICDs only have versions from 1.0 to 1.2.

What happens when encountering an ICD with a later version number where, once again, some older functions have been deprecated and are no longer implemented? Is there some way for the application to ask "Do you support OpenCL 1.0/1.1/1.2?" Naturally, the app could just produce an error when encountering a version string it doesn't recognise, but what about say AMD's implementation which supports v1.2 but still provides v1.0 functions? The app would have no way of knowing that v1.0 functions are available.

How should one future-proof oneself in this situation? Or are we basically stuffed?

Re: clCreateImage{,2D,3D} vs the ICD loader

chippies: not that I'm only an independant developper. So, what I write is only my personnal opinion, not any kind of "official" message.

I aggree with you that, with the current situation, they is no way to know if a ICD with a declared version fully support or not a previous version.
I would really welcome a feature such as the one I discribed so that an ICD Loader is able to know if an ICD provides or not any (even core) functions. I program would then be able to check at start that all required functions for it are supported by the choosen ICD.
We can imagine shortcut check-functions that check for all functions required by a specific OpenCL version (in order to avoid to check the whole lists of functions by any programs).
We can also imagine that, for official OpenCL version, Khronos introduces specific declared extensions (so that applications check for this extension instead of looking at the version string). For example, AMD ICD can declare cl_khr_ocl_1.0, cl_khr_ocl_1.1 and cl_khr_ocl_1.2 if it supports all these three version.

In any case, in the current situation, it is very difficult to write OpenCL applications or libraries that are able to work with different ICD versions. And, as the ICD version is discovered at run-time, it is very difficult to write portable OpenCL applications or libraries.