如何使用OpenCL C ++绑定获得最大的全局工作大小?

时间:2018-04-26 13:38:22

标签: c++ opencl

我想获得最大的全球工作量。 我不希望内核OpenCL会尝试为您选择最合适的内核,可能是或不是最大尺寸。

要执行此操作,我想在调用clEnqueueNDRangeKernel时指定大小。 e.g:

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

clGetKernelWorkGroupInfo documentation,表示:

CL_KERNEL_GLOBAL_WORK_SIZE:这为应用程序提供了一种机制,用于在设备或内置内核给出的自定义设备上查询可用于执行内核的最大全局大小(即clEnqueueNDRangeKernel的global_work_size参数)设备提供的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];

1 个答案:

答案 0 :(得分:2)

是的,因为您的电话符合签名:

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声明通过宏生成的template<typename T> cl_int getWorkGroupInfo(const Device &device, cl_kernel_work_group_info name, T *param) const; 。这将是标题中的错误。 (GitHub issue created by OP

对于某些条目 here 缺少条目 here

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

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

通话看起来像:

size_t

我的问题是:你自己尝试过吗?结果不符合您的期望吗?

您收到了CL_INVALID_VALUE吗?

  

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

     

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

OpenCL 1.2 spec,第14和15页:

  

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

     

自定义设备:完全实现OpenCL运行时但未完全实现OpenCL设备的OpenCL设备   支持用OpenCL C编写的程序。自定义设备可能是专用的   可编程硬件,非常节能,适用于定向任务或   具有有限可编程功能的硬件,如专用DSP。定制设备是   不符合OpenCL标准。自定义设备可能支持在线编译器。程序   可以使用允许OpenCL程序的OpenCL运行时API创建自定义设备   从源(如果支持在线编译器)和/或二进制文件,或从内置内核创建   由设备支持。另见设备。

对于常规内核和设备,标准约束工作组大小(设备属性),而全局大小仅受使用的svc.Port = Randomiser.Next(29700, 29900); <范围限制/ strong>即可。请参阅clEnqueueNDRangeKernel