获取CUDA thrust :: transform operator()函数内的向量索引

TK *_*ble 3 c++ cuda thrust

在CUDA Thrust变换中,是否可以获取向量的索引,传递给函数内的operator()函数?

说,我们有,

struct op{
    float operator()(const float& f){
        //do something like return the index
    }
};
vector<float> v(100);
thrust::transform(v.begin(),v.end(),v.begin(),op());
Run Code Online (Sandbox Code Playgroud)

如何在operator()中获取向量的索引?基本上我想要一个简单的方法在CUDA中制作一个单位矩阵.

Rob*_*lla 6

可能有很多方法可以做到这一点.一种方法是:

  1. 用于thrust::sequence创建与数据向量长度相同的索引向量(或者只是使用a counting_iterator)
  2. 使用a zip_iterator返回a thrust::tuple,组合数据向量和索引向量,返回数据项的元组及其索引
  3. 定义运算符op()以将特定元组作为其中一个参数
  4. 在运算符中,用于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;

}
Run Code Online (Sandbox Code Playgroud)

  • 它不会将 GPU 的传递次数增加到 2 次或更多……如果我在原始 cuda 中对其进行硬编码,我可以一次完成……谢谢您的链接…… (2认同)