내가이 2 개 지침 사용할 수없는 이유는 상단 루프에 커널이 : 나는 이러한 변수를 업데이트해야업데이트 지침 OpenACC
#pragma acc update device(hbias[0:n_hidden],W[0:n_hidden][0:n_visible])
#pragma acc update device(vbias[0:n_visible)
을 hbias
, 아래의 코드에서 vbias
, W
하지만,
void RBM::contrastive_divergence(int train_X[6][6], double learning_rate, int k) {
double r= rand()/(RAND_MAX + 1.0);
int * input = new int[n_visible];
double *ph_mean = new double[n_hidden];
int *ph_sample = new int[n_hidden];
double *nv_means = new double[n_visible];
int *nv_samples = new int[n_visible];
double *nh_means = new double[n_hidden];
int *nh_samples = new int[n_hidden];
#pragma acc kernels
for (int i = 0; i<train_N; i++) {
for (int j = 0; j< n_visible; j++){
input[j] = train_X[i][j];
}
sample_h_given_v(input, ph_mean, ph_sample,r);
for (int step = 0; step<k; step++) {
if (step == 0) {
gibbs_hvh(ph_sample, nv_means, nv_samples, nh_means, nh_samples,r);
}
else {
gibbs_hvh(nh_samples, nv_means, nv_samples, nh_means, nh_samples,r);
}
}
for (int i = 0; i<n_hidden; i++) {
for (int j = 0; j<n_visible; j++) {
W[i][j] += learning_rate * (ph_mean[i] * input[j] - nh_means[i] * nv_samples[j])/N;
}
hbias[i] += learning_rate * (ph_sample[i] - nh_means[i])/N;
}
//this directive
#pragma acc update device(hbias[0:n_hidden],W[0:n_hidden][0:n_visible])
for (int i = 0; i<n_visible; i++) {
vbias[i] += learning_rate * (input[i] - nv_samples[i])/N;
}
//and this directive
#pragma acc update device(vbias[0:n_visible)
}
delete[] input;
delete[] ph_mean;
delete[] ph_sample;
delete[] nv_means;
delete[] nv_samples;
delete[] nh_means;
delete[] nh_samples;
}
을하지만 각 중첩 루프 작업 많은 분리 커널이있을 때, 나는 변수를 업데이트 할 수 있습니다 : 작동하지 않습니다
void RBM::contrastive_divergence(int train_X[6][6], double learning_rate, int k) {
double r= rand()/(RAND_MAX + 1.0);
int * input = new int[n_visible];
double *ph_mean = new double[n_hidden];
int *ph_sample = new int[n_hidden];
double *nv_means = new double[n_visible];
int *nv_samples = new int[n_visible];
double *nh_means = new double[n_hidden];
int *nh_samples = new int[n_hidden];
for (int i = 0; i<train_N; i++) {
#pragma acc kernels
for (int j = 0; j< n_visible; j++){
input[j] = train_X[i][j];
}
sample_h_given_v(input, ph_mean, ph_sample,r);
#pragma acc kernels
for (int step = 0; step<k; step++) {
if (step == 0) {
gibbs_hvh(ph_sample, nv_means, nv_samples, nh_means, nh_samples,r);
}
else {
gibbs_hvh(nh_samples, nv_means, nv_samples, nh_means, nh_samples,r);
}
}
#pragma acc kernels
{
for (int i = 0; i<unhidden; i++) {
for (int j = 0; j<n_visible; j++) {
W[i][j] += learning_rate * (ph_mean[i] * input[j] - nh_means[i] * nv_samples[j])/N;
}
hbias[i] += learning_rate * (ph_sample[i] - nh_means[i])/N;
}
//this directive
#pragma acc update device(hbias[0:n_hidden],W[0:n_hidden][0:n_visible])
}
#pragma acc kernels
{
for (int i = 0; i<n_visible; i++) {
vbias[i] += learning_rate * (input[i] - nv_samples[i])/N;
}
//and this directive
#pragma acc update device(vbias[0:n_visible)
}
}
delete[] input;
delete[] ph_mean;
delete[] ph_sample;
delete[] nv_means;
delete[] nv_samples;
delete[] nh_means;
delete[] nh_samples;
}
을
어떤 컴파일러를 사용하고 있습니까? PGI라면 -Minfo = accel의 출력을 게시 할 수 있습니까? 이게 효과가있는 것처럼 보입니다. 커널 밖에서 데이터 영역을 바로 추가한다면 어떨까요? 이것은 필요하지 않지만 도움이됩니다. – jefflarkin
예, 저는 PGI 컴파일러를 사용합니다. 기본적으로 일부 변수에 대해서는 감산을 수행해야합니다. 그러나 컴파일러도이를 수용하지 않았습니다. 완료 될 때마다 일부 변수 값을 동기화해야합니다. 그렇지 않으면 결과가 사실이 아닙니다. 데이터 영역 지시문을 추가하고 내가 무엇을 얻을지 알아 보겠습니다. 감사합니다. –
이 명령을 사용했습니다. $ pgC++ - fast - acc - ta = tesla : managed - Minfo = accel - o task2./RBM.cpp && echo "컴파일 성공!" 커널은 추가 지시문을 사용하지 않고 출력은 다음과 같습니다. –