c++ - Thrust:对另一个数组索引的数组元素求和【Matlab的语法 sum(x(indices))】

标签 c++ cuda thrust

我正在尝试使用 Thrust 库对另一个数组索引的数组元素求和,但我找不到示例。换句话说,我想实现Matlab的语法

sum(x(indices))

这是一个指导代码,试图指出我想要实现什么目标:

#define N 65536

// device array copied using cudaMemcpyToSymbol
__device__ int global_array[N];

// function to implement with thrust
__device__ int support(unsigned short* _memory, unsigned short* _memShort)
{
   int support = 0;

  for(int i=0; i < _memSizeShort; i++)
        support += global_array[_memory[i]];

  return support;     
}

此外,在主机代码中,我可以使用 global_array[N] 而不使用 cudaMemcpyFromSymbol 将其复制回来吗?

每一条评论/答案都值得赞赏:)

谢谢

最佳答案

这是一个很晚才提供的答案,目的是从未回答的列表中删除这个问题。我确信 OP 已经找到了解决方案(自 2012 年 5 月起:-)),但我相信以下内容可能对其他用户有用。

正如@talonmies 所指出的,这个问题可以通过融合聚集缩减来解决。该解决方案确实是 Thurst 的 permutation_iteratorreduce 的应用。 permutation_iterator 允许根据 indices 数组中的索引(隐式)对目标数组 x 重新排序。 reduce 执行(隐式)重新排序数组的总和。

此应用程序是 Thrust's documentation 的一部分,为方便起见,报道如下

#include <thrust/iterator/permutation_iterator.h>
#include <thrust/reduce.h>
#include <thrust/device_vector.h>

// this example fuses a gather operation with a reduction for
// greater efficiency than separate gather() and reduce() calls

int main(void)
{
    // gather locations
    thrust::device_vector<int> map(4);
    map[0] = 3;
    map[1] = 1;
    map[2] = 0;
    map[3] = 5;

    // array to gather from
    thrust::device_vector<int> source(6);
    source[0] = 10;
    source[1] = 20;
    source[2] = 30;
    source[3] = 40;
    source[4] = 50;
    source[5] = 60;

    // fuse gather with reduction: 
    //   sum = source[map[0]] + source[map[1]] + ...
    int sum = thrust::reduce(thrust::make_permutation_iterator(source.begin(), map.begin()),
                             thrust::make_permutation_iterator(source.begin(), map.end()));

    // print sum
    std::cout << "sum is " << sum << std::endl;

    return 0;
}

在上面的例子中,map扮演了indices的角色,而source扮演了x的角色.

关于您评论中的附加问题(迭代减少数量的术语),更改以下行就足够了

int sum = thrust::reduce(thrust::make_permutation_iterator(source.begin(), map.begin()),
                         thrust::make_permutation_iterator(source.begin(), map.end()));

int sum = thrust::reduce(thrust::make_permutation_iterator(source.begin(), map.begin()),
                         thrust::make_permutation_iterator(source.begin(), map.begin()+N));

如果您只想迭代索引数组 map 的前 N 项。

最后,关于从主机使用 global_array 的可能性,您应该注意到这是驻留在设备上的 vector ,因此您确实需要一个 cudaMemcpyFromSymbol 来移动首先将其发送给主机。

关于c++ - Thrust:对另一个数组索引的数组元素求和【Matlab的语法 sum(x(indices))】,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10451664/

相关文章:

c++ - QTextStream 行为搜索不符合预期的字符串

c++ - “官方”CUDA Reduction 函数不能接受某些数字?

c++ - 在 CUDA 中混合自定义内存管理和 Thrust

c++ - 严格别名、CUdeviceptr 和 cuMemAllocManaged

c++ - 从 C++ 访问 device_vector 的最佳方式

cuda - 如何将 Thrust::host_vector<char> 复制到 char*

c++ - Qt 应用程序不会在特定机器上运行

.net - fatal error C1083 : Cannot open include file: 'vld.h' : No such file or directory

c++ - 将多重继承的对象转换到 void* 或从 void* 转换

vector - 在 CUDA/thrust 中执行向量求和