自定义min运算符用于减少推力::元组

时间:2014-06-12 15:52:46

标签: c++ cuda thrust

我试图在zip迭代器上运行min min,但是使用自定义运算符只考虑元组中的第二个字段(第一个字段是键,第二个字段是值) ,实际上与减少相关)

但是,我无法让它工作,并且正在计算向量中存在的结果

以下代码重现了该问题:

#include <thrust/device_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/tuple.h>
#include <thrust/sequence.h>

typedef thrust::tuple<unsigned int, unsigned int> DereferencedIteratorTuple;

struct tuple_snd_min{
  __host__ __device__ 
  bool operator()(const DereferencedIteratorTuple& lhs,
                  const DereferencedIteratorTuple& rhs){
    return (thrust::get<1>(lhs) < thrust::get<1>(rhs));
  }
};


void f(){
    thrust::device_vector<unsigned int> X(10);
    thrust::device_vector<unsigned int> Y(10);

    thrust::sequence(X.begin(), X.end());
    thrust::sequence(Y.begin(), Y.end());

    X[0] = 5;
    Y[0] = 5;
    X[1] = 50;

    // X: 5 50 2 3 4 5 6 7 8 9
    // Y: 5 1  2 3 4 5 6 7 8 9

    typedef thrust::device_vector<unsigned int>::iterator UIntIterator;
    typedef thrust::tuple<UIntIterator, UIntIterator> IteratorTuple;

    thrust::zip_iterator<IteratorTuple> first = 
        thrust::make_zip_iterator(thrust::make_tuple(X.begin(), Y.begin()));

    thrust::tuple<unsigned int, unsigned int> init = first[0];
    thrust::tuple<unsigned int, unsigned int> min = 
        thrust::reduce(first, first + 10, init, tuple_snd_min());

    printf("(%d,%d)\n", thrust::get<0>(min), thrust::get<1>(min));
    // should return (50,1)
    // returns (0,0)   
}

感谢Jared Hoberock的评论,我能解决这个问题。

typedef thrust::tuple<unsigned int, unsigned int> DereferencedIteratorTuple;

struct tuple_snd_min{
  __host__ __device__ 
  const DereferencedIteratorTuple& operator()(const DereferencedIteratorTuple& lhs, const DereferencedIteratorTuple& rhs)
  {
    if(thrust::get<1>(lhs) < thrust::get<1>(rhs)) return lhs;
    else return rhs;
  }
};

1 个答案:

答案 0 :(得分:1)

这似乎是由于对reduce调用中的函子必须实现哪个操作的误解造成的。根据{{​​3}},仿函数必须是二进制函数的模型,其输出必须可转换为输入类型。这是你的算子失败的地方。而不是这个

struct tuple_snd_min{
  __host__ __device__ 
  bool operator()(const DereferencedIteratorTuple& lhs,
                  const DereferencedIteratorTuple& rhs){
    return (thrust::get<1>(lhs) < thrust::get<1>(rhs));
  }
};

您的仿函数需要定义如下:

struct tuple_snd_min{
  __host__ __device__ 
  int operator()(const DereferencedIteratorTuple& lhs,
                  const DereferencedIteratorTuple& rhs){
    return (thrust::get<1>(lhs) < thrust::get<1>(rhs)) ?
             thrust::get<1>(lhs) : thrust::get<1>(rhs);
  }
};

即。该函数应返回一个值而不是作为谓词。

[这个答案是根据评论收集的,并作为社区维基条目发布,以便将这个问题从未答复的队列中删除]