Make it easier to get the CL version number

I currently have this to check for OpenCL 1.1:

// get the version
    cl.platform.version_major = atoi(strchr(cl.platform.version, ' ') + 1);
    cl.platform.version_minor = atoi(strchr(strchr(cl.platform.version, ' ') + 1, '.') + 1);

    if (cl.platform.version_major == 1)
    {
        if (cl.platform.version_minor == 0)
            cl.platform.version_num = version_1_0;
        else if (cl.platform.version_minor == 1)
            cl.platform.version_num = version_1_1;
        else
            cl.platform.version_num = version_newer;
    }
    else
        cl.platform.version_num = version_newer;

As you can see it is rather messy.

My suggestion is to add a way to get the version back as an int rather than a string.

e.g.
Add CL_PLATFORM_VERSION_NUMBER, CL_DEVICE_VERSION_NUMBER, and CL_DEVICE_OPENCL_C_VERSION_NUMBER to clGetPlatformInfo and clGetDeviceInfo.

They should return a cl_ushort structured like this:
0xAABB
Where the upper 8 bits (A) is the major version number, and the lower 8 bits (B) is the minor version number.

Then in cl.h add:

#define CL_VERSION_1_0     0x0100
#define CL_VERSION_1_1     0x0101
#define CL_VERSION_2_0     0x0200

etc.

Then to test for new features you can do something like:

cl_ushort version;
clGetDeviceInfo(device, CL_DEVICE_VERSION_NUMBER, sizeof(version), &version);

if (version >= CL_VERSION_1_1)
{
     //do something specific to 1.1
}

Since the version string is guaranteed to have the format “OpenCL M.m” you can do this:


const char* version_1_0 = "OpenCL 1.0";
const char* version_1_1 = "OpenCL 1.1";

if(!strncmp(version, version_1_0, strlen(version_1_0)))
{
   // Handle CL 1.0 here
}
else
if(!strncmp(version, version_1_1, strlen(version_1_1)))
{
    // Handle CL 1.1 here
}
else
{
    // Handle other versions here.
}

The code above is a simple way to do it. There are other ways that are almost as straightforward.

Thanks for that tip. I will put that into the code tomorrow.
I still reckon an integer version number is easier than strings.

How about this?


// The version string is guaranteed to have the form "OpenCL M.m"
if(strlen(version_string) < strlen("OpenCL M.m"))
{
     // Handle error here
}
int major_version = version_string[7] - '0';
int minor_version = version_string[9] - '0';

Another quick and dirty way:


double version = atof(&version_string[7]);
int major_version = floor(version);
int minor_version = fmod(version, 1.0);

Sorry. I was working and suddenly realized that I made a mistake here. It should have been something like this:

int minor_version = (int)(10.0*fmod(version, 1.0));

I’m sure you got the idea either way.

For OpenCL 10.0 this will return major_version = 1 and minor_version = -2

…which is why there is a guard right before that code to prevent that case. Anyhow, the point is that there are a variety of ways in which you can read the version number in a few lines of code even in C.

When trying to test if the current version is >=3.5, many coders have been known to do:
if (major_version >= 3) and (minor_version >= 5) then…
Which obviously fails as soon as you get to version 4.0

That is a good argument.