【问题标题】:2D Array as OpenCL kernel argument二维数组作为 OpenCL 内核参数
【发布时间】:2016-05-28 07:24:36
【问题描述】:

非常直接的问题:如何使用二维数组作为 OpenCL 内核参数?

常识建议使用

__kernel void main(__global <datatype> **<name>),

但是编译器似乎对这个想法不太感兴趣:

kernel parameter cannot be declared as a pointer to a pointer.

我是否在监督显而易见的事情,或者究竟是什么,我在这里做错了?

编辑:

hosts (c++) 数据结构如下所示:

vector<vector<Element>>,

其中 Element 是一个结构,其中包含同一数组内的子节点的索引。基本上是指针。

【问题讨论】:

  • 你不能在 opencl 中将指针作为全局变量传递。图像/纹理是否适合您的目的?还是一维数组?
  • 我正在传递一个存储为结构数组本身的树数组,因此图像根本不适合我的目的。我可以考虑使用一维数组,但我不太确定这是否可行。
  • 树木是否平衡?它们可以分别构造成一维数组吗?如果必须,您可以使用不同的参数多次调用内核
  • 暗示在大多数答案中,但从未直接说明:vector<vector<Element>> 在内存中没有连续的元素。

标签: arrays multidimensional-array opencl


【解决方案1】:

您需要将二维数组缩减为一维数组。

主持人:

int array[50][50];
int * ptr_to_array_data = array[0];
int width = 50, height = 50;
cl_mem device_array = clCreateBuffer(/*context*/, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, 50 * 50 * sizeof(int), ptr_to_array_data, /*&err*/);
clSetKernelArg(/*kernel*/, 0, sizeof(cl_mem), &device_array);
clSetKernelArg(/*kernel*/, 1, sizeof(cl_int), &width);
clSetKernelArg(/*kernel*/, 2, sizeof(cl_int), &height);

设备:

kernel function(global int * array, int width, int height) {
    int id = get_global_id(0);
    int our_value = array[id];
    int x = id % width; //This will depend on how the memory is laid out in the 2d array. 
    int y = id / width; //If it's not row-major, then you'll need to flip these two statements.
    /*...*/
}

如果您的 2D 数组没有像我的示例所暗示的那样连续存储在内存中,则您需要滚动自己的函数以确保整个内存连续存储在单个堆分配对象中。

【讨论】:

  • 我不知道。我也不建议使用图像进行这种数据处理,因为访问图像通常需要一个采样器,这涉及以一种会导致错误和难以阅读的代码的方式抽象您的访问。
  • 或者,换个角度来看,使用样本和专用函数访问图像可以避免你不得不做丑陋的数学来查找元素,支持使用单个内核的许多不同像素类型,允许边界、镜像或重复,并根据需要提供对硬件双线性插值的访问。
  • @Dithermaster 如果您使用的数据是实际图像数据,所有这些都非常有用。但是,如果您使用的是数据结构或非图像数据(就像 OP 所显示的那样),它只会增加复杂性层,几乎没有可察觉的好处。
猜你喜欢
  • 1970-01-01
  • 2012-02-05
  • 2013-09-14
  • 1970-01-01
  • 2020-10-01
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多