我是OpenCL的新手,一直在尝试在内核函数中实现3级嵌套循环。猜猜我的理解还不够。下面是逻辑的C代码
void scale(float *output, float *scales, int batch, int n, int size)
{
int i,j,b;
for(b = 0; b < batch; ++b){
for(i = 0; i < n; ++i){
for(j = 0; j < size; ++j){
output[(b*n+i)*size+j] *= scales[i];
}
}
}
}
output
和scales
是1D数组。例如:
float output[18] = {1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
float scales[9] = {1,0,1,0,1,0,1,0,1};
int n = 9;
int size = 2;
int batch = 1;
预期输出为输出:
1.000000 2.000000 0.000000 0.000000 5.000000 6.000000
0.000000 0.000000 9.000000 1.000000 0.000000 0.000000
4.000000 5.000000 0.000000 0.000000 8.000000 9.000000
下面是我的OpenCL内核
__kernel void scale_kernel(__global float *output, __global float *biases, int n, int size)
{
int j = get_global_id(0);
int i = get_group_id(1);
int b = get_group_id(2);
if(j < size) output[(b*n+i)*size + j] *= biases[i];
}
我希望这个实现是正确的,我启动NDkernel的方式是错误的。我的BLOCK大小是16(想想这是我理解错误的地方)。
size_t global_work_size[3] = {size-1)/BLOCK + 1, n, batch};
size_t local_work_size[3] = {BLOCK, 1, 1};
cl.error = clEnqueueNDRangeKernel(queue, kernel, 3, 0, global_work_size, local_work_size, 0, 0, NULL);
编辑1:
如下所示更改global_work_size会产生预期的输出,在这种情况下我将local_work_size设置为NULL。这可能无法提供最佳性能。
size_t global_work_size[3] = {size, n, batch};
cl.error = clEnqueueNDRangeKernel(queue, kernel, 3, 0, global_work_size, NULL, 0, 0, NULL);
请让我知道如何选择global_work_size,local_work_size。