【问题标题】:c++ opencl return CL_OUT_OF_RESOURCESc++ opencl return CL_OUT_OF_RESOURCES
【发布时间】:2016-01-23 06:01:24
【问题描述】:

我正在学习 OpenCL 并尝试在图片上应用黑白,但 enqueueNDRangeKernel 返回 CL_OUT_OF_RESOURCES,我不明白为什么。 OpenCL 在 GTX 980M 和 OpenCL 1.2 上运行。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <CL/cl.hpp>


#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_write.h"

int main() {

    unsigned int vectorSize = 1000;
    const std::string progCode = "__kernel                                   \n"
                            "void img_kernel( __read_only image2d_t inputImage, __write_only image2d_t outputImage) \n"
                            "{                                                                                             \n"
                            "const sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; \n"
                            "    int width = get_image_width(inputImage);                                                      \n"
                            "    int height = get_image_height(inputImage);                                                    \n"
                            "    int2 pixelcoord = (int2) (get_global_id(0), get_global_id(1));                            \n"
                            "    float4 pixel = read_imagef(inputImage, sampler, pixelcoord);                         \n"
                            "    float color = (pixel.x + pixel.y + pixel.z)/3;                                            \n"
                            "    float4 outColor = (float4)(pixel.x,pixel.y,pixel.z, 1.0);                                    \n" 
                            "    write_imagef(outputImage, pixelcoord, outColor);          }                                     \n";
    int imageX, imageY, imageN;
    unsigned char *dataImage = stbi_load("test.jpg", &imageX, &imageY, &imageN, 3);
    if (dataImage == nullptr)
    {
        std::cout << "Unable to load picture" << std::endl;
        getchar();
        return 1;
    }

    cl_int  error;

    std::vector<cl::Platform> platformsList;
    error = cl::Platform::get(&platformsList);
    if (error != CL_SUCCESS) 
    {
        std::cout << "Unable to find any OpenCL platforms" << std::endl;
        getchar();
        return 1;
    }


    std::vector<cl::Device> devicesList;
    error = platformsList[0].getDevices(CL_DEVICE_TYPE_DEFAULT, &devicesList);
    if (error != CL_SUCCESS) 
    {
        std::cout << "Unable to find any OpenCL device" << std::endl;
        getchar();
        return 1;
    }

    cl::Device currentDevice = devicesList[0];
    std::string nameDevice, driverDevice;
    error = currentDevice.getInfo(CL_DEVICE_NAME, &nameDevice);
    error = currentDevice.getInfo(CL_DRIVER_VERSION, &driverDevice);
    std::cout << "Device : " << nameDevice << "   " << driverDevice << std::endl;;

    cl::Context context(currentDevice);

    cl::Program::Sources source;
    source.push_back({ progCode.c_str(), progCode.size() });
    cl::Program program(context, source);
    if (program.build({ currentDevice }) != CL_SUCCESS)
    {
        std::cout << " Error building: " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(currentDevice) << "\n";
        getchar();
        exit(1);
    }

    cl::ImageFormat globalImgFormat; 
    globalImgFormat.image_channel_data_type = CL_UNSIGNED_INT8;
    globalImgFormat.image_channel_order = CL_RGB;

    cl::size_t<3> origin;
    origin[0] = 0; origin[1] = 0, origin[2] = 0;
    cl::size_t<3> region;
    region[0] = imageX; region[1] = imageY; region[2] = 1;



    cl::Image2D inputImage(context, CL_MEM_READ_ONLY, globalImgFormat, imageX, imageY, 0, dataImage, &error);
    if (error != CL_SUCCESS) 
    {
        std::cout << "Unable to create cl Image for input." << std::endl;
        getchar();
        return 1;
    }

     cl::Image2D outputImage(context, CL_MEM_WRITE_ONLY, globalImgFormat, imageX, imageY, 0, nullptr, &error);
     if (error != CL_SUCCESS)
    {
        std::cout << "Unable to create cl Image for output." << std::endl;
        getchar();
        return 1;
    }

    cl::CommandQueue queue(context, currentDevice);


    cl::Kernel image_kernel(program, "img_kernel", &error);
    if (error != CL_SUCCESS)
    {
        std::cout << "Unable to create kernel." << std::endl;
        getchar();
        return 1;
    }

    error = image_kernel.setArg(0, inputImage);
    if (error != CL_SUCCESS)
    {
        std::cout << "Unable to set param." << std::endl;
        getchar();
        return 1;
    }
    error = image_kernel.setArg(1, outputImage);
    if (error != CL_SUCCESS)
    {
        std::cout << "Unable to set param." << std::endl;
        getchar();
        return 1;
    } 

    cl::NDRange globalSize(imageX, imageY);


    error = queue.enqueueNDRangeKernel(image_kernel, cl::NullRange, globalSize, cl::NullRange);
    if (error != CL_SUCCESS)
    {
        std::cout << "Unable to compute Image data." << std::endl;
        getchar();
        return 1;
    }
    queue.finish(); 



    unsigned char *resultPros = new unsigned char[imageX * imageY * imageN];
    error = queue.enqueueReadImage(outputImage, CL_TRUE, origin, region, 0, 0, resultPros);
    stbi_write_bmp("testresul.jpg", imageX, imageY, imageN, resultPros);


    stbi_image_free(dataImage);
    stbi_image_free(resultPros);
    getchar();
    return 0;
}

【问题讨论】:

  • 您确定imageXimageY 的值已正确初始化吗?顺便说一句,nVidia OpenCL 实施充满了他们没有故意修复的错误,因为他们希望人们使用 CUDA。这就是为什么没有什么能让你感到惊讶的原因......

标签: c++ opencl


【解决方案1】:

在 NVIDIA 硬件上,如果您在缓冲区或图像之外写入(这是一个未定义的操作),则 CL_OUT_OF_RESOURCES 是一个常见的错误。它比早期的硬件或驱动程序简单崩溃!仔细检查你的写作。

【讨论】:

    【解决方案2】:

    好像 image_channel_data_type 和 image_channel_order 的组合不正确。您的问题可能与此有关吗?

    请看这里: https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_image_format.html

    问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      相关资源
      最近更新 更多