2017-01-26 4 views
1

OpenACC並列コンピューティングモデル(C++)を使用するにはいくつかの助けが必要です。問題は次のようなものです:OpenACCネストループ依存性エラー

vairables 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」に「independent」節を追加することはどうですか? 上部に「#pragma acc parallel」を使用します。 したがって、依存関係を表現したり結果の正当性を保証する責任があります。