OpenCL:基本示例不起作用。clSetKernelArg-38错误

OpenCL:基本示例不起作用。clSetKernelArg-38错误,opencl,Opencl,我正在尝试一个非常简单的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

我正在尝试一个非常简单的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
}
#定义CL_HPP_启用_异常
#定义CL_HPP_目标_OPENCL_版本200
#包括
#定义多行字符串(ARG)#ARG
名称空间操作
{
const char*resizeAndMergeKernel=多行字符串(
__内核void testKernel(u全局浮点*映像)
{
}
);
}
void testCL(){
cl::装置;
语境;
cl::命令队列;
int deviceId=0;
//加载装置
向量平台;
std::矢量设备;
std::string deviceName;
cl_uint i,类型;
cl::平台::获取(&platforms);
类型=平台[0]。获取设备(CL\U设备\U类型\U GPU和设备);
if(type==CL_SUCCESS)
{
//仅获取相关设备
cl::Context-allContext(设备);
std::向量gpuDevices;
gpuDevices=allContext.getInfo();
bool deviceFound=假;

对于(int i=0;i它不是一个“崩溃”,而是一个错误代码。OpenCL error-38是CL_INVALID_MEM_对象。这意味着CL_MEM_对象无效。这是因为您将CL::Buffer对象传递给setArg,但您需要传递表示该缓冲区的CL_MEM句柄。CL::Buffer操作符()方法返回该对象。因此使用
kernel.setArg(0,x())
。注意,
()
是添加的部分(是的,它很微妙)。

是的,还有我创建了一个cl::程序而没有传递上下文的事实