你如何解决无法将cl_mem列表传递给内核调用的问题?

时间:2011-07-27 20:19:05

标签: opencl

你有很多真实的理由想要这样做。我们的原因是我们有一个可变长度数据结构的列表,我们希望能够改变其中一个元素的大小而不必重新复制它们。

以下是我尝试过的一些事情:

  1. 只是有很多内核参数。当然,听起来很讨厌,但适用于小N.这实际上就是我们一直在做的事情。
  2. 做1)使用某种宏循环将内核args扩展到最大大小(我认为这取决于设备)。我真的不想这样做......听起来很糟糕。
  3. 创建某种包含指针的结构列表,并在内核调用之前填充它。我试过这个,我认为它违反了规范。根据我在nVidia论坛上看到的,保留超出一个内核调用的设备指针的地址是非法的。如果有人能指出它在说明书中的哪个位置,我很想知道,因为我找不到它。然而,这肯定会打破ATI硬件,因为它会移动物体。
  4. 放弃,将可变大小的对象存储在一个大数组中,并编写一个聪明的算法来使用空白空间,这样整个数组必须不经常回流。这将是有效的,但是是一个不优雅,复杂的设计。此外,它需要大量可怕的指针算法......
  5. 还有其他人有其他想法吗?尝试这样做的经历呢?是否有最少的hacky方式?为什么呢?

2 个答案:

答案 0 :(得分:0)

到3: OpenCL 1.1规范第193页说“程序中对内核函数的参数不能声明为指向指针的指针。”

包含指向指针的指针(指向缓冲区对象的指针)可能不会严格阅读这句话,但它符合精神:没有指向缓冲区对象的指针可以作为参数从主机代码传递给内核,即使它们是'隐藏在用户定义的结构中。

我选择选项5:不要使用可变大小的数据结构。如果你有任何方法可以通过任何方式使它们保持恒定大小。它会让你的生活变得更轻松。确切地说,没有“可变尺寸结构”。每个结构定义都会生成常量大小的结构,因此如果大小已更改,则结构本身已更改,因此需要另一个mem对象。传递给内核函数的每个指针都必须有一个类型。

答案 1 :(得分:0)

除了sharpnelis回答选项5:

如果对象具有相似的大小,则可以使用最大可能对象大小的联合。但请确保使用显式对齐。传递第二个缓冲区,标识变量大小的对象在静态大小的联合缓冲区中每个对象中使用的联合。

当使用opencl lib代码时,我只回到了这个,它只允许一个任意类型的变量数组。我只是使用cl_float2来传递两个浮点数。由于cl_floatN类型是作为联合实现的 - 对于构建类型有效的方法也适用于您。