我在理解 OpenCL 2D 工作组维度时遇到问题。
我想创建一个 N x N 矩阵并将每一行分配给一组工作组进行计算。 例如,如果我有一个 1000 x 1000 矩阵,我希望每行有 10 个工作组(因此每个工作组将计算 100 个元素),总共有 10000 个工作组 (10 * 1000)。
这是我的一段代码:
size_t global_pattern[] = {n,n,0}; //My matrix pattern
size_t group_pattern[] = {workgroups_per_row, n, 0}; //My workgroups pattern
下面是一些行:
err = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_pattern,
group_pattern, 0, NULL, NULL);
失败了。错误代码是-54,引用#define CL_INVALID_WORK_GROUP_SIZE -54。
我对 group_pattern 数组的初始化正确吗?我的意思是,数组的第一个元素是否像我假设的那样指的是 x 坐标,第二个元素指的是 y 坐标? 背后的数学原理是什么?
出于调试目的,我还尝试使用空内核运行它(只是为了确保这不是我的代码问题)。我还尝试交换 group_pattern 数组中的第一个和第二个元素。
最佳答案
当你说:
size_t global_pattern[] = {n,n,0}; //My matrix pattern
size_t group_pattern[] = {workgroups_per_row, n, 0}; //My workgroups pattern
然后像这样使用它:
err = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_pattern, group_pattern, 0, NULL, NULL);
这显然是错误的。您必须传递给内核的是 local_size
AKA,即一组的大小。不是你想如何分割你的空间。
所以对于你的情况来说是这样的:
size_t global_size[] = {n,n}; //My matrix pattern
size_t group_pattern[] = {workgroups_per_row, n}; //My workgroups pattern
size_t local_size[] = {global_size[0]/group_pattern[0], global_size[1]/group_pattern[1]}; //My workgroups pattern
err = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_pattern, local_size, 0, NULL, NULL);
编辑:如果您有 CL_INVALID_WORK_GROUP_SIZE,那么原因可能是:
- 您指定的局部大小不是全局大小的整数除数
- 设备不支持您定义的本地大小
关于arrays - OpenCL 2D 工作组尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20655668/