如何从数组中并行删除零值

Posted

技术标签:

【中文标题】如何从数组中并行删除零值【英文标题】:How to remove zero values from an array in parallel 【发布时间】:2012-09-09 22:20:42 【问题描述】:

如何使用 CUDA 有效地从数组中并行删除零值。 有关零值数量的信息可提前获得, 这应该可以简化这项任务。

保持数字在源数组中的顺序很重要, 当被复制到结果数组时。


例子:

数组将例如包含以下值: [0, 0, 19, 7, 0, 3, 5, 0, 0, 1] 附加信息是 5 个值为零。 所需的最终结果将是另一个数组,其中包含: [19、7、3、5、1]

【问题讨论】:

确定要删除零吗?如果你删除非零,你会得到一个只有零的数组?! 是的,纠正了这一点。我正在寻找一种从源数组中删除零值的有效方法。 我想通过 cuda 线程替换 for 循环,有效地并行删除。 这听起来像是标准的流流压缩操作 在搜索算法方法时,这绝对是正确的。谢谢你的回答。 【参考方案1】:

要从数组中删除一些元素,您可以使用Thrust Library's reordering operations。给定一个谓词is_not_zero,对于零值返回false,对于其他值返回true,你可以这样写操作

thrust::copy_if(in_array, in_array + size, out_array, is_not_zero);

输出数组将仅包含非零值,因为谓词表明如此。

您也可以使用带有反向谓词的“remove_if”函数,它返回 true 表示零,false 表示其他......

thrust::remove_if(in_array, in_array + size, is_zero);

我建议你看一下 Thrust 库的压缩示例,或一般压缩概念。

https://github.com/thrust/thrust/blob/master/examples/stream_compaction.cu

【讨论】:

我可能无法在该项目中使用推力,但如果可以,我会使用您的建议。感谢您的帮助。 有类似的库,只是用于压缩的内核实现。您可能不需要仅将 Thrust 用于此功能,但我建议您使用它。看看 CUDA SDK 的例子就知道了。【参考方案2】:

如果您不想使用 Thrust 而更喜欢使用 CUDA,最好的办法可能是运行 Sum Scan,这里有详细描述

https://developer.nvidia.com/gpugems/gpugems2/part-iv-general-purpose-computation-gpus-primer/chapter-36-stream-reduction

【讨论】:

【参考方案3】:

奇偶合并排序的变体,或者实际上任何排序算法,其中排序由a < b === (a != 0 && b == 0) 定义?

【讨论】:

这是一种位排序,因此可以比一般的归并排序做得更好。 @JaredHoberock:嗯,我还没有看到你提出了一种更好的工作方法。 排序方法的另一个问题是它会破坏输入,@diver_182 希望保留在输入数组中。 remove_copy_if 在这种情况下会更好,正如上面的@phoad 所述。 @JaredHoberock:没问题,他可以先复制再排序。

以上是关于如何从数组中并行删除零值的主要内容,如果未能解决你的问题,请参考以下文章

在 TensorFlow 中,如何使用 python 从张量中获取非零值及其索引?

并发数组检查

如何在R中的并行任务中删除临时文件

比较从文本文件中读取的并行数组

如何在 iOS 中获取 JSON 响应?获得零值?

'尝试索引字段'颜色'(零值)'在LUA中访问数组时