C++ OpenACC-嵌套循环奇怪的行为

C++ OpenACC-嵌套循环奇怪的行为,c++,nested-loops,openacc,C++,Nested Loops,Openacc,我正在研究如何使用OpenACC。 当我按顺序运行代码时,我得到了正确的分解,而当根据OPECAC指令执行代码时,我在执行分解时得到了错误的结果 LU分解涉及该类型的嵌套循环(请参见LUPSolve函数): 我得到的结果是: x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 但正确的答案(我在没有OpenACC的情况下运行代码时得到的答案)应该是: x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 我一定是做错了什么,因为当I

我正在研究如何使用OpenACC。
当我按顺序运行代码时,我得到了正确的分解,而当根据OPECAC指令执行代码时,我在执行分解时得到了错误的结果

LU分解涉及该类型的嵌套循环(请参见
LUPSolve
函数):

我得到的结果是:

x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
但正确的答案(我在没有OpenACC的情况下运行代码时得到的答案)应该是:

x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1,
我一定是做错了什么,因为当
I=0

时,它不应该进入嵌套循环
另外,当我将循环直接放在并行区域(不使用函数调用)时,它确实工作得很好。

看起来像是一个编译器代码生成器问题,它总是执行内部循环,即使k和I都为零。我已经提交了一份问题报告(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
%cat test.cpp
#包括
#包括
#pragma acc例行程序序列
无效测试(int*x,int const n){
for(无符号整数i=0;ix[i]=(k看起来像是编译器代码生成器问题,即使k和i都为零,它也总是执行内部循环。我已经提交了一份问题报告(TPR#24317),并将其发送给我们的编译器工程师进行进一步评估。作为解决方法,在内部循环中添加一个“如果”检查

% 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
%cat test.cpp
#包括
#包括
#pragma acc例行程序序列
无效测试(int*x,int const n){
for(无符号整数i=0;ix[i]=(kIt非常奇怪,我也尝试过这种类型的嵌套循环:
for(int i=n-1;i>=0;i--){for(int k=i+1;k
,设备不会进入
i=n-1
的嵌套循环,但如果我将其更改为:
for(int i=n-1;i>=0;i--){for(int k=0;k
同样的奇怪行为发生了,设备进入了
i=n-1
的嵌套循环……这就像
0这很奇怪,我也尝试过这种类型的嵌套循环:
for(int i=n-1;i>=0;i--){for(int k=i+1;k
并且设备不会进入
i=n-1
的嵌套循环,但是如果我将其更改为:
for(int i=n-1;i>=0;i--){for(int k=0;k
同样的奇怪行为发生了,设备进入了
i=n-1
的嵌套循环……这就像
0谢谢你,我疯了!我最后还进行了
if
检查fyi,原来的问题(TPR 24317)是在PGI 19.1版中修复的谢谢你我快疯了!我最后还做了一个
if
检查。仅供参考,原始问题(TPR#24317)在PGI 19.1版中修复
% 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