如何使用推力减少数组中非连续的数字段

时间:2019-04-27 21:34:52

标签: cuda nvidia gpgpu thrust

我有一维数组“ A”,它由许多数组“ a”组成,如下所示: An example of an array "a" in "A"

我正在实现一个代码,以对不连续的段进行求和(对“ A”中每个数组“ a”的相同颜色的段中的数字求和,如下所示:

An example for one array "a" in "A"

有什么想法可以有效地做到这一点吗?

非常感谢您

注意:图片仅表示一个数组“ a”。大数组“ A”包含许多数组“ a”

1 个答案:

答案 0 :(得分:2)

在一般情况下,事先不知道数据的顺序和按段分组,一般建议是使用thrust::sort_by_key将相似的段分组在一起,然后使用thrust::reduce_by_key对各段求和。给出了示例here

但是,如果输入数据段遵循已知的重复模式(如此处建议的那样),我们可以通过使用thrust::permutation_iterator将类似的段“聚集”在一起作为{ {1}}。

使用问题中的示例数据,困难的部分是创建置换迭代器。为此,使用问题中给出的特定数量的段类型(3),段长度(3)和每个段类型的段数(3),我们需要一个映射“向量”(即迭代器)作为置换迭代器顺序如下:

thrust::reduce_by_key

然后,此序列将“映射”或重新排列输入数组,以便将所有类似的段组合在一起。我确定创建这种序列的方法有很多种,但是我选择的方法如下。我们将从标准计数迭代器序列开始,然后向其应用转换函子(使用0 1 2 9 10 11 18 19 20 3 4 5 12 13 14 21 22 23 ... ),以便创建上述序列。我选择使用以下方法进行操作,该方法以逐步的顺序排列,显示了添加到一起的组件:

make_transform_iterator

这是一个完整的示例:

counting iterator: (_1)                         0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 ...
---------------------------------------------------------------------------------------------------
((_1/seg_len)%seg_types)*(seg_len*seg_types):   0  0  0  9  9  9 18 18 18  0  0  0  9  9  9 18 18 18 ...
 _1%seg_len:                                    0  1  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1  2 ...
_1/(seg_len*seg_types)*seg_len:                 0  0  0  0  0  0  0  0  0  3  3  3  3  3  3  3  3  3 ...
 Sum:                                           0  1  2  9 10 11 18 19 20  3  4  5 12 13 14 21 22 23 ...