【问题标题】:How do you represent pixel coordinates as a 1D array?你如何将像素坐标表示为一维数组?
【发布时间】:2013-07-25 01:59:51
【问题描述】:

我正在关注Heterogeneous Computing with OpenCL,这让我悬而未决。

他们将图像作为浮点数组传递给 enqueueWriteBuffer。我认为在这种情况下,图像没有颜色值。它只是 {col,row,col,row,col,row} 例如{0,0,0,1,0,2,1,0,1,1,1,2...}。

但是当他们执行 enqueueReadBuffer 时,他们期望的大小是 HW,如果你要像我刚才那样做一个数组,那么数组大小将是 HW*2。

// SETUP BUFFERS
Buffer d_ip = Buffer(context, CL_MEM_READ_ONLY, W*H*sizeof(float));
Buffer d_op = Buffer(context, CL_MEM_WRITE_ONLY, W*H*sizeof(float));
queue.enqueueWriteBuffer(d_ip, CL_TRUE, 0, W*H*sizeof(float), img); //img, what is img? the book just says it is my image.

// SETUP RANGES
NDRange globalws(W, H);
NDRange localws(16, 16);

// QUEUE AND READ
queue.enqueueNDRangeKernel(rotn_kernel, NullRange, globalws, localws);
queue.enqueueReadBuffer(d_op, CL_TRUE, 0, W*H*sizeof(float), img);

// X AND Y INSIDE THE KERNEL
const int x = get_global_id(0);
const int y = get_global_id(1);

如果所有新的像素坐标都在内核中计算,你不能只传递一个适当大小的空浮点数组(WH 显然,虽然我不明白它为什么不是 W em>H*2)。但后来我尝试对它进行硬编码(在 500x300 图像上),结果我的堆栈爆炸了。

【问题讨论】:

    标签: opencl


    【解决方案1】:

    这不是W*H*2 的大小,因为它们可能不像您想象的那样存储数据。通常,存储这种性质的数据时,数据的第一行存储在第一个W 条目中,第二行存储在第二个W 中,依此类推;这会产生一个大小为W*H 的数组。因此,要在行X、列Y 中获取有关某些内容的信息,您必须获取索引(W * X) + Y 处的元素

    【讨论】:

    • 这是有道理的。我想可能是这样的。我注意到代码中有很多 WH 和 sizeof(AB*C) 重复。我想每次都必须计算而不是将其存储在变量中,这对性能影响不大。
    • @user1873073 你是对的,这不会对性能造成重大影响,因为乘法和加法是快速运算,并且您每次都要进行一定数量的计算。因此,这个计算可以说在O(1)时间内完成,不会影响渐近运行时间。因此,您拥有高效的内存使用和可预测、合理的运行时间
    【解决方案2】:

    在编写我的 OpenCL 代码时,我总是将每个内核视为读取一组 3D 数据,无论数据是 1D、2D 还是 3D:

     __kernel void TestKernel(__global float *Data){
          k = get_global_id(0); //also z
          j = get_global_id(1); //also y
          i = get_global_id(2); //also x
    
          //Convert 3D to 1D
          int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k;
    
          //do stuff
     }
    

    在执行 clEnqueueNDKernelRange(...) 时,只需将维度设置为:

     int X = 500;
     int Y = 300;
     int Z = 1;
    
     size_t GlobalDim = {Z, Y, X};
    

    这让我的所有内核都可以在各个维度上轻松工作。

    您的代码没有调用任何clSetKernelArg,您添加了这些吗? OpenCL 函数是否会回退任何错误?您可能想退后一步,使用 OpenCL C 代码而不是 C++ 类。

    【讨论】:

    • 这很聪明。我喜欢。 ...我确实有所有其他代码。我刚刚发布了一个摘要,试图让大家明白这一点。
    • 我仍然建议您尝试 C 版本的 OpenCL 调用,直到您对所有内容都更加熟悉为止。你的代码有错误检查吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多