0

我目前正在尝试通过使用带有 PGI (15.10) 编译器的 OpenACC 将大部分例程移植到 GPGPU 来加速光谱元素流体求解器。源代码是用 OO-Fortran 编写的。该软件具有调用其他功能和子程序的子程序“层”。为了使用 openacc 将代码带到 GPU 上,我首先尝试在每个需要移植的例程中放置“$accroutine”指令。在编译期间,使用“pgf90 -acc -Minfo=accel”,我收到以下错误:

nvvmCompileProgram 错误:9。

错误:/tmp/pgacc2lMnIf9lMqx8.gpu (146, 24): 使用错误类型解析对函数“innerroutine_”的无效前向引用!

PGF90-S-0155-Compiler 无法转换加速器区域(请参阅 -Minfo 消息):设备编译器以错误状态代码退出 (Test.f90: 1)

可以使用以下简单的 fortran 程序重现同样的问题:

PROGRAM Test
IMPLICIT NONE

CONTAINS

 SUBROUTINE OuterRoutine( sol, xF, N )
 !$acc routine
   IMPLICIT NONE
   INTEGER :: N
   REAL(KIND=8) :: sol(0:N,1:3)
   REAL(KIND=8) :: xF(0:N,1:3)
   ! LOCAL
   INTEGER :: i

      DO i = 0, N
         xF(i,1:3) = InnerRoutine( sol(i,1:3) )
      ENDDO

 END SUBROUTINE OuterRoutine
 FUNCTION InnerRoutine( sol ) RESULT( xF )
 !$acc routine
   IMPLICIT NONE
   REAL(KIND=8) :: sol(1:3)
   REAL(KIND=8) :: xF(1:3)

      xF(1) = sol(1)*sol(2)
      xF(2) = sol(1)*sol(3)
      xF(3) = sol(1)*sol(1)

 END FUNCTION InnerRoutine

END PROGRAM Test

同样,使用“pgf90 -acc -Minfo=accel”编译上述程序会产生问题。

openacc 是否支持启用 acc 的例程调用其他启用 acc 的例程?

如果是这样,我做错了什么?

4

1 回答 1

2

您正确使用了 OpenACC“例程”指令。这里的问题是我们(PGI)还不支持将“例程”与数组值函数一起使用。问题在于这种支持需要编译器创建一个临时数组来保存返回值。这意味着每个线程都需要分配这个临时数组,从而导致严重的性能损失。如果是帮派或工人级别的例程,更糟糕的是如何处理共享临时数组。

我们确实有对此功能的公开请求,但我们可能需要一段时间才能解决它。同时,您可以尝试内联例程吗?即用“-Minline”编译。

于 2016-10-07T20:16:17.807 回答