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

时间:2018-01-23 20:21:10

标签: 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>

#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。

1 个答案:

答案 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())。请注意()是添加的部分(是的,它很微妙)。