如果我在内核中使用屏障(无论CLK_LOCAL_MEM_FENCE
还是CLK_GLOBAL_MEM_FENCE
),则会导致CL_INVALID_WORK_GROUP_SIZE
错误。全局工作大小为512,本地工作大小为128,必须计算65536个项目,我的设备的最大工作组大小为1024,我只使用一个维度。对于Java绑定,我使用JOCL。
内核非常简单:
kernel void sum(global float *input, global float *output, const int numElements, local float *localCopy
{
localCopy[get_local_id(0)] = grid[get_global_id(0)];
barrier(CLK_LOCAL_MEM_FENCE); // or barrier(CLK_GLOBAL_MEM_FENCE)
}
我在Intel(R) Xeon(R) CPU X5570 @ 2.93GHz
上运行内核,可以使用OpenCL 1.2。调用方法看起来像
kernel.putArg(aCLBuffer).putArg(bCLBuffer).putArg(elementCount).putNullArg(localWorkSize);
queue.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize);
但错误总是一样的:
[...]can not enqueue 1DRange CLKernel [...] with gwo: null gws: {512} lws: {128}
cond.: null events: null [error: CL_INVALID_WORK_GROUP_SIZE]
我做错了什么?
答案 0 :(得分:6)
这是某些OpenCL平台上的预期行为。例如,在我的Apple系统上,CPU设备的最大工作组大小为1024.但是,如果内核中有一个屏障,那么该特定内核的最大工作组大小将减少到1.
您可以使用带有clGetKernelWorkGroupInfo
参数的CL_KERNEL_WORK_GROUP_SIZE
函数查询特定内核的最大工作组大小。返回的值不会超过clGetDeviceInfo
和CL_DEVICE_MAX_WORK_GROUP_SIZE
返回的值,但允许更小(在这种情况下)。