【问题标题】:Cannot compile OpenCL application using 1.2 headers in 1.1 version无法在 1.1 版本中使用 1.2 标头编译 OpenCL 应用程序
【发布时间】:2013-10-24 16:42:27
【问题描述】:

我正在使用 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 版本的原因。

【问题讨论】:

  • 我遇到了同样的问题,只是使用了 1.1 标头。将它复制到 cuda/include/CL 目录并让它永远存在。 Nvidia 似乎永远不会支持 OpenCL 1.2。奇怪的是 1.1 标题对我有用而没有警告。 Centos 6.2 和 gcc 4.8.1。

标签: c++ opencl nvidia


【解决方案1】:

不幸的是,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 的优势在于,有很多错误修复无法向后移植到 cl.hpp 的 1.1 版本。
  • 你可以这样做:

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

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

【讨论】:

  • 您仍然需要像 Erik 的回答那样定义 CL_USE_DEPRECATED_OPENCL_1_1_APIS。
  • 很可惜,nVIDIA 试图扼杀如此绝望的 OpenCL,而不是给予适当的支持。例如,现在他们的工具甚至不配置或记录 OpenCL 内核......
  • 有效! Nvidia 非常沉默,对 OpenCL 无话可说。英特尔为 MSWIndows 提供 GPU OpenCL 支持。他们运气不好!支持 OpenCL 2.0 的 AMD 在 linux 下是非常有前途的技术,虽然我还没有拿到他们的卡。
  • 就我而言,我做了#undef CL_VERSION_2_0,现在一切正常。谢谢!我仍然必须添加 CL_USE_DEPRECATED_OPENCL_X_X_APIS 定义。
【解决方案2】:

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

#define CL_USE_DEPRECATED_OPENCL_1_1_APIS

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

【讨论】:

  • 我一到我的另一台电脑上就试一试,那里有源代码。编译错误是关于clRetainDeviceclReleaseDevice,它们都是OpenCL 1.2相关函数。当我分析代码时,看起来它们可以被CL_VERSION_1_1 禁用,但我也会尝试你建议的标志。
  • 很遗憾没有,设置标志并没有阻止标头尝试链接到clRetainDevice()clReleaseDevice()。不过我会进一步调查。
【解决方案3】:

我已经厌倦了下载英特尔、Nvidia 和 AMD 的几个 GB OpenCL SDK,但存在不同的问题:

  • 英特尔需要注册并拥有临时许可证。
  • Nvidia SDK 不支持 OpenCL 2.0,您必须下载 cl.hpp。
  • AMDs cl.hpp 文件定义了可能与 MSVC 的 min 和 max 宏冲突的 min 和 max 宏(我花了太多时间来弄清楚如何使用 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

请注意,您不再需要(也不应该)包含 &lt;CL/opencl.h&gt;

最后,在#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。

【讨论】:

  • 一定会看看的。非常感谢!
  • 看到有人真的像个男人一样挑战这个障碍真是令人耳目一新!
【解决方案4】:

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

【讨论】:

  • 我的反应:哦,好吧,对 nVidia 卡所有者来说太糟糕了。我更愿意使用像 OpenCL 这样的开放、可移植、易于理解的技术,而不是像 CUDA 这样的死胡同、专有框架。
【解决方案5】:

你可以调用可以设置clBuildProgram的选项如下

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

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

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

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    相关资源
    最近更新 更多