英特尔最近将其OpenCL SDK更新为2.0规范。 AMD仍然在1.2,而Nvidia在1.1。从本质上讲,这意味着每个GPU平台现在都有自己的版本。
OpenCL似乎没有以相同的方式设计OpenGL就弃用的工作方式而言。据我所知,没有办法请求兼容版本,英特尔甚至在其SDK中包含构建错误,阻止您调用已弃用的函数。
如果我想支持使用最低版本(1.1,最有可能)的每个平台,我需要什么?
答案 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)
希望这有帮助