Wenn ich einen Kernel auf der oberen Schleife haben, warum ich nicht diese 2-Richtlinien verwenden können:Aktualisierung Richtlinien OpenACC
#pragma acc update device(hbias[0:n_hidden],W[0:n_hidden][0:n_visible])
#pragma acc update device(vbias[0:n_visible)
ich diese Variablen aktualisieren hbias
, vbias
, W
in folgenden Code, aber es wird nicht funktionieren:
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;
}
Aber wenn ich auf jedem verschachtelten Schleifen viele getrennte Kerne haben arbeiten, kann ich die Variablen aktualisieren:
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;
}
Welchen Compiler benutzen Sie? Wenn PGI, können Sie bitte die Ausgabe von -Minfo = accel posten? Es sieht so aus als ob das funktionieren sollte. Was ist, wenn Sie einen Datenbereich direkt außerhalb der Kernel hinzufügen? Dies sollte nicht notwendig sein, könnte aber helfen. – jefflarkin
Ja, ich benutze PGI-Compiler. Grundsätzlich muss ich für einige Variablen eine Reduktion durchführen. Aber es wurde auch vom Compiler nicht akzeptiert. Ich muss einige Variablenwerte für jede durchgeführte Iteration synchronisieren. Andernfalls wird das Ergebnis nicht wahr sein. Ich werde versuchen, eine Datenregion-Direktive hinzuzufügen und zu sehen, was ich bekommen werde. Danke –
Ich habe diesen Befehl verwendet $ pgC++ - schnell - acc - ta = tesla: verwaltet - Minfo = accel - o task2./RBM.cpp && echo "Erfolgreich kompiliert!" in den Kernen ohne zusätzliche Anweisung und die Ausgabe war folgende: –