我目前正在尝试通过使用带有PGI(15.10)编译器的OpenACC将大多数例程移植到GPGPU来加速光谱元素流体求解器 . 源代码是用OO-Fortran编写的 . 该软件具有调用其他函数和子程序的子程序“层” . 为了使用openacc将代码转移到GPU,我首先尝试在每个需要移植的例程中放置“$ acc routine”指令 . 在编译期间,使用“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的例程?
如果是这样,我做错了什么?
1 回答
您正确使用OpenACC“例程”指令 . 这里的问题是我们(PGI)还不支持使用带有数组值函数的“例程” . 问题是这种支持需要编译器创建一个临时数组来保存返回值 . 这意味着每个线程都需要分配此临时数组,从而导致严重的性能损失 . 更糟糕的是如果是帮派或 Worker 级别例程,如何处理共享临时数组 .
我们确实有对此功能的开放请求,但在我们解决它之前可能还需要一段时间 . 在此期间,您可以尝试内联例程吗?即用“-Minline”编译 .