2017-05-22 20 views
0

OpenACC를 사용하여 LU decompositionblock diagonal matrices입니다.
코드를 순차적으로 실행할 때 올바른 분해가 발생하지만 OpecACC 지시문에서 실행하면 분해를 수행 할 때 잘못된 결과가 발생합니다.OpenACC - 중첩 된 루프 이상한 동작

LU 분해 (hereLUPSolve 기능 참조) 유형의 중첩 루프를 포함한다 :

중첩 루프의 형태는 병렬 영역 내에 routine seq 지시자로 사용되는 경우, 장치는 항상 관리하도록 표시
for (unsigned int i = 0; i < N; i++) 
    for (unsigned int k = 0; k < i; k++) 

i=0 (k<i 조건으로 인해 가능하지 않음)이더라도 중첩 루프 을 입력 할 수 있습니다. 내가 OpenACC없이 코드를 실행했을 때 얻을

x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 

그러나 정확한 (:

#pragma acc routine seq 
void test (int* x, int const n) { 
    for (unsigned int i = 0; i < n; i++) { 
     x[i] = -1; 
     for (unsigned int k = 0; k < i; k++) 
     x[i] = k < i; 
    } 
} 

int main () { 
    unsigned const n(4); 
    unsigned const nb(3); 
    int x[nb*n]; 
    #pragma acc parallel loop copyout(x[:nb*n]) 
    for (unsigned int b = 0; b < nb; b++) 
     test(x+b*n,n); 
    // display x 
} 

내가 얻을 결과는 이것이다 :

나는 그것을 확인하는 간단한 코드를 만들어)는 다음과 같아야합니다.

x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 

012 일 때 중첩 루프에 들어가서는 안되기 때문에 뭔가 잘못하고 있어야합니다....
Plus (함수 호출을 사용하지 않고) 병렬 영역에 직접 루프를 추가하면 올바르게 작동합니다.

+0

은 내가 이러한 타입의 중첩 루프와 같은 노력은 매우 이상한 : '에 대해 INT (I = N-1, I> = 0; 난 ...) {(INT k에 대한 = I + 1; (i = n-1; i> = 0; 0);이 장치를 다음과 같이 변경하면, 장치는'i = n-1'에 대한 중첩 루프에 들어 가지 않습니다. 똑같은 이상한 행동이 일어나고 디바이스는'i = n-1'에 대해 중첩 된 루프에 들어갑니다 ... 그것은'0 (0, 1) <0'은 중첩 된 루프에 대해 true입니다 ... 나는 단지 내가 잘못하고있는 것이 무엇인지 모릅니다. 그것은 내 루프의 상태 어딘가에 있어야합니다 ... –

답변

2

k와 i가 모두 0 일 때도 항상 내부 루프를 실행하는 컴파일러 코드 생성기 문제처럼 보입니다. 문제점 보고서 (TPR # 24317)를 제출하여 추가 평가를 위해 컴파일러 엔지니어에게 보냈습니다. 해결 방법으로 내부 루프에 "if"체크를 추가하십시오.

% cat test.cpp 
#include <stdio.h> 
#include <stdlib.h> 

#pragma acc routine seq 
void test (int* x, int const n) { 
    for (unsigned int i = 0; i < n; i++) { 
     x[i] = -1; 
     for (unsigned int k = 0; k < i; k++) { 
     if (k < i) 
      x[i] = (k<i); 
     } 
    } 
} 

int main () { 
    unsigned const n(4); 
    unsigned const nb(3); 
    int x[nb*n]; 
    #pragma acc parallel loop copyout(x[:nb*n]) 
    for (unsigned int b = 0; b < nb; b++) 
     test(x+b*n,n); 

    for (int i=0; i <nb; ++i) { 
    for (int j=0; j <n; ++j) { 
    printf("%d:%d %d\n", i,j, x[i*n+j]); 
    } } 
    exit(0); 
} 
% pgc++ -acc -Minfo=acc -ta=tesla:cc60 test.cpp; a.out 
test(int *, int): 
     5, Generating acc routine seq 
     Generating Tesla code 
main: 
    18, Generating copyout(x[:]) 
     Accelerator kernel generated 
     Generating Tesla code 
     20, #pragma acc loop gang, vector(3) /* blockIdx.x threadIdx.x */ 
0:0 -1 
0:1 1 
0:2 1 
0:3 1 
1:0 -1 
1:1 1 
1:2 1 
1:3 1 
2:0 -1 
2:1 1 
2:2 1 
2:3 1 
+0

고맙습니다. 나는 미쳐 가고있었습니다! 나는'if' 체크로 끝났다. –