给定元素数组,偏移量和子列表长度的有效部分约简

bbt*_*trb 6 c++ cuda thrust

对于我的应用程序,我必须处理一堆对象(比如ints),这些对象随后被分割并分类成更小的桶.为此,我将元素存储在一个连续的数组中

arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14...}
Run Code Online (Sandbox Code Playgroud)

并且关于桶(子列表)的信息由相应桶中的第一个元素的偏移量和子列表的长度给出.

所以,例如,给定

offsets = {0,3,8,..}
sublist_lengths = {3,5,2,...}
Run Code Online (Sandbox Code Playgroud)

会导致以下分裂:

0 1 2 || 3 4 5 6 7 || 8 9 || ...
Run Code Online (Sandbox Code Playgroud)

我正在寻找的只是使用自定义内核或thrust库在桶上运行算法(如减少)的一种通用且有效的方法.总结水桶应该给:

3 || 25 || 17 || ...
Run Code Online (Sandbox Code Playgroud)

我想出了什么:

  • 选项1:自定义内核需要相当多的修补,复制到共享内存,正确选择块和网格大小以及自己的算法实现,如扫描,减少等.此外,每个操作都需要自己定制核心.总的来说,我很清楚如何做到这一点,但在thrust过去几天使用后,我的印象是可能有更聪明的方式

  • 选项2:从偏移量({0,0,0,1,1,1,1,1,2,2,3,...}在上面的例子中)生成一个键数组并使用thrust::reduce_by_key.不过,我不喜欢额外的列表生成.

  • 选项3:thrust::transform_iterator与...一起使用thrust::counting_iterator以生成上面给出的密钥列表.不幸的是,我无法想出一个实现,它不需要将索引增加到设备上的偏移列表,并且会破坏并行性.

实现这一目标最理智的方式是什么?

wnb*_*ell 5

在 Thrust 中,我想不出比选项 2 更好的解决方案。性能不会很糟糕,但肯定不是最佳的。

您的数据结构与用于存储稀疏矩阵的压缩稀疏行 (CSR)格式相似,因此如果您想要更好的性能,您可以使用为计算此类矩阵的稀疏矩阵向量乘法 (SpMV)而开发的技术。请注意,对于具有 N 行的矩阵(即您的情况中的存储桶),CSR 格式的“偏移”数组的长度为 (N+1),其中最后一个偏移值是 的长度arrCusp中的CSR SpMV 代码有点复杂,但它可以作为内核的良好起点。只需删除对代码或从代码中的任何引用,并将和分别传递到和参数中即可。AjxoffsetsarrApAv