2016-01-22 154 views
2

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

#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; 
} 
+0

你确定'imageX'和'imageY'的值是否被正确初始化?顺便说一句,nVidia OpenCL的实现充满了他们不能故意修复的错误,因为他们希望人们使用CUDA。这就是为什么没有什么会让你感到惊讶 –

回答

0

在NVIDIA的显卡,如果你写一个缓冲或图像(这是一个不确定的操作)之外,那么CL_OUT_OF_RESOURCES是一个常见的错误来获得。它比早期的硬件或驱动程序简单崩溃更好!仔细检查你的写作。