处理多个OpenCL版本和平台

时间:2014-09-11 19:26:59

标签: opencl

英特尔最近将其OpenCL SDK更新为2.0规范。 AMD仍然在1.2,而Nvidia在1.1。从本质上讲,这意味着每个GPU平台现在都有自己的版本。

OpenCL似乎没有以相同的方式设计OpenGL就弃用的工作方式而言。据我所知,没有办法请求兼容版本,英特尔甚至在其SDK中包含构建错误,阻止您调用已弃用的函数。

如果我想支持使用最低版本(1.1,最有可能)的每个平台,我需要什么?

3 个答案:

答案 0 :(得分:2)

如果您拥有多个平台,那么仅使用ifdef语句并不起作用,并且它们支持不同的OpenCL版本。例如,安装在CPU上的POCL支持2.0,因此您需要拥有2.0 OpenCL标头,但大多数GPU和开源驱动程序仅支持OpenCL 1.1或1.2。

最佳选择似乎是获取OpenCL平台版本信息,并基于此调用基于调用的命令。不幸的是它是一个char []所以可能需要解析它。

以下是如何获取平台信息字符串的示例。

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

通常,版本信息的格式为:" OpenCL 1.2实施名称"

这是我用来诊断当前opencl数字的一个小功能


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

然后可以像这样使用它,例如使用为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
        }

答案 1 :(得分:1)

不必实现AFAIK弃用函数,因此代码应检查OpenCL平台版本号,并避免在该平台上调用已弃用的函数。请参阅前面的讨论:http://www.khronos.org/message_boards/showthread.php/8514-clCreateImage-2D-3D-vs-the-ICD-loader。目前,在AMD或英特尔平台(OpenCL 1.2)上调用已弃用的OpenCL 1.1函数仍然有效,但无法保证将来或其他平台仍然如此。我想,只要支持那些已弃用的函数对于实现的维护者来说就太麻烦了,它们就会被删除。

不可否认,我顽皮,因为我忽略了这个问题,并继续使用OpenCL 1.1功能。但是,如果你正在开始一个新项目(并且有时间),那么将弃用的函数包装在某种通用函数中,该函数具有每个OpenCL版本的路径 - 现在比我后来更快地完成它。 http://www.khronos.org/opencl/resources有一个框架和库列表。也许你会发现其中一个很好地解决了这个问题。如果没有,如果你有足够的时间,那么你可以构建一个框架来隐藏程序中的大多数OpenCL函数。然后,随着越来越多的函数被弃用,您希望只需要更改框架,而不是使用它的程序。目前,我还不知道任何用C ++编写的框架。

答案 2 :(得分:0)

在标题cl.h中,您将找到如下定义列表:

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

在我的情况下,如果我使用OpenCL 2.0进行构建,我会对已弃用的函数发出恼人的警告。所以我的快速/肮脏的解决方案是

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

虽然这可能需要在您的代码中进行多次修复,但如果您想根据可用的opencl库进行编译,那么这就是我的方法。
请注意,如果您使用的是opencl 1.2,那么您将获得所有先前版本的定义(因此,在上面的示例中也会定义CL_VERSION_1_1和CL_VERSION_1_0) 希望这有帮助

相关问题