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;
}
누군가가 도움이 될 가능성을 높이려면 코드를 형식화하고 읽을 수 있도록하는 것이 좋습니다. 뭔가를 원하면 최소한의 노력을 기울이십시오. – pSoLT