可能有很多方法可以做到这一点。一种方法是:
- 用于
thrust::sequence
创建与数据向量长度相同的索引向量(或者只使用 a counting_iterator
)
- 使用 a
zip_iterator
返回 a thrust::tuple
,结合数据向量和索引向量,返回一个数据项的元组加上它的索引
- 定义运算符
op()
以将特定元组作为其参数之一
- 在运算符中,用于
thrust::get<>
根据需要从元组中检索数据元素或索引
您可以在推力快速入门指南中了解更多关于这些概念的大部分内容。
编辑:针对下面的问题,这是一个有效的示例。尽管这实际上并没有使用任何device_vector
,但如果我们在 GPU 上执行此操作(使用device_vector
),唯一会产生任何重要 GPU 活动的活动将是调用thrust::transform
,即。GPU上只有1个“通过”。
(是的,thrust::sequence 调用也会生成一个 GPU 内核,但我只是用它来为这个例子创建一些数据)。
#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/sequence.h>
#include <thrust/copy.h>
#define N 30
#define SELECT 3
typedef thrust::tuple<int, int> tpl2int;
typedef thrust::host_vector<int>::iterator intiter;
typedef thrust::counting_iterator<int> countiter;
typedef thrust::tuple<intiter, countiter> tpl2intiter;
typedef thrust::zip_iterator<tpl2intiter> idxzip;
struct select_unary_op : public thrust::unary_function<tpl2int, int>
{
__host__ __device__
int operator()(const tpl2int& x) const
{
if ((x.get<1>() %SELECT) == 0)
return x.get<0>();
else return -1;
}
};
int main() {
thrust::host_vector<int> A(N);
thrust::host_vector<int> result(N);
thrust::sequence(A.begin(), A.end());
thrust::counting_iterator<int> idxfirst(0);
thrust::counting_iterator<int> idxlast = idxfirst +N;
idxzip first = thrust::make_zip_iterator(thrust::make_tuple(A.begin(), idxfirst));
idxzip last = thrust::make_zip_iterator(thrust::make_tuple(A.end(), idxlast));
select_unary_op my_unary_op;
thrust::transform(first, last, result.begin(), my_unary_op);
std::cout << "Results :" << std::endl;
thrust::copy(result.begin(), result.end(), std::ostream_iterator<int>( std::cout, " "));
std::cout << std::endl;
return 0;
}