2017-01-26 6 views
1

Пожалуйста, мне нужна помощь с использованием параллельной вычислительной модели OpenACC (C++). Проблема заключается в следующем:Ошибка зависимостей вложенной петли OpenACC

Существует зависимость между wairables W, hbias, vbias (она должна получать обновление каждой итерации) и вычислять средства внутри функций propup и propdown, но используя OpenACC для кода, который не доступен , Таким образом, каждая функция итерации получит внутреннее значение W и смещения. Обратите внимание, что если распараллеливание произойдет на более низком уровне, это не принесет пользы. Это код:

void RBM::contrastive_divergence(int ** train_X, double learning_rate, int k) { 


    int * input = new int[n_visible]; 

    double *ph_mean = new double[n_hidden]; 
    int *ph_sample = new int[n_hidden]; // CALUCLATED WITHIN COMPLETE CODE 
    double *nv_means = new double[n_visible]; 
    int *nv_samples = new int[n_visible]; //CALUCLATED WITHIN COMPLETE CODE 
    double *nh_means = new double[n_hidden]; 
    int *nh_samples = new int[n_hidden]; //CALUCLATED WITHIN COMPLETE CODE 


    #pragma acc parallel 
    { 

    #pragma acc loop gang private(input[0:n_visible],ph_mean[0:n_hidden],ph_sample[0:n_hidden], \ 
    nv_means[0:n_visible], nv_samples[0:n_visible], nh_means[0:n_hidden], \ 
    nh_samples[0:n_hidden]) 

    for (int ii = 0; ii<train_N; ii++) { 

    #pragma acc loop vector 
    for (int j = 0; j< n_visible; j++) 
    input[j] = train_X[ii][j]; 


    sample_h_given_v(input, ph_mean); 

    sample_v_given_h(h0_sample, nv_means); 
    sample_h_given_v(nv_samples, nh_means); 

     #pragma acc loop vector 
     for (int i = 0; i<n_hidden; i++) { 
      for (int j = 0; j<n_visible; j++) { 
      #pragma acc atomic update 
      W[i][j] += learning_rate * (ph_mean[i] * input[j] - nh_means[i] * nv_samples[j])/N; 
      } 
     #pragma acc atomic update 
     hbias[i] += learning_rate * (ph_sample[i] - nh_means[i])/N; 
     } 

     #pragma acc loop vector 
     for (int i = 0; i<n_visible; i++) { 
     #pragma acc atomic update 
     vbias[i] += learning_rate * (input[i] - nv_samples[i])/N; 
     } 

    } 

    } 

    delete[] input; 
    delete[] ph_mean; 
    delete[] ph_sample; 
    delete[] nv_means; 
    delete[] nv_samples; 
    delete[] nh_means; 
    delete[] nh_samples; 

    } 

    #pragma acc routine vector 
    void RBM::sample_h_given_v(int *v0_sample, double *mean){ 

     #pragma acc loop vector 
     for (int i = 0; i<n_hidden; i++) { 
      mean[i] = propup(v0_sample, W[i], hbias[i]); 
     } 
    } 




    #pragma acc routine vector 
    void RBM::sample_v_given_h(int *h0_sample, double *mean){ 

      #pragma acc loop vector 
      for (int i = 0; i < n_visible; i++) { 
       mean[i] = propdown(h0_sample, i, vbias[i]); 
      } 
    } 


    #pragma acc routine seq 
    double RBM::propup(int *v, double *w, double b) { 
    double pre_sigmoid_activation = 0.0; 
    for (int j = 0; j<n_visible; j++) { 
    pre_sigmoid_activation += w[j] * v[j]; 
    } 
    pre_sigmoid_activation += b; 

    double x; 
    x = 1.0/(1.0 + exp(-pre_sigmoid_activation)); 

    return x; 
    } 

    #pragma acc routine seq 
    double RBM::propdown(int *h, int i, double b) { 
    double pre_sigmoid_activation = 0.0; 
    for (int j = 0; j<n_hidden; j++) { 
    pre_sigmoid_activation += W[j][i] * h[j]; 
    } 
    pre_sigmoid_activation += b; 

    double x; 
    x = 1.0/(1.0 + exp(-pre_sigmoid_activation)); 
    return x; 
    } 
+1

Если вы хотите увеличить свои шансы на то, что кто-то поможет вам, это, вероятно, хорошая идея отформатировать ваш код и сделать его доступным для чтения. Положите минимальные усилия, если вы хотите что-то вернуть. – pSoLT

ответ

1

Как насчет добавления "независимого" предложения в "#pragma acc loop vector"? Вы используете «#pragma acc parallel» вверху. Таким образом, вы несете ответственность за выражение зависимостей или за правильность результата.

Смежные вопросы