【问题标题】:opencl clCreateImage clCreateImage2Dopencl clCreateImage clCreateImage2D
【发布时间】:2014-02-03 18:14:21
【问题描述】:

我是 C++ 的 OpenCl 新手,我正在尝试创建一个图像的 cl_mem,但我无法让它工作:

首先我像这样使用 clCreateImage2D:

Mat image=imread("pic.jpg",CV_32FC1);
int width = image.rows;
int height = image.cols;

char *buffer = reinterpret_cast<char *>(image.data);

cl_image_format clImageFormat;
    clImageFormat.image_channel_order = CL_INTENSITY ;
    clImageFormat.image_channel_data_type = CL_FLOAT;
cl_mem Image2DBuffer =clCreateImage2D(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &clImageFormat, width,height,0,buffer,&error);

但它没有编译,Visual Studio 2012 给了我这个错误:“error C4996: 'clCreateImage2D': was declared deprecated”。

我寻找了一个解决方案,我发现 OpenCL 1.2 已经将 clCreateImage2D 和 clCreateImage3D 替换为 clCreateImage(或者至少我是这么理解的),所以我更改了以下代码:

cl_image_desc image_desc;
    image_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
    image_desc.image_width = width;
    image_desc.image_height = height;
    image_desc.image_array_size = 1;
    image_desc.image_row_pitch = 0;
    image_desc.image_slice_pitch = 0;
    image_desc.num_mip_levels = 0;
    image_desc.num_samples = 0;
    image_desc.buffer = NULL;

cl_mem ImageBuffer=clCreateImage(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &clImageFormat, &image_desc, buffer,&error);

但程序在最后一行崩溃(未处理的异常在 0x0000000000000000),我不知道为什么。

如果有人能提供帮助,我将不胜感激。我想我写了您可能需要了解问题的所有内容,但如果缺少某些内容,请告诉我,我会提供额外信息。

【问题讨论】:

  • 你声明和分配错误了吗?图像是否正确打开?上下文是否正确初始化?
  • 另外,您的数据是 char* 但 clImageFormat 设置为 CL_FLOAT
  • 两个可能有帮助的问题:(1)image_desc 的配置方式,看起来您正在将长度为 1 的 image2d_array_t 传递到内核中。这是你打算做的吗? IE。您的内核签名是否包含image2d_array_t 参数?如果它只是一个 image2d_t(我期望基于您的初始代码),则 image_array_size 应在 image_desc 中设置为 0。在某些情况下,传输 1 个 image2d_t 类型甚至可能比大小为 1 的 image2d_array_t 更快。(2)您是否在 Nvidia 硬件上运行但使用来自 AMD/Intel 的标头 - 支持 OpenCL1.2,而 Nvidia 不支持?
  • 如果您使用的设备是 OpenCL 1.1,那么使用 clCreateImage 会崩溃。在使用 1.2 API 之前,您必须检查设备是否为 1.2。如果您使用混合设备,使用 1.1 API 会更安全。您可以在 #include cl.h 之前设置一个 #define 来启用 1.1 API(我很惊讶它们已经被标记为不推荐使用)。

标签: c++ image opencl


【解决方案1】:

以下代码适用于 VS12、AMD APP SDK v2。使用第一个分配标志,我的 GPU 使用共享内存,所以我选择 CL_MEM_ALLOC_HOST_PTR。

//Let image constructor select row pitch
std::size_t row_pitch = 0, rows = 768, cols = 1024;

Mat image(rows, cols, CV_32F, cv::Scalar(0.0f));
try{
    cl::Image2D img(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, cl::ImageFormat(CL_LUMINANCE, CL_FLOAT), image.cols, image.rows, row_pitch, (void*)image.data);
}catch(cl::Error &e){
    cerr <<e.what()<<endl;
}

【讨论】:

    【解决方案2】:

    clCreateImage 是 1.2 函数。

    如果您的设备仅支持 opencl 1.1,则应使用 clCreateImage2D 或 clCreateImage3D 并包含 1.1 CL 文件夹。

    如果在不支持1.2的设备中使用clCreateImage函数,应用程序在运行时会崩溃。

    如果你使用 clCreateImage2D 或 clCreateImage3D 不包含 1.1 CL 文件夹将编译错误。

    【讨论】:

      【解决方案3】:

      我觉得你应该设置

      image_desc.image_row_pitch = width *channel;
      image_desc.image_slice_pitch =  width *channel*height;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-05
        • 1970-01-01
        • 2014-06-15
        • 2018-05-16
        • 2017-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多