我正在尝试一个非常简单的OpenCL示例。我在下面开发了以下代码。它编译一个简单的内核,然后我创建一个简单的float *缓冲区并将其设置为cl :: Buffer。但是,当我尝试调用kernel.setArg()函数时,它会崩溃,错误为-38。此错误表明我的cl :: Buffer无效。我不知道为什么会这样:
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 200
#include <CL/cl2.hpp>
#define MULTI_LINE_STRING(ARG) #ARG
namespace op
{
const char *resizeAndMergeKernel = MULTI_LINE_STRING(
__kernel void testKernel(__global float* image)
{
}
);
}
void testCL(){
cl::Device device;
cl::Context context;
cl::CommandQueue queue;
int deviceId = 0;
// Load Device
std::vector<cl::Platform> platforms;
std::vector<cl::Device> devices;
std::string deviceName;
cl_uint i, type;
cl::Platform::get(&platforms);
type = platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &devices);
if( type == CL_SUCCESS)
{
// Get only relavent device
cl::Context allContext(devices);
std::vector<cl::Device> gpuDevices;
gpuDevices = allContext.getInfo<CL_CONTEXT_DEVICES>();
bool deviceFound = false;
for(int i=0; i<gpuDevices.size(); i++){
if(i == deviceId){
device = gpuDevices[i];
context = cl::Context(device);
queue = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE);
deviceFound = true;
cout << "Made new GPU Instance: " << deviceId << endl;
break;
}
}
if(!deviceFound)
{
throw std::runtime_error("Error: Invalid GPU ID");
}
}
// Create Kernel
cl::Program program = cl::Program(context, op::resizeAndMergeKernel, true);
cl::Kernel kernel = cl::Kernel(program, "testKernel");
// Simple Buffer
cl_int err;
float* test = new float[3*224*224];
cl::Buffer x = cl::Buffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(float) * 3 * 224 * 224, (void*)test, &err);
cout << err << endl;
kernel.setArg(0,x); // CRASHES WITH cl::Error -38
}
正如您所见,最后一行kernel.setArg(0,x)崩溃,错误为-38。
答案 0 :(得分:1)
它不是&#34;崩溃&#34;,它是一个错误代码。 OpenCL错误-38是CL_INVALID_MEM_OBJECT。这意味着cl_mem_obj无效。这是因为您将cl :: Buffer对象传递给setArg,但您需要传递代表该缓冲区的cl_mem句柄。 cl :: Buffer operator()方法返回该值。所以使用kernel.setArg(0,x())
。请注意()
是添加的部分(是的,它很微妙)。