OpenCL:clSetKernelArg返回CL_INVALID_ARG_SIZE

时间:2016-04-29 19:50:02

标签: c++ opencl

我是OpenCL的新手。我正在尝试将5个参数传递给内核:输入缓冲区,输出缓冲区,整数和2个输入缓冲区大小的本地数组。

//Create input/output cl_mem objects
cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY |
    CL_MEM_COPY_HOST_PTR, inputVector.size(), (void *)inputVector.data(), NULL);
cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY,
    inputVector.size(), NULL, NULL);

//get iterator from command line
cl_uint iterations = (cl_uint) atoi(argv[3]);
//std::cout << "iterations: " << iterations << std::endl
//cout confirms I'm getting this correctly

//Set kernel arguments
bool argOK = (CL_SUCCESS == clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&inputBuffer));
argOK = argOK && (CL_SUCCESS == clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&outputBuffer));
argOK = argOK && (CL_SUCCESS == clSetKernelArg(kernel, 2, sizeof(cl_uint), &iterations));
argOK = argOK && (CL_SUCCESS == clSetKernelArg(kernel, 3, sizeof(inputBuffer), NULL));
argOK = argOK && (CL_SUCCESS == clSetKernelArg(kernel, 4, sizeof(inputBuffer), NULL));
//Check for failure
if(!argOK) {
    std::cerr << "Error: clSetKernelArg failed\n";
    return SDK_FAILURE;
}

当我运行该程序时,它会打印:

Error:  clSetKernelArg failed

我做了一些挖掘/调试,最终发现这一行:

argOK = argOK && (CL_SUCCESS == clSetKernelArg(kernel, 2, sizeof(cl_uint), &iterations));

是罪魁祸首。将其更改为:

argOK = argOK && (CL_INVALID_ARG_SIZE == clSetKernelArg(kernel, 2, sizeof(cl_uint), &iterations));

让程序继续成功。 因此,clSetKernelArg(kernel,2,...)语句返回CL_INVALID_ARG_SIZE。虽然它很奇怪,因为它看起来像是为迭代变量传递了正确的大小。

这是我的内核供参考:

__kernel void do_the_thing (__global uchar* in, __global uchar* out,
    __global uint * numIterations, __local uchar* arr1, __local uchar* arr2)
{
    //Do stuff that I haven't written yet.  

}

TL; DR:为什么setKernelArg调用返回CL_INVALID_ARG_SIZE?

1 个答案:

答案 0 :(得分:3)

内核的第三个参数(index = 2)是一个缓冲区(__global uint *)而不是cl_uint标量。

将内核更改为:

__kernel void do_the_thing (__global uchar* in, __global uchar* out, uint numIterations, __local uchar* arr1, __local uchar* arr2)
{
     //Do stuff that I haven't written yet.  

}