Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiply device vector by constant

I am using thrust for a project, and it seem to be missing some basic functionality :-

In c++, the easiest way to multiply a vector by a constant is using std::transform and std::bind1st like so:

std::transform(vec.begin(), vec.end(), vec.begin(),
           std::bind1st(std::multiplies<double>(),myConst)); 

But apparently bind1st and bind2nd does not work with thrust.

So, is there an easy way to multiply a vector by a constant in thrust?

PS: Currently I am using my own functor to do the multiplication like so:

thrust::for_each(vec.begin(), vec.end(), multiplyByConstant<double>(myConst))

where

    template< typename T >
    struct multiplyByConstant
    {
    const T constant;

    multiplyByConstant(T _constant) : constant(_constant) {}

     __host__ __device__
     void operator()( T& VecElem) const 
      {
        VecElem=VecElem*constant;
      }
    };

But writing a functor to do a simple multiplication seems like overkill. There surely must be an easier way.

like image 455
Shayan RC Avatar asked Dec 12 '22 06:12

Shayan RC


1 Answers

Thrust can be made to work with adaptors, but std::bind1st, std::bind2nd, std:bind can't be used. You will need to write your own __device__ adaptor function instead (see here for a little more information).

However, thrust 1.7 (should be available in CUDA 5.5 and newer) supports lambda expressions, so your example could be written as something like:

#include <thrust/functional.h>
#include <thrust/transform.h>

using namespace thrust::placeholders;
thrust::transform(vec.begin(), vec.end(), vec.begin(), myConst * _1); 

{disclaimer, written in browser, not tested, use at own risk}

If you are using an older CUDA release, then you are stuck with defining a functor.

like image 94
talonmies Avatar answered Dec 25 '22 00:12

talonmies