【问题标题】:How to get the maximum global work size with OpenCL C++ bindings?如何使用 OpenCL C++ 绑定获得最大的全局工作大小?
【发布时间】:2018-04-26 13:38:21
【问题描述】:

我想获得最大的全局工作大小。 我不希望内核 OpenCL 会尝试为您选择最好的内核,这可能是也可能不是最大尺寸。

为此,我想在调用clEnqueueNDRangeKernel 时指定大小。 例如:

clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size, NULL, 0, NULL, NULL);

clGetKernelWorkGroupInfo documentation,表示:

CL_KERNEL_GLOBAL_WORK_SIZE :这为应用程序提供了一种机制来查询可用于在 device 给出的自定义设备或内置内核上执行内核的最大全局大小(即 clEnqueueNDRangeKernel 的 global_work_size 参数)一个由 device 提供的 OpenCL 设备。

如何通过 OpenCL C++ 绑定获得CL_KERNEL_GLOBAL_WORK_SIZE

我这样做

cl::array<size_t, 3> kernel_global_work_size = my_kernel.getWorkGroupInfo<CL_KERNEL_GLOBAL_WORK_SIZE>(my_device);

但我得到了错误:

cl2.hpp:5771:12: note: candidate: template<class T> cl_int cl::Kernel::getWorkGroupInfo(const cl::Device&, cl_kernel_work_group_info, T*) const
     cl_int getWorkGroupInfo(
            ^~~~~~~~~~~~~~~~
cl2.hpp:5771:12: note:   template argument deduction/substitution failed:
cl2.hpp:5782:9: note: candidate: template<int name> typename cl::detail::param_traits<cl::detail::cl_kernel_work_group_info, name>::param_type cl::Kernel::getWorkGroupInfo(const cl::Device&, cl_int*) const
         getWorkGroupInfo(const Device& device, cl_int* err = NULL) const

还有这段代码

cl::array<size_t, 3> kernel_global_work_size;
my_kernel.getWorkGroupInfo<cl::array<size_t, 3>>(my_device, CL_KERNEL_GLOBAL_WORK_SIZE, &kernel_global_work_size);

我收到 OpenCL 错误 -30(无效值)

my_kernel 不是内置内核 例如:cl::Kernel my_kernel = cl::Kernel(program, "my_kernel"); my_device 不是自定义设备。 例如:cl::Device device = myDevices[0];

【问题讨论】:

    标签: c++ opencl


    【解决方案1】:

    是的,因为您的调用与签名匹配:

    https://github.khronos.org/OpenCL-CLHPP/classcl_1_1_kernel.html

    template <cl_int name> typename
    detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type getWorkGroupInfo(const Device& device, cl_int* err = NULL) const;
    

    看起来通过宏生成的param_traits 没有为CL_KERNEL_GLOBAL_WORK_SIZE 声明。那将是标题中的错误。 (GitHub issue created by OP)

    对于一些条目 here 缺少条目 here .

    或者,您可以使用返回错误代码的版本以及通过输出参数提供的信息,这应该可以解决该问题:

    template<typename T>
    cl_int getWorkGroupInfo(const Device &device, cl_kernel_work_group_info name, T *param) const;
    

    调用可能如下所示:

    cl::array<size_t, 3> result;
    kernel.getWorkGroupInfo<decltype(result)>(device, CL_KERNEL_GLOBAL_WORK_SIZE, result);
    

    我的问题是:你自己试过了吗?结果不符合你的预期吗?


    您收到 CL_INVALID_VALUE 了吗?

    [...] 在由 device 提供的自定义设备上或在由 device 提供的 OpenCL 设备上的内置内核上。

    如果设备不是自定义设备或内核不是内置内核,clGetKernelArgInfo 会返回错误 CL_INVALID_VALUE。

    参见OpenCL 1.2 spec,第 14 和 15 页:

    内置内核:内置内核是在 OpenCL 设备或自定义设备上执行的内核 设备由固定功能硬件或固件。应用程序可以查询内置内核 由设备或自定义设备支持。程序对象只能包含编写的内核 OpenCL C 或内置内核,但不是两者兼而有之。另请参阅内核和程序。

    自定义设备:完全实现 OpenCL 运行时但不支持的 OpenCL 设备 支持用 OpenCL C 编写的程序。定制设备可能是专门的非 可编程硬件,对于定向任务或 可编程能力有限的硬件,例如专用 DSP。定制设备是 不符合 OpenCL。定制设备可能支持在线编译器。程序为 可以使用允许 OpenCL 程序的 OpenCL 运行时 API 创建自定义设备 从源代码(如果支持在线编译器)和/或二进制文件,或从内置内核创建 设备支持。另请参阅设备。

    对于常规内核和设备,标准限制了工作组大小(设备属性),而全局大小仅受使用的size_t的范围限制 >。见clEnqueueNDRangeKernel

    【讨论】:

    • 是的,我尝试这样cl::array&lt;size_t, 3&gt; kernel_global_work_size = my_kernel.getWorkGroupInfo&lt;CL_KERNEL_GLOBAL_WORK_SIZE&gt;(my_device);,但我得到了错误。 cl_kernel_work_group_info name&T * param是什么意思?
    • 然后请发布错误,并验证您使用的是内置内核还是自定义设备,因为调用将返回CL_INVALID_VALUE else。
    • 使用替代语法的示例调用更新了答案,也许可行。如需进一步分析,请发布一个简单的复制器。
    • 正如您在“如何获取 CL_KERNEL_GLOBAL_WORK_SIZE 值?#43”中所说的(github.com/KhronosGroup/OpenCL-CLHPP/issues/…)这似乎是 cl.hpp 和 cl2.hpp 中的错误。
    • 如前所述,您只能将其用于自定义或内置内核。对于常规内核,它不是有效的调用(并返回 CL_INVALID_VALUE )。您确定您没有考虑最大本地工作组大小(不是全局)吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多