【问题标题】:OpenCL Write back on the bufferOpenCL 回写缓冲区
【发布时间】:2023-03-21 06:26:02
【问题描述】:

当我尝试在主机缓冲区上写回 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...

【问题讨论】:

    标签: c++ opencl


    【解决方案1】:

    我在您的代码中看到两件事对我来说非常可疑:

    1. enqueueNDRangeKernel() 的调用,尤其是使用cl::NDRange(sizeof(cl_mem)) 来指定全局工作项维度的数组...AFAICT,这没有任何意义,但我很可能会错过一些东西在这里。

    2. 在内核本身中使用临时数组:在我看来很像你忘记声明它们local。会是这样吗?如果是这样,您需要在初始化部分之后添加barrier(CLK_LOCAL_MEM_FENCE)

    无论如何,我的感觉是,您的代码适用于大小为 256 的工作组,local 内存用于临时数组。我可能错了,但无论如何,内核的运行方式和逻辑都存在问题。

    【讨论】:

      猜你喜欢
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 2015-03-10
      • 2016-09-16
      相关资源
      最近更新 更多