通过常数乘以设备向量

时间:2014-03-30 05:41:56

标签: c++ vector cuda thrust

我正在使用推力进行项目,似乎缺少一些基本功能: -

在c ++中,将向量乘以常量的最简单方法是使用std::transformstd::bind1st,如下所示:

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

但显然bind1stbind2nd不适用于推力。

那么,是否有一种简单的方法可以将矢量乘以推力常数?

PS :目前我正在使用自己的仿函数来进行乘法运算:

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

,其中

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

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

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

但是编写一个仿函数进行简单的乘法似乎有些过分。肯定必须有一个更简单的方法。

2 个答案:

答案 0 :(得分:7)

可以使用适配器进行推力,但不能使用std::bind1ststd::bind2ndstd:bind。您需要编写自己的__device__适配器函数(有关更多信息,请参阅here)。

但是,推力1.7(应该在CUDA 5.5和更新版本中可用)支持lambda表达式,因此您的示例可以写成:

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

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

{免责声明,用浏览器编写,未经测试,自担风险使用}

如果您使用较旧的CUDA版本,那么您将无法定义仿函数。

答案 1 :(得分:3)

实现此目的的一种简单方法是使用Thrust的花式迭代器,这通常允许您避免定义(尽可能多的)仿函数。您可以将二进制函数与花式迭代器结合使用,而不是使用std :: bind1st从二进制函数实现一元函数:

#include <thrust/transform.h>
#include <thrust/iterator/constant_iterator.h>
#include <thrust/functional.h>
...
thrust::transform(vec.begin(), vec.end(), 
                  thrust::make_constant_iterator(myConst),
                  vec.begin(),
                  thrust::multiplies<int>());

在我看来,这个解决方案比使用std :: bind或lambda更优雅。

可以找到花式迭代器的文档here