c++ - OpenCL 内核访问 CL_MEM_READ_WRITE,缓冲区

标签 c++ opencl

我正在尝试将 float3 缓冲区 border 用于数据结构。它在使用英特尔 OpenCL SDK 4.4、英特尔 iCore7 的内核执行期间崩溃。不幸的是,我无法找出 3d-index (i, y, x) 到线性索引 adr=WIDTH2*i+WIDTH*y+x 中的任何索引错误然而。我错过了什么?

以下是缓冲区定义(使用 OpenCL C++ 包装器 v1.2):

m_numPixels(width*width),
m_inBuffer(getContext(), CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, 
    sizeof(float)*(width*width), NULL),
m_inBuffer2(getContext(), CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, 
    sizeof(float)*(width*width), NULL),
m_backBuffer(getContext(), CL_MEM_READ_ONLY, 
     sizeof(float)*(width*width), NULL),
m_borderBuffer(getContext(), CL_MEM_READ_WRITE, 
   (3*sizeof(float))*(10*width*width), NULL),
m_outBuffer(getContext(), CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, 
    4*(width*width), NULL),

内核代码如下:

__kernel void computeMedial (__global const float* height, // input height
                 __global const float* height2, // input height, previous frame
                 __global const float* background, // input background
                 __global float3*      border,  // border datastructure
                 __global uchar4*      output,  // output image
                 float thres,
                 uint  width,
                 uint  ls,
                 float scale)
{
    uint   x = get_global_id(0);
    uint   y = get_global_id(1); 
    const uint WIDTH2 = width*width;
    const uint WIDTH  = width;

    // access pixel (x, y)
    float2 c00 = (float2)(x, y);
    float  h00 = array_height(height, height2, width, c00);
    if (x < 4 || x > width-5 || y < 4 || y > width-5) { // border location
      return;
    }
    if (h00 < thres-10 || h00 > thres+10) { // not in thres interval
      return;
    }
    output[y*WIDTH+x] = colorUCHAR(0, y, x); // writing output image   

    // test
    for (uint i=0; i<ls; ++i) { // ls<=7 ok, ls==8/9/10 crashes
      uint   adr  = WIDTH2*i+WIDTH*y+x; 
      border[adr] = (float3)(0);
    } 
}

最佳答案

边框 中存在对齐问题。在 cl_platform.h 中声明:

/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */
typedef  cl_float4  cl_float3;

最好使用 cl_* 类型来避免此类问题,因此您可以按以下方式创建 border 缓冲区:

m_borderBuffer(getContext(), CL_MEM_READ_WRITE, (sizeof(cl_float3))*10*width*width), NULL),

关于c++ - OpenCL 内核访问 CL_MEM_READ_WRITE,缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36224071/

相关文章:

c++ - 与 PVOID 的参数类型不兼容

c++ - 远离 Windows\C++ 中的虚拟内存

buffer - OpenCl 2 : How to convert image2d object to buffer without copy and vice versa

android - 链接共享库 libGLES_mali.so 导致 dlopen 失败 : library "android.hardware...@1.0.so" not found in Android >= 7. 0

c++ - 是否有针对 "conditional expression is constant"的 gcc 警告?

c++ - gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链表循环到自身

c++ - 如何使用 OpenCL 构建 ImageMagick?

c++ - opencl clCreateImage clCreateImage2D

linux - 如何在 Linux 中为 opencl 编程(安装英特尔 OpenCL SDK)准备 eclipse

c++ - 学c++之前需要先学c吗?