【问题标题】:C++ OpenCL kernel setArg returns CL_INVALID_ARG_VALUE for __read_only image2d_tC++ OpenCL 内核 setArg 为 __read_only image2d_t 返回 CL_INVALID_ARG_VALUE
【发布时间】:2017-05-15 18:27:39
【问题描述】:

我正在使用 OpenCL(C++ API)迈出我的第一步,步履蹒跚,但我遇到了一个问题,我束手无策,根本不知道可能出了什么问题。设置 image2d_t 内核参数时(参见下面的蒸馏代码),调用抛出并返回错误代码 -50 (= CL_INVALID_ARG_VALUE ),我完全不知道为什么。我正在使用 Intel 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;
}

【问题讨论】:

    标签: c++ opencl


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢,这确实是问题的根源!您是否知道为什么甚至允许没有上下文或设备的呼叫? (如果我设置了一个,我假设它应该使用默认上下文/设备?但是,我不明白为什么如果没有默认值就不会抛出......?)
    • 它将使用默认上下文,如果不存在则创建一个。我同意当我的意思做的事情没有按照你的想法做时,这有点令人困惑。
    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 2020-02-06
    • 1970-01-01
    相关资源
    最近更新 更多