Search code examples
c++stlfunctorthrust

thrust::transform_reduce How can I access iterator within unary op?


I am trying to perform a transform reduce on a vector of structs. The struct contains two numbers. I want the unary function to do something with these two numbers and return a single value for each struct in my vector and reduce with a summation of these values. How do I write my functor to access the values in the struct?

for example, whats the proper syntax for mystruct.value1 within the function?:

struct unary_op
{
    float operator()()
    {
        return mystruct.value1 + mystruct.value2; //function is a lot more complex 
    }
}

so I can do:

unary_op uop1;
thrust::transform_reduce(myvec.begin(), myvec.end(), uop1, 0, thrust::add)

Solution

  • Disclaimer: Since you obviously did not post real code and your example looks like a few unrelated code lines, my answer might not be what you are looking for - a SSCCE would have been nice.

    If I understand correctly, you want to transform_reduce a vector of MyStructs to the sum of all the structs member values. To do that, you need the binary addition (thrust::add) and a unary op taking a MyStruct and returning the addition of its member values:

    struct MyStruct {
      float value1;
      float value2;
    };
    std::vector<MyStruct> myvec;
    
    /* fill myvec */
    
    //C++11 with lambdas:
    auto result = thrust::transform_reduce(begin(myvec), end(myvec), 
      [](MyStruct const& ms) { //unary op for transform
        return ms.value1 + ms.value2;
      },
      0, thrust::add);
    
    //C++03 with a functor:
    struct MyStructReducer {
      float operator()(MyStruct const& ms) {
        return ms.value1 + ms.value2;
      }
    };
    
    float result = thrust::transform_reduce(myvec.begin, myvec.end(), 
      MyStructReducer(), 0, thrust::add);
    

    You could as well use a free function instead of the Reducer class.

    //C++03 with a function:
    float reduceMyStruct(MyStruct const& ms) {
      return ms.value1 + ms.value2;
    }
    
    /* ... */
    float result = thrust::transform_reduce(myvec.begin, myvec.end(), 
      reduceMyStruct, 0, thrust::add);
    

    HTH