10

The loop is simple enough, but I just can't seem to wrap my head around using the STL algorithms to give the same nested loop below.

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]);
}

The reason why I would like to do this, is for the Boost.Compute library, which would do the calculations on the GPU using STL-like algorithms (std::transform, std::for_each, etc.).

2
  • 4
    It seems that one can rewrite your algorithm using matrix operations. Commented Oct 30, 2013 at 9:23
  • 1
    I think it is better to allow users to write arbitrary kernels in Boost.Compute - it will be much more useful. For instance via TaskGraph method which I described here. Commented Oct 30, 2013 at 9:26

2 Answers 2

8

in fact the nested loop is algorithm 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 );

Instead of the outer loop you could use algorithm std::generate.

Sign up to request clarification or add additional context in comments.

Comments

6

I came up 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
    ));
});

But it does not look pretty well - probably in such case I would prefer to write my own algorithm.

Or use matrix-form. With Eigen library it will became:

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

4 Comments

It will take me a while to digest that. Never heard of Eigen, does it support computations on the GPU?
@user1973386 AFAIK - for the moment it does not support GPU. Though it does vectorization via intrinsics (SSE2, etc). I have just found following thing: gpumatrix - "A matrix and array library on GPU with interface compatible with Eigen" - I think it worth to look too.
Too bad it does not support OpenCL just yet, but it's planned. I'll keep track of that library :).
@nijansen As I understand from code-sample - It just provides types similar to GLSL for C++, but not does computations on GPU.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.