I’m working on an application that will support OpenCL 1.2 implementations and OpenCL 1.1 implementations (come on, NVIDIA).
OpenCL 1.2 has some macro definitions, such as the CL_MEM_HOST_NO_ACCESS allowed argument to clCreateBuffer that did not exist in 1.1. So my application will not compile on an OpenCL 1.1 system without some alternative code (i.e. suppressing the flag)
I’m not finding a reference to a global OpenCL version macro definition for the host code.
So, for flags like the above example, I’m not sure what else to do besides create a global macro of my own that my build system will have to set based on some driver version test. Does this really have to be so complicated, or am I overlooking something?
This test is probably best done at run-time instead of at compile time. If you tried to do the test at compile time, someone could take your binary to another machine and get different results. Or someone could put a new device in the same machine, and your compiled-in test would be incorrect. At run-time, the clGetDeviceInfo query with the CL_DEVICE_VERSION parameter should give you what you need.
Well, I need some way to obscure or expose the 1.2 symbols to the host compiler. Even if I implemented some code to parse the string response for CL_DEVICE_VERSION or CL_PLATFORM_VERSION, I cannot refer to a 1.2 symbol such as CL_MEM_HOST_NO_ACCESS, on a platform that only supports OpenCL 1.1. I’ll just get a compiler error, even if the reference is in some inactive if/else branch.
I suppose I could do something like this.
But I don’t think the OpenCL spec requires that the constants like CL_MEM_HOST_NO_ACCESS be preprocessor macro definitions. Couldn’t they be implemented as extern typed-constants?
Yes, I don’t see a way to do this that is guaranteed by the spec. cl_platform.h defines CL_API_SUFFIX__VERSION_1_2 in the 1.2 version of the standard headers. That might be a more readable way to test, but it is not mentioned in the spec.
This is one of my major issues with OpenCL. I am currently working on a library and header files that will deal with this issue for you, by breaking OpenCL apart into discrete units of functionality called capabilities. You can read an article I wrote on the topic here https://blog.ajguillon.com/2013/09/16/my-opencl-vision-and-philosophy/.
I anticipate that I will have a library ready by the end of the month that you can use. Basically, you will link to a library like libclcaps, and that’s it. That library will figure out what is on the system, and will map the calls to the right version and concepts. This treats the symptoms not the disease, however, and I hope that the interface and approach I propose is taken seriously by the standards group.
Essentially, your application will link this way:
Application --> libclcaps --> OpenCL
This will provide permanent binary compatibility by design. Everything I am doing is fully conformant with the specification.