2

我正在尝试使用 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将其复制回来吗?

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

谢谢

4

1 回答 1

2

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

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

此应用程序是Thrust 文档的一部分,为方便起见,以下报告

#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));

如果您只想迭代N索引数组的第一项map

最后,关于global_array从主机使用的可能性,你应该注意到这是一个驻留在设备上的向量,所以你需要cudaMemcpyFromSymbol先将它移动到主机。

于 2014-03-26T22:15:23.597 回答