简体   繁体   English

获取CUDA推力:: transform operator()函数中向量的索引

[英]Get index of vector inside CUDA thrust::transform operator() function

In CUDA Thrust transform, is it possible to get the index of a vector, passed into the operator() function, inside the function? 在CUDA Thrust变换中,是否可以获取传递到operator()函数内的向量的索引?

say, we have, 说,我们有,

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());

how do i get the index of the vector inside the operator()? 如何获取operator()中向量的索引? basically i want a easy way to make a identity matrix in CUDA. 基本上我想在CUDA中制作身份矩阵的简单方法。

There are probably many ways to do this. 可能有很多方法可以做到这一点。 One approach would be: 一种方法是:

  1. use thrust::sequence to create a vector of indices of the same length as your data vector (or instead just use a counting_iterator ) 使用thrust::sequence创建一个索引向量,该索引的长度与数据向量的长度相同(或者只使用counting_iterator
  2. use a zip_iterator to return a thrust::tuple , combining the data vector and the index vector, returning a tuple of a data item plus its index 使用zip_iterator返回thrust::tuple ,将数据向量和索引向量组合,返回数据项及其索引的元组
  3. Define the operator op() to take the particular tuple as one of it's arguments 定义运算符op()以将特定的元组作为其参数之一
  4. In the operator, use thrust::get<> to retrieve either the data element, or the index as needed, from the tuple 在运算符中,使用thrust::get<>从元组中检索数据元素或索引(根据需要)

You can read more about most of these concepts in the thrust quickstart guide . 您可以在推力快速入门指南中阅读更多有关这些概念的更多信息。

EDIT : In response to question below, here's a worked example. 编辑 :针对以下问题,这是一个可行的示例。 Although this doesn't actually use any device_vector , if we were doing this on the GPU (using device_vector ) the only activity that would generate any significant GPU activity would be the call to thrust::transform , ie. 尽管实际上并没有使用任何device_vector ,但是如果我们在GPU上执行该操作(使用device_vector ),则唯一会产生任何重要GPU活动的活动就是对thrust::transform的调用。 there would be only 1 "pass" on the GPU. GPU上只有1次“通过”。

(Yes, the thrust::sequence call would also generate a GPU kernel, but I'm just using that to create some data for this example). (是的,推力:::序列调用也会生成一个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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM