OpenCL:输出可变长度的数组

时间:2011-12-20 08:44:34

标签: c++ arrays opencl gpgpu

我们正在为GPGPU课程做作业。我们选择了一种算法,在CPU上实现,现在将其转换为OpenCL。

我们选择的算法将模型加载为一组三角形并将它们光栅化为体素。体素被定义为点数据的VBO。然后,我们使用几何着色器将这些点转换为体素作为三角形。

所以我们的OpenCL程序需要获取一个三角形列表并输出一个变量列表。

输出可变长度数组似乎是一个问题。

我们发现的解决方案是以原子方式递增计数器,并将该计数器用作输出数组的索引和数组的最终大小。除了......我们的GPU都不支持原子操作的扩展。

这是我们到目前为止所做的:

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable

#define POS1      i0 * 3 + 0
#define POS2      i0 * 3 + 1
#define POS3      i0 * 3 + 2

void WritePosition( __global float* OutBuffer, uint inIndex, __global float* inPosition )
{
    OutBuffer[ inIndex * 3 ] = inPosition[0];
    OutBuffer[ inIndex * 3 + 1] = inPosition[1];
    OutBuffer[ inIndex * 3 + 2] = inPosition[2];
}

__kernel void Voxelize( 
    __global float* outPointcloudBuffer, 
    __global float* inTriangleBuffer, 
    __global uint* inoutIndex
)
{
    size_t i0 = get_global_id(0);
    size_t i1 = get_local_id(0);

    WritePosition( outPointcloudBuffer, inIndex[0], &inTriangleBuffer[ i0 ] );

    //atomic_inc(inoutIndex[0]);
    inoutIndex[0] = max(inoutIndex[0], i0);
}

这个输出很奇怪。我们正在测试一个非常小的模型(12个三角形,36个位置,108个浮点数),我们得到的结果是31,63或95.总是16减去1的倍数。

我们如何获得可变长度输出数组的长度?

提前致谢。

1 个答案:

答案 0 :(得分:5)

我猜这通常会解决如下问题:

  • 第一遍:使用scan(并行前缀和)原语计算GPU上所需的数组大小。上面的链接包含Apple的示例实现。
  • 使用扫描算法的结果在主机端分配所需的资源。请注意,扫描算法的结果通常可用作各个工作项结果的索引提示。
  • 第二遍(可选):将数组压缩到第三遍中需要考虑的元素。
  • 第三遍:重新运行传递目标索引和分配数组的算法。

您可能想看看NVIDIA的OpenCL行进多维数据集implementation,其中实现了上述所有三个过程。

Best,Christoph