OpenCL:clSetKernelArg 中的 CL_INVALID_ARG_SIZE

OpenCL: CL_INVALID_ARG_SIZE in clSetKernelArg

我目前正在学习如何使用 OpenCL,但我在尝试将内核加入队列时遇到问题。

内核应该接收一个 float 和 2 个 unsigned char 和 unsigned int 类型的缓冲区 -

__kernel void task2(float value,
                    __global unsigned char *chars,
                    __global unsigned int *ints) 

我的程序如下所示 -

bufferA = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_uchar) * alphabets.size());
bufferB = cl::Buffer(context, CL_MEM_READ_WRITE, sizeof(cl_uint) * numbers.size());

kernel = cl::Kernel(prog, "kernelTest");
kernel.setArg(0, 2.55);
kernel.setArg(1, bufferA);
kernel.setArg(2, bufferB);

queue.enqueueTask(kernel);

其中字母和数字是向量。该程序已成功构建但被排除在外,因为我认为它与这个问题无关。

当到达程序中的 enqueueTask 部分时,我收到一个错误 -

Error in: clSetKernelArg
Error code: -51 (CL_INVALID_ARG_SIZE)

除非我对此完全错误,否则内核会接收 3 个参数,而我分别传入 float、unsigned char Buffer 和 unsigned Int buffer 三个参数。我做错了什么吗?

你没有说你的 3 个 setArg() 调用中的哪个失败了,但我怀疑问题可能是文字 2.55double 类型,而你的内核期望一个float。您可以尝试 2.55f,或者如果这不起作用,请使用 float 类型的临时变量而不是文字。

请注意 clSetKernelArg()cl::Kernel::setArg() 的后端)不验证缓冲区对象的大小。所以 CL_INVALID_ARG_SIZE 只与标量参数的大小不匹配有关,对于 global 指针内核参数,clSetKernelArg() 验证传递的参数实际上是一个有效的 cl_mem 句柄(并且指定arg_sizesizeof(cl_mem)).