私はこれらの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 "コンパイルに成功しました!"カーネルに追加の指示文がなく、出力は次のようになりました: –