코드를 GPU로 가져오고 있습니다. 이 코드에는 개인 배열을 사용하는 커널이 있습니다. 즉, 배열은 커널 루프 내에서 선언됩니다.OpenACC : 모든 GPU 스레드에 대한 개인 배열이 있습니다.
OpenACC에 코드를 포팅하면 버그가 발생합니다. 나에게있어서 어레이가 GPU 벡터 쓰레드들 사이에서 공유되는 것처럼 보이고 이로 인해 여러 경쟁 조건이 발생한다.
외부 호출을 사용하여 다음 예제를 구성 했으므로 이것이 원래 코드처럼 보입니다.
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];
}
내가 Export PGI=/opt/pgi/17.5.0
을 반환 cc -v
와 컴파일러 버전을 볼 수 있습니다.
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
코드는 i
와 같은 모든 A[i]
요소를 설정해야합니다. OpenACC 지원으로이 코드를 실행하면 완전히 잘못된 결과를 얻습니다. 제 추측은 경쟁 조건입니다. openacc
이없는 버전은 올바르게 컴파일되고 실행됩니다. A[i]==i
그래서 실행의 끝에서, 내 질문은 :은 어떻게 작은 배열이 OpenACC 모든 GPU 스레드 에 개인으로 만들 수 있습니까?
참고로, 나는이 문제 (TPR 번호 25047)에 대한 문제 보고서를 제출했다. 컴파일러는 루프에서 선언 되었기 때문에 자동으로 "priv"를 private로 설정해야하지만이 경우에는 그렇지 않습니다. –