Search code examples
cudathrust

Why does transform_reduce result differ from the result of transform & reduce?


I was testing some thrust code and found transform_reduce is giving a slightly different calculation result which totally confused me.

Here's a testing sample code: (to compute sum(exp(x)))

It was complied and run in VS2012 + CUDA 6.0

#include <iostream>
#include <cmath>
#include <thrust/device_vector.h>

using namespace std;

template <typename T>
struct exponential
{
    __host__ __device__
        T operator()(const T& x) const { 
            return exp(x);
    }
};

void main() {
    thrust::device_vector<double> f(7), g(7);
    f[0]=0.0; f[1]=1.0; f[2]=2.0; f[3]=3.0; f[4]=5.0; f[5]=5.0; f[6]=5.0;
    double d = thrust::transform_reduce(f.begin(), f.end(), exponential<double>(), 0, thrust::plus<double>());
    cout<<"transform_reduce result: " d << '\n';

    thrust::transform(f.begin(), f.end(), g.begin(), exponential<double>());
    double e = thrust::reduce(g.begin(), g.end());
    cout<<"transform+reduce result: " << e << endl;

}

The output I got was that

transform_reduce result: 474
transform+reduce result: 476.432

The correct value should be 476.432
I don't know what happened in transform_reduce. It not only gives an integer but also a wrong answer.

Isn't transform_reduce supposed to be the same as transform+reduce?

Please help me to explain what happened...


Solution

  • Change your initialization constant from an integer:

    double d = thrust::transform_reduce(f.begin(), f.end(), exponential<double>(), 0, thrust::plus<double>());
    

    to a double:

    double d = thrust::transform_reduce(f.begin(), f.end(), exponential<double>(), 0.0, thrust::plus<double>());
                                                                                   ^^^
    

    transform_reduce picks up its OutputType from the type of this parameter.

    (By the way, the code you have posted will not compile.)