Fortran-OpenACC例程如何调用另一个Fortran-OpenACC例程?

时间:2016-10-07 19:43:09

标签: fortran gpgpu openacc pgi pgi-accelerator

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

  

nvvmCompileProgram错误:9。

     

错误:/tmp/pgacc2lMnIf9lMqx8.gpu(144,24):解析对函数' innerroutine _'的无效前向引用错误的类型!

     

PGF90-S-0155-编译器无法转换加速器区域(请参阅-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的例程?

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

1 个答案:

答案 0 :(得分:1)

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

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