2013-10-30 16 views
10

Vòng lặp đủ đơn giản, nhưng tôi dường như không thể quấn quanh đầu tôi bằng cách sử dụng các thuật toán STL để cung cấp cùng một vòng lặp lồng nhau bên dưới.Làm thế nào để viết lại vòng lặp lồng nhau bằng thuật toán 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]); 
} 

Lý do tại sao tôi muốn làm điều này, là cho các thư viện Boost.Compute, mà sẽ làm các tính toán trên GPU sử dụng các thuật toán STL-like (std :: biến đổi, std :: for_each, vv .).

+4

Có vẻ như bạn có thể viết lại thuật toán của mình bằng cách sử dụng các phép toán ma trận. –

+1

Tôi nghĩ tốt hơn là cho phép người dùng viết các hạt tùy ý trong 'Boost.Compute' - nó sẽ hữu ích hơn nhiều. Ví dụ: thông qua phương thức ['TaskGraph'] (http://ideone.com/qQ4Pvo) mà tôi mô tả [ở đây] (http://boost.2283326.n4.nabble.com/compute-GPGPU-Library-Request-For -Feedback-tp4643691p4643927.html). –

Trả lời

6

tôi đã đưa ra 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 
    )); 
}); 

Nhưng nó không giống khá tốt - có lẽ trong trường hợp như vậy tôi muốn viết thuật toán của riêng tôi.

Hoặc sử dụng biểu mẫu ma trận. Với thư viện Eigen, thư viện này sẽ trở thành:

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

Tôi sẽ mất một lúc để tiêu hóa điều đó. Không bao giờ nghe nói về Eigen, nó có hỗ trợ tính toán trên GPU không? – user1973386

+1

@ user1973386 AFAIK - cho thời điểm nó không hỗ trợ GPU. Mặc dù nó không vectorization thông qua nội tại (SSE2, vv). Tôi vừa tìm thấy điều sau đây: ['gpumatrix'] (https://github.com/rudaoshi/gpumatrix) -" * Thư viện ma trận và mảng trên GPU với giao diện tương thích với Eigen * "- Tôi nghĩ nó đáng để xem xét . –

+0

Quá tệ nó chưa hỗ trợ OpenCL, nhưng nó đã được lên kế hoạch. Tôi sẽ theo dõi thư viện đó :). – user1973386

7

thực tế vòng lặp lồng nhau là thuật toán 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); 

Thay vì vòng ngoài bạn có thể sử dụng thuật toán std :: generate.

Các vấn đề liên quan