2014-03-30 28 views
3

我使用推力的一個項目,它似乎乘設備向量是缺少一些基本的功能: -通過不斷

在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; 
     } 
    }; 

但寫一個函子做一個簡單的乘法,似乎有點小題大做。肯定有一個更簡單的方法。

+0

並非是一個CUDA傢伙(和嫉妒的*所有*您抽出時間到信封踢屁股平臺),被lamdas支持與工具鏈? (並且如果它是一個天真的問題,但它似乎是天作之合)。 – WhozCraig

+0

Thrust是基於__標準模板庫的實現。這並不奇怪,它不支持一切。請注意,bind1st等已被棄用,並被綁定取代。 –

回答

7

推力可以使用適配器,但std::bind1st,std::bind2nd,std: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

對於複雜的算術運算,例如'vec'是'thrust :: device_vector '而'myConst'是'make_cuComplex'的結果嗎? – JackOLantern

1

完成此操作的一個簡單方法是使用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更優雅: :綁定或lambda。

花式迭代器的文檔可以在下面的鏈接中找到。

https://thrust.github.io/doc/group__fancyiterator.html#ga0510c773bef5408b233245d5be5dab70