首页 > 解决方案 > OpenCL:clSetKernelArg 中的 CL_INVALID_ARG_SIZE

问题描述

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

内核应该接收一个浮点数和 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 缓冲区和 unsigned Int 缓冲区的三个参数。难道我做错了什么?

标签: c++bufferopencl

解决方案


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

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


推荐阅读