C++ OpenCL 内核 setArg returns CL_INVALID_ARG_VALUE for __read_only image2d_t
C++ OpenCL kernel setArg returns CL_INVALID_ARG_VALUE for __read_only image2d_t
我正在使用 OpenCL(C++ API)迈出我的第一个摇摇欲坠的步骤,我 运行 遇到了一个问题,我束手无策,根本不知道可能出了什么问题。设置 image2d_t 内核参数时(请参阅下面的提炼代码),调用会抛出 returns 错误代码 -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;
}
使用上下文创建程序,如下所示:
auto program = cl::Program(context, my_kernel, CL_TRUE);
我正在使用 OpenCL(C++ API)迈出我的第一个摇摇欲坠的步骤,我 运行 遇到了一个问题,我束手无策,根本不知道可能出了什么问题。设置 image2d_t 内核参数时(请参阅下面的提炼代码),调用会抛出 returns 错误代码 -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;
}
使用上下文创建程序,如下所示:
auto program = cl::Program(context, my_kernel, CL_TRUE);