当我尝试在主机缓冲区上写回opencl代码的输出时,我总是得到一个零/零的数组
这是内核:
void kernel convolution(global const int* A, global const int* B,
global int* C, const int size_1, const int size_2) {
float prob_1[256];
float prob_2[256];
float cum_prob_1[256];
float cum_prob_2[256];
prob_1[get_global_id(0)] = (A[get_global_id(0)]/size_1);
prob_2[get_global_id(0)] = (B[get_global_id(0)]/size_2);
cum_prob_1[0] = prob_1[0];
cum_prob_1[get_global_id(0)+1] = cum_prob_1[get_global_id(0)] + prob_1[get_global_id(0)+1];
cum_prob_2[0] = prob_2[0];
cum_prob_2[get_global_id(0)+1] = cum_prob_2[get_global_id(0)] + prob_2[get_global_id(0)+1];
int j = 0;
for (int i = 0; i < 256; i++) {
if (cum_prob_1[i] <= cum_prob_2[j]) {
C[i] = j;
}
else {
while (cum_prob_1[i] > cum_prob_2[j])
j++;
if (cum_prob_2[j] - cum_prob_1[i] > cum_prob_1[i] - cum_prob_2[j - 1]) {
C[i] = j - 1;
}
else {
C[i] = j;
}
}
}
}
以下是代码的其余部分:
// create buffers on the device
cl::Buffer buffer_A(context, CL_MEM_READ_WRITE, sizeof(int) * 256);
cl::Buffer buffer_B(context, CL_MEM_READ_WRITE, sizeof(int) * 256);
cl::Buffer buffer_C(context, CL_MEM_READ_WRITE, sizeof(int) * 256);
//create queue to which we will push commands for the device.
cl::CommandQueue queue(context, default_device);
//write arrays A and B to the device
queue.enqueueWriteBuffer(buffer_A, CL_TRUE, 0, sizeof(int) * 256, pixls_1);
queue.enqueueWriteBuffer(buffer_B, CL_TRUE, 0, sizeof(int) * 256, pixls_2);
//alternative way to run the kernel
cl::Kernel kernel_add = cl::Kernel(program, "convolution");
kernel_add.setArg(0, buffer_A);
kernel_add.setArg(1, buffer_B);
kernel_add.setArg(2, buffer_C);
kernel_add.setArg(3, size_1);
kernel_add.setArg(4, size_2);
queue.enqueueNDRangeKernel(kernel_add, cl::NullRange, cl::NDRange(sizeof(cl_mem)), cl::NullRange);
queue.finish();
int lookup_table[256];
for (size_t i = 0; i < 256; i++) {
lookup_table[i] = 10;
}
//read result C from the device to array C
queue.enqueueReadBuffer(buffer_C, CL_TRUE, 0, sizeof(int) * 256, lookup_table);
//map the new pixel values from the lookup table
for (int i = 0; i < inp_image.total(); i++) {
myData[i]= lookup_table[myData[i]];
}
system("pause");
return 0;
lookup_table
是给我零/空的,但它应该在所有单元格中给我5
...
答案 0 :(得分:1)
我在你的代码中看到两件非常可疑的事情:
致电enqueueNDRangeKernel()
,特别是使用cl::NDRange(sizeof(cl_mem))
来指定全球工作项维度数组...... AFAICT,这没有任何意义,但是我可能会在这里错过一些东西。
在内核中使用临时数组:它在我看来非常像你忘了声明它们local
。会是这样的吗?如果是这样,您需要在初始化部分之后添加barrier(CLK_LOCAL_MEM_FENCE)
。
无论如何,我的感觉是你的代码用于大小为256的工作组,临时数组有local
内存。我可能错了,但无论如何,内核的运行方式和逻辑也存在问题。