c++ - 如何使用 OpenCL C++ 绑定获得最大的全局工作大小?
问题描述
我想获得最大的全球工作规模。我不希望内核 OpenCL 会尝试为您选择最好的内核,这可能是也可能不是最大尺寸。
为此,我想在调用时指定大小clEnqueueNDRangeKernel
。例如:
clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size, NULL, 0, NULL, NULL);
clGetKernelWorkGroupInfo 文档,指出:
CL_KERNEL_GLOBAL_WORK_SIZE :这为应用程序提供了一种机制来查询可用于在 device 给出的自定义设备上执行内核的最大全局大小(即 clEnqueueNDRangeKernel 的 global_work_size 参数)或由 device 给出的 OpenCL 设备上的内置内核.
如何CL_KERNEL_GLOBAL_WORK_SIZE
使用 OpenCL C++ 绑定?
我这样做
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];
解决方案
是的,因为您的电话与签名匹配:
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
. 那将是标题中的错误。(由 OP 创建的 GitHub 问题)
或者,您可以使用返回错误代码的版本以及通过输出参数提供的信息,这应该可以解决该问题:
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 了吗?
[...] 在设备给定的自定义设备上或在设备给定的 OpenCL 设备上的内置内核上。
如果 device 不是自定义设备或内核不是内置内核,则 clGetKernelArgInfo 返回错误 CL_INVALID_VALUE。
请参阅OpenCL 1.2 规范,第 14 和 15 页:
内置内核:内置内核是通过固定功能硬件或固件在 OpenCL 设备或定制设备上执行的内核。应用程序可以查询设备或自定义设备支持的内置内核。程序对象只能包含用 OpenCL C 编写的内核或内置内核,但不能同时包含两者。另请参见内核和程序。
定制设备:完全实现 OpenCL 运行时但不支持用 OpenCL C 编写的程序的 OpenCL 设备。定制设备可能是专门的非可编程硬件,它对于定向任务或具有有限可编程能力的硬件非常节能和高性能,例如专门的 DSP。自定义设备不符合 OpenCL。定制设备可能支持在线编译器。可以使用 OpenCL 运行时 API 创建自定义设备的程序,这些 API 允许从源代码(如果支持在线编译器)和/或二进制文件或设备支持的内置内核创建 OpenCL 程序。另见设备。
对于常规内核和设备,标准限制了工作组大小(设备属性),而全局大小仅受使用的范围限制size_t
。请参阅clEnqueueNDRangeKernel。
推荐阅读
- android - Android Drawable Blur DropShadow
- php - Google 回调 url 返回在 Laravel Socialite 中找不到的页面
- php - Nova 排队操作
- php - 在 PHP 8.0.5 上的 WSL Ubuntu 中启用 pdo_mysql.so
- reactjs - react-slick 的错误行为
- mysql - Liquibase 连接在本地失败 [拒绝访问用户'root'@'172.18.0.1']
- kotlin - 如何在 ktor 中自动生成 swagger doc,或者如何在 ktor 中编写 api doc
- vue.js - Vue3 / Vite:如何打包组件以在 npm 上发布
- reactjs - 如何根据 JS 对象的属性强制 React 组件重新渲染?
- php - 在 MySQL 中每隔 n 小时获取一次订单