2017-01-26 1 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"을 사용합니다. 따라서 종속성을 표현하거나 결과의 정확성을 보장 할 책임이 있습니다.