推力:求和另一个数组索引的数组元素[Matlab的语法和(x(索引))]

时间:2012-05-04 15:19:50

标签: 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 将其复制回来吗?

赞赏每条评论/答案:)

由于

1 个答案:

答案 0 :(得分:1)

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

正如@talonmies指出的那样,问题可以通过融合聚集减少来解决。解决方案确实是Thurst的permutation_iteratorreduce的应用。 permutation_iterator允许(隐式)根据x数组中的索引对目标数组indices重新排序。 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));

如果您只想对索引数组N的第一个map项进行迭代。

最后,关于从主机使用global_array的可能性,您应该注意到这是驻留在设备上的向量,因此您需要cudaMemcpyFromSymbol首先将其移动到主机。