Search code examples
cudathrust

Is there a way to multiply all the elements of an array using thrust?


Let's say I have an array and I want to multiply all the elements of that array and store it in a variable. How do I do it? I want to multiply all the elements in A and store the result in S. Doing this gives me zero.

thrust::device_vector<double> A(10);
thrust::sequence(A.begin(), A.end(), 1);
double S = thrust::reduce(thrust::host, A.begin(), A.end(), 
                             0, thrust::multiplies<double>());

Solution

  • There are two problems here:

    1. The use of the thrust::host execution policy makes no sense (in fact no execution policy makes sense if you are using thrust vectors as inputs). I would expect some sort of segfault or runtime error if you actually tried to run this code. Use tag based execution instead, i.e. just remove the first argument, and thrust will infer the execution policy from the types.
    2. The fourth argument in the thrust::reduce in call your code is the initial value of the product. You are setting it to 0. This means any product calculated by that code will be zero. Presumably you want the initial value to be one.

    Fixing both of those glaring problems gets me this:

    #include <thrust/device_vector.h>
    #include <thrust/reduce.h>
    #include <thrust/sequence.h>
    
    #include <iostream>
    #include <iomanip>
    
    int main()
    {
        thrust::device_vector<double> A(10);
        thrust::sequence(A.begin(), A.end(), 1.0);
    
        for(auto p = A.begin(); p != A.end(); ++p) {
            double v = *p;
            std::cout << v << std::endl;
        }
    
        double S = thrust::reduce(A.begin(), A.end(), 1.0, thrust::multiplies<double>());
    
        std::cout << "S = " << std::fixed << std::setprecision(1) << S << std::endl;
    
        return 0;
    }
    

    Compiling and running it gets me this:

    $ nvcc -std=c++11 -o prodprob prodprob.cu 
    
    $ ./prodprob 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    S = 3628800.0
    

    The correct answer should be 10! = 3628800, so I judge this as working correctly.