我想使用推力创建一个包含通过测试的所有索引的数组。我想我在这里遗漏了一些东西,因为我似乎无法弄明白。使用推力有没有一种简单的方法呢?
struct is_odd
{
__device__
bool operator()(int &x)
{
return (x % 2) == 1;
}
};
int A[] = {1, 2, 1, 1, 4, 1};
int result[] = {-1, -1, -1, -1, -1};
thrust::find_map_if(A, A+5, result, is_odd()); // this function doesn't exist!
// result = {0, 2, 3, 5, -1}
我需要这个地图来分散任意数据数组(不是A)。
答案 0 :(得分:3)
可能有很多方法可以解决这个问题。这是一种可能的方法:
创建索引数组(或使用计数迭代器)
int A[] = {1, 2, 1, 1, 4, 1};
int iA[] = {0, 1, 2, 3, 4, 5};
例如,您可以使用thrust::sequence
来执行此操作。或者,您可以跳过iA
的显式生成,并在下一步中使用counting_iterator。
使用thrust::remove_copy_if获取索引数组并将其减少为与测试结果对应的元素。
这是一个完全有效的例子。请注意,remove_copy_if复制仿函数测试为 false 的元素:
$ cat t596.cu
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/remove.h>
#include <thrust/copy.h>
#define DSIZE 6
struct is_odd
{
__device__
bool operator()(int x) const
{
return !(x&1);
}
};
int main(){
int A[] = {1, 2, 1, 1, 4, 1};
thrust::device_vector<int> d_A(A, A+DSIZE);
thrust::device_vector<int> result(DSIZE, -1);
thrust::counting_iterator<int> first(0);
thrust::counting_iterator<int> last = first+DSIZE;
thrust::device_vector<int>::iterator r_end = thrust::remove_copy_if(first, last, d_A.begin(), result.begin(), is_odd());
thrust::copy(result.begin(), r_end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
thrust::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
$ nvcc -arch=sm_20 -o t596 t596.cu
$ ./t596
0 2 3 5
0 2 3 5 -1 -1
$