我在OpenCL中遇到一个奇怪的问题,我正在调用clEnqueueNDRangeKernel
来查找使用大内存缓冲区作为参数的内核。对于小于16384字节的缓冲区,一切正常。如果我将缓冲区大小增加到超过该值,则返回INVALID_KERNEL_ARGS错误。据我所知,这个错误意味着表明没有设置参数。将参数设置为无效大小或不适合内存的内容应触发不同的错误。
有什么想法吗?
@mfa的回答让我再次看看设备规格。看起来128 * 128的浮点数正好是64KB,这是卡的常量内存的大小。全局内存要大得多,所以使用__global而不是__constant来修复它。
但我仍然感到困惑:每次调用const内存的内存参数如何?在我创建缓冲区时,我似乎还不知道它是否会被用作常量或全局...是否有任何方法可以获得更有用的错误消息?
答案 0 :(得分:1)
在设备中查询“CL_DEVICE_MAX_PARAMETER_SIZE”,我打赌它将是16384.我的intel cpu的值为4096.
规格定义的最小值为:
Read more on the clGetDeviceInfo page.
Re:缓冲区和内存不足错误
创建缓冲区时,可以知道它可以连接到哪些设备。 clCreateBuffer获取缓冲区将与之关联的cl_context,之前对clCreateContext的调用获取了与新上下文关联的设备列表。但缓冲区不是你的问题。
__常数是您的原始问题。您的设备不会让您使用总计超过4352字节的常量参数,并且您尝试传递65536字节。全局内存没有这么低的约束(通常为GPU的总内存的50%,默认情况下为CPU的25%)。在尝试将内核参数设置为太大的值之前,将不会知道/触发内存不足错误。
当要为所有工作组共享(或复制 - 这取决于实现)常量内存时,问题发生在低级别。在计算单元中仅保留有限量的内存用于此用途。在芯片的设计者必须切断ALU内核或其他类型的存储器以允许更大的恒定存储器大小之前,只有这么多晶体管专用于此目的。即使在opencl 2.0中,最小值仍然只有1024字节。