Using a barrier causes a CL_INVALID_WORK_GROUP_SIZE error

Mic*_*ner 0 reduction opencl jocl

If I use a barrier (no matter if CLK_LOCAL_MEM_FENCE or CLK_GLOBAL_MEM_FENCE) in my kernel, it causes a CL_INVALID_WORK_GROUP_SIZE error. The global work size is 512, the local work size is 128, 65536 items have to be computed, the max work group size of my device is 1024, I am using only one dimension. For Java bindings I use JOCL. The kernel is very simple:

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)
}
Run Code Online (Sandbox Code Playgroud)

I run the kernel on the Intel(R) Xeon(R) CPU X5570 @ 2.93GHz and can use OpenCL 1.2. The calling method looks like

kernel.putArg(aCLBuffer).putArg(bCLBuffer).putArg(elementCount).putNullArg(localWorkSize);
queue.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize);
Run Code Online (Sandbox Code Playgroud)

But the error is always the same:

[...]can not enqueue 1DRange CLKernel [...] with gwo: null gws: {512} lws: {128} 
cond.: null events: null [error: CL_INVALID_WORK_GROUP_SIZE]
Run Code Online (Sandbox Code Playgroud)

What I am doing wrong?

jpr*_*ice 6

这是某些OpenCL平台上的预期行为.例如,我的苹果系统上,则CPU装置具有1024的最大工作组大小然而,如果内核内部具有阻挡,则该特定的内核的最大工作组大小减小到1.

您可以使用clGetKernelWorkGroupInfoCL_KERNEL_WORK_GROUP_SIZE参数的函数来查询特定内核的最大工作组大小.返回的值将不超过由返回的值更clGetDeviceInfoCL_DEVICE_MAX_WORK_GROUP_SIZE,但是被允许要少(因为它是在这种情况下).

  • @Cicada OpenCL规范允许特定内核的最大工作组大小小于设备的最大值.出于其他原因,这种情况经常发生 - 如果您的内核在GPU上使用大量寄存器,则可以减少最大工作组大小.通过'预期行为',我的意思是允许行为,并且已知一些平台可以做到这一点.我同意这对开发人员来说很痛苦,因为它确实意味着你不能做任何有用的同步. (3认同)
  • @Cicada是的,它基本上意味着实现者无法为该特定平台实现任何同步.这可能意味着每个工作项都映射到不同的线程,这会使同步变得昂贵.其他CPU实现将一个work-*group*映射到一个线程上,然后在该线程中序列化工作项执行,这使同步变得更容易和更便宜. (3认同)
  • @Cicada是的,英特尔的实现确实这样做,整个工作组在一个线程内执行.我怀疑OP正在使用Apple的OpenCL实现,这不是那么聪明. (2认同)
  • @jprice我在多个平台上试验自己,我知道内核WG大小有时更小(寄存器等).但是我从来没有遇到过它会是1的情况.我认为这只适用于CPU OpenCL仿真.但是,对于一个好的做法,开发人员应该始终读取API提供的值,并计算考虑到这一点的最佳大小.这是对多平台进行内核调整的好方法. (2认同)