【问题标题】:OpenCL returns INVALID_KERNEL_ARGS depending on size of bufferOpenCL 根据缓冲区的大小返回 INVALID_KERNEL_ARGS
【发布时间】:2015-03-10 17:05:52
【问题描述】:

我在使用 OpenCL 时遇到了一个奇怪的问题,我正在为使用大内存缓冲区作为参数的内核调用 clEnqueueNDRangeKernel。对于小于 16384 字节的缓冲区,一切正常。如果我将缓冲区大小增加到超过该值,则会返回 INVALID_KERNEL_ARGS 错误。据我了解,此错误表示未设置参数。将参数设置为无效大小或不适合内存的内容会触发不同的错误。

有什么想法吗?

更新

@mfa 的回答让我再次查看了设备规格。看起来一个 128*128 的浮点数组正好是 64KB,这是卡的常量内存的大小。全局内存要大得多,因此内核参数使用 __global 而不是 __constant 可以解决此问题。

但我仍然感到困惑:如何调用 const memory every 的内存不足参数?在我看来,当我创建缓冲区时,尚不知道它是用作常量还是全局......有没有办法获得更有用的错误消息?

【问题讨论】:

  • 当你创建数据时还不知道它会被如何使用。然而,HW 有特定的频道以非常快速的方式广播小关键参数(如 GL 中的变换矩阵)。那是__constant 内存。如果你的缓冲区大于这个大小,那么你传递给内核的参数是无效的,因此错误。

标签: c opencl


【解决方案1】:

在您的设备上查询“CL_DEVICE_MAX_PARAMETER_SIZE”,我敢打赌它会是 16384。对于我的英特尔 CPU,这个值是 4096。

规范定义的最小值是:

  • opencl 1.0 - 256 字节
  • opencl 1.1 - 1024 字节
  • opencl 1.2 - 1024 字节
  • opencl 2.0 - 1024 字节

Read more on the clGetDeviceInfo page.


Re: 缓冲区和内存不足错误

当您创建缓冲区时,就知道它可以连接到哪些设备。 clCreateBuffer 获取缓冲区将关联的 cl_context,并且先前对 clCreateContext 的调用获取了与新上下文关联的设备列表。但缓冲区不是你的问题。

__constant 是您最初的问题。您的设备不允许您使用总计超过 4352 字节的常量参数,而您试图传递 65536 字节。全局内存没有这么低的限制(默认情况下,GPU 占总内存的 50%,CPU 占 25%)。在您尝试将内核参数设置为太大的值之前,不会知道/触发内存不足错误。

问题发生在低级别,当常量内存要共享(或复制——这取决于实现)以供所有工作组使用时。计算单元中仅保留有限数量的内存用于此用途。在芯片设计者不得不削减 ALU 内核或其他类型的存储器以允许更大的恒定存储器大小之前,只能有这么多专用于此目的的晶体管。即使在 opencl 2.0 中,最小值仍然只有 1024 字节。

【讨论】:

  • 谢谢!我的 NVIDIA gpu 上的最大参数大小是(奇怪的是)4352 字节。我的 AMD cpu 上有 4096 字节。但是,我传入的参数是一个指向内存缓冲区的指针,所以我猜应该是 size_t 的大小。
  • 17 * 256 并不奇怪。哪个显卡?
  • GeForce GT 640。我实际上已经发现了发生了什么,但仍然对为什么会出现这个特殊错误感到有些困惑。查看更新的答案
  • 大小高达 64kb 在恒定内存中工作正常!我明白为什么现在会出现错误,但我仍然很困惑为什么这会导致“INVALID_KERNEL_ARGS”:完全错误的错误消息!
  • 哦,这很有趣。我想我误读了您对 64kb 部分的描述。您遇到的错误可能是您正在使用的 nvidia sdk/runtime 中的错误。检查以确保您是最新的,如果仍然存在,请考虑将错误报告给 nvidia。
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 2018-10-01
  • 2023-03-21
  • 1970-01-01
  • 2017-03-21
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多