2013-10-30 10 views
10

ループは簡単ですが、私はちょうどSTLアルゴリズムを使って周りを囲んで、同じネストループを以下に与えているようです。C++ STLアルゴリズムを使用してネストループを書き直すにはどうすればよいですか?

const int a_size = 5; // input 
const int c_size = 2; // output 
const int b_size = a_size * c_size; // multipliers 

std::vector<float> a(a_size); 
std::vector<float> b(b_size); 
std::vector<float> c(c_size); 

// fill a and b with data 

// this nested loop 
for(int i = 0; i<c_size; i++) { 
    c[i] = 0.0; 
    for(int k = 0; k<a_size; k++) { 
     c[i] += (a[k] * b[i*a_size+k]); 
    } 
    c[i] = sigmoid(c[i]); 
} 

私はこれをやりたい理由、STLのようなアルゴリズムを使用して、GPU上での計算を行うだろうBoost.Computeライブラリ、ためている(STD ::変換、のstd :: for_eachなど)。

+4

行列演算を使用してアルゴリズムを書き直すことができるようです。 –

+1

私は、ユーザーが 'Boost.Compute'に任意のカーネルを書くことを許可するほうが良いと思います。例えば、私がここに記述した['TaskGraph'](http://ideone.com/qQ4Pvo)メソッド(http://boost.2283326.n4.nabble.com/compute-GPGPU-Library-Request-For -Feedback-tp4643691p4643927.html)。 –

答えて

6

私はwithを思い付いた:

auto i = 0; 
generate(begin(c), end(c), [&i, &a, &b] 
{ 
    return sigmoid(inner_product 
    (
     begin(a), end(a), 
     begin(b) + distance(begin(a), end(a)) * i++, 0.f 
    )); 
}); 

しかし、それはかなりよく見ていません - おそらく、このような場合には、私は私自身のアルゴリズムを書くことを好むだろう。

または、マトリックス形式を使用してください。 Eigenライブラリでは、次のようになります。

MatrixXd b; 
VectorXd a, c; 
// ... 
c = (b*a).unaryExpr(sigmoid); 
+0

それを消すにはしばらく時間がかかります。 Eigenのことは聞いたことがありませんが、GPUでの計算をサポートしていますか? – user1973386

+1

@ user1973386 AFAIK - 現時点ではGPUをサポートしていません。組み込み関数(SSE2など)を使用してベクトル化します。私はちょうど次のことを見つけました:['gpumatrix'](https://github.com/rudaoshi/gpumatrix) - " * Iigenと互換性のあるインタフェースを備えたGPU上の行列と配列ライブラリ " - 私はそれも価値があると思う。 –

+0

OpenCLをまだサポートしていないのは残念ですが、これは予定されています。私はそのライブラリを追跡します:)。 – user1973386

7

実際にネストループはアルゴリズムstd :: inner_productです。

auto first = std::begin(b); 
auto increment = std::distance(std::begin(a), std::end(a)); 
//,, 

c[i] = std::inner_product(std::begin(a), std::end(a), first, 0); 
std::advance(first, increment); 

外側ループの代わりにアルゴリズムstd :: generateを使用できます。

関連する問題