我正在尝试使用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 将其复制回来吗?
赞赏每条评论/答案:)
由于
答案 0 :(得分:1)
这是一个非常晚的答案,可以从未答复的列表中删除此问题。我确信OP已经找到了解决方案(自2012年5月起:-)),但我相信以下内容可能对其他用户有用。
正如@talonmies指出的那样,问题可以通过融合聚集减少来解决。解决方案确实是Thurst的permutation_iterator
和reduce
的应用。 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
首先将其移动到主机。