Ich bringe einen Code auf die GPU. Dieser Code verfügt über einen Kernel, der ein privates Array verwendet. Dies bedeutet, dass das Array innerhalb der Kernel-Schleife deklariert ist.OpenACC: mit einem privaten Array für jeden GPU-Thread
Wenn ich den Code zu OpenACC portiere, bekomme ich fehlerhafte Ergebnisse. Für mich, sieht es so aus, als wäre das Array zwischen GPU-Vektor-Threads geteilt und dies verursacht mehrere Wettlaufbedingungen.
Ich organisierte das folgende Beispiel mit auch externen Anrufen, weil mein Originalcode so aussieht.
header.h:
#define N 100000
#define K 16
#pragma acc routine
void assign_i_to_privj(int * priv, int j, int i);
#pragma acc routinetnumpy
void add_privi_to_sum(int * priv, int i, int *sum);
main.c:
#include "header.h"
int main(void){
int A[N];
#pragma acc data copy(A)
{
#pragma acc parallel loop
for(int i=0; i<N;i++){
int priv[K];
int sum=0;
int j=0;
while(1){
if(j>=K) break;
assign_i_to_privj(priv, j, i);
j++;
}
j=0;
while(1){
if(j>=K) break;
add_privi_to_sum(priv, j, &sum);
j++;
}
sum/=K; // now sum == i;
A[i]=sum;
}
}
//now A[i] == i
for(int i=0; i<123; i++) printf("A[%d]=%d ",i, A[i]);
printf("\n");
return 0;
}
F. C:
#include "header.h"
void assign_i_to_privj(int *priv, int j, int i){
priv[j]=i;
}
void add_privi_to_sum(int *priv, int j, int *sum){
(*sum)+=priv[j];
}
ich die Compiler-Version mit cc -v
sehen können, die Export PGI=/opt/pgi/17.5.0
zurückgibt.
kompilieren:
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays -c main.c &&
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays -c f.c &&
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays f.o main.o -o acc.exe &&
srun -n 1 acc.exe
Der Code alle A[i]
Elemente gleich i
setzen soll. Wenn ich diesen Code mit OpenACC-Unterstützung ausführe, bekomme ich völlig falsche Ergebnisse. Meine Vermutung ist eine Race-Bedingung. Die Version ohne openacc
kompilieren und läuft korrekt. Am Ende des Laufes A[i]==i
So meine Frage ist: wie kann ich ein kleines Array machen zu alle GPU-Threads mit OpenACC privat sein?
FYI, legte ich einen Problembericht für dieses Problem (TPR # 25047). Der Compiler sollte automatisch "priv" privatieren, da er in der Schleife deklariert ist, aber in diesem Fall nicht. –