无法在1.1版本中使用1.2标头编译OpenCL应用程序

时间:2013-10-16 14:04:24

标签: c++ opencl nvidia

我正在使用Khronos Group的cl.hpp为OpenCL 1.2和nVidia的openCL库编写一个小的hello world OpenCL程序。驱动程序和ICD我支持OpenCL 1.1。由于nVidia方面尚不支持1.2,因此我在OpenCL 1.2上需要的功能上出现一些错误。

另一方面,OpenCL 1.2的cl.hpp有一个标志,确切地说CL_VERSION_1_1,以1.1模式运行标头,但它不起作用。任何人都有类似的经历或解决方案吗?

注意:版本1.1的cl.hpp有效但在编译期间会生成许多警告。这就是我试图使用1.2版本的原因。

5 个答案:

答案 0 :(得分:7)

不幸的是,NVIDIA会分发旧版本的OpenCL ICD(将API调用发送到相应驱动程序的库)。你最好的选择是

  • 获取更新版本的ICD(如果您使用的是Linux,这是libOpenCL.so,您可以在AMD的APP SDK中找到更新的副本)。缺点是,如果您分发已编译的代码,它还需要1.2 ICD。
  • 使用OpenCL 1.1头文件,但您可以使用最新的cl.hpp。它(理论上)应该检测到它与OpenCL 1.1标头组合并禁用所有OpenCL 1.2代码(虽然没有经过多少测试)。使用最新的cl.hpp的优点是有很多错误修复无法反向移植到1.1版本的cl.hpp。
  • 你可以这样做:

    #include <CL/cl.h>
    #undef CL_VERSION_1_2
    #include <CL/cl.hpp>
    

    我刚刚在我的代码中实现了它,似乎可以解决这个问题。

答案 1 :(得分:6)

您可以定义标志CL_USE_DEPRECATED_OPENCL_1_1_APIS,这将使1.2 hpp文件1.1兼容。

#define CL_USE_DEPRECATED_OPENCL_1_1_APIS

这是我在NVIDIA和AMD上所做的。像魅力一样工作

答案 2 :(得分:4)

我厌倦了下载英特尔,Nvidia和AMD的几个GB OpenCL SDK,并遇到了不同的问题:

  • 英特尔需要注册并拥有临时许可。
  • Nvidia SDK不支持OpenCL 2.0,无论如何你必须下载cl.hpp。
  • AMD cl.hpp文件定义了最小和最大宏,它们可能与MSVC的最小和最大宏冲突(我花了太多时间弄清楚如何解决这个问题,例如NOMINMAX)。标题与Khronos定义的标题甚至不同(没有最小/最大问题)。

因此,我按照此SO answer的建议下载了源代码并包含了Khronos,并自行编译了OpenCL.lib文件。包含和OpenCL.lib文件是几MB。这比Intel / Nvidia / AMD SDK中的所有额外功能要小得多!我可以在我的项目中包含OpenCL包含和OpenCL.lib文件,不再需要告诉其他人下载SDK。

来自Khronos registry的OpenCL 2.0包含一个新的C ++绑定文件cl2.hpp。看看这个文件,我已经确定使用OpenCL 2.0支持已弃用函数的正确方法是这样的。

#define CL_HPP_MINIMUM_OPENCL_VERSION 110
#define CL_HPP_TARGET_OPENCL_VERSION 120
#define CL_HPP_CL_1_2_DEFAULT_BUILD
#include "CL/cl2.hpp"

这是因为cl2.hpp文件具有此代码

#if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
# define CL_USE_DEPRECATED_OPENCL_1_0_APIS
#endif
#if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
#endif
#if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
# define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#endif
#if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
# define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#endif

请注意,您不再需要(也不应该)再包含<CL/opencl.h>

最后,在#include "CL/cl2.hpp"之后为了让我的代码与Boost/Compute一起使用,我必须添加

#undef CL_VERSION_2_0

我自己的OpenCL代码没有这个,但Boost / Compute没有。 It appears I'm not the only one having this issue。我的GPU不支持OpenCL 2.0。

答案 3 :(得分:1)

看起来唯一的方法是在使用支持1.1的设备时使用OpenCL 1.1标头。

答案 4 :(得分:1)

您可以调用可以设置clBuildProgram的选项,如下所示

const char options[] = "-cl-std=CL1.1";

clBuildProgram( program, 1, &devices, options, NULL, NULL );

无论您的设备支持哪种版本,都会强制编译器使用OpenCL 1.1