C ++ OpenCL内核setArg为__read_only返回CL_INVALID_ARG_VALUE image2d_t

时间:2017-05-15 18:27:40

标签: c++ opencl

我在OpenCL(C ++ API)中采取了我的第一个,摇摆不定的步骤,并且我遇到了一个问题,我在我的智慧结束时根本不知道什么可能是错的。在设置image2d_t内核参数时(参见下面的蒸馏代码),调用抛出并返回错误代码-50(= CL_INVALID_ARG_VALUE),我完全不知道为什么。我使用的是英特尔OpenCL平台和我的CPU(OpenCL 2.0),并且我能够毫无问题地编译和运行其他示例代码。

#include "stdafx.h"

#include <vector>
#include <string>
#include <iostream>

#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 200

#include <CL/cl2.hpp>

std::string my_kernel = R"(
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE;

__kernel void simple_copy(  __read_only image2d_t input_image
                         , __write_only image2d_t output_image
                         )
{
    int2 coords;
    coords.x = get_global_id(0);
    coords.y = get_global_id(1);

    float4 value = read_imagef(input_image, sampler, coords);
    write_imagef(output_image, coords, value);
})";

int main()
{
    try
    {
        //define source and destination image data
        constexpr unsigned channels = 4, width = 2, height = 2;
        std::array<std::uint8_t, channels*width*height> source = { 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255 };
        std::array<std::uint8_t, channels*width*height> destination{}; //value initialization

        //initialize OpenCL
        std::vector<cl::Platform> platforms;
        cl::Platform::get(&platforms);
        auto platform = platforms.front();
        std::vector<cl::Device> devices;
        platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
        auto device = devices.front();
        auto context = cl::Context(device);
        auto queue = cl::CommandQueue(context, device);

        //create OpenCL image buffers
        auto image_format = cl::ImageFormat(CL_RGBA, CL_UNSIGNED_INT8);
        auto input_image = cl::Image2D(context, CL_MEM_READ_ONLY, image_format, width, height);
        auto output_image = cl::Image2D(context, CL_MEM_WRITE_ONLY, image_format, width, height);

        //transfer source image data to device
        auto origin = cl::array<cl::size_type, 3U>{0, 0, 0};
        auto region = cl::array<cl::size_type, 3U>{width, height, 1};
        queue.enqueueWriteImage(input_image, CL_TRUE, origin, region, 0, 0, &source[0]);

        //compile device code, retrieve kernel, set kernel arguments
        auto program = cl::Program(my_kernel, CL_TRUE);
        auto kernel = cl::Kernel(program, "simple_copy");
        kernel.setArg(0, input_image); //ERROR: throws -50 (= CL_INVALID_ARG_VALUE ) ... why?!
        kernel.setArg(1, output_image);

        //enqueue copy kernel
        queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(width, height), cl::NullRange);

        //read result back to host
        queue.enqueueReadImage(output_image, CL_TRUE, origin, region, 0, 0, &destination[0]);

        //output result
        for (auto const & val : destination)
        {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }
    catch (cl::Error & e)
    {
        std::cout << "caught OpenCL exception - what: " << e.what() << " err: " << e.err() << std::endl;
    }
    std::string str;
    std::getline(std::cin, str);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

使用上下文创建程序,如下所示:

auto program = cl::Program(context, my_kernel, CL_TRUE);