本文介绍了一个Fortran-OpenACC例程如何调用另一个Fortran-OpenACC例程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently attempting to accelerate a spectral element fluids solver by porting most of the routines to a GPGPU using OpenACC with the PGI (15.10) compiler. The source code is written in OO-Fortran. This software has "layers" of subroutines that call other functions and subroutines. To bring the code over to a GPU using openacc, I've been first attempting to place "$acc routine" directives in each routine that needs to be ported. During compilation, using "pgf90 -acc -Minfo=accel", I receive the following error :

错误:/tmp/pgacc2lMnIf9lMqx8.gpu(146,24):解析类型错误的函数'innerroutine_'的无效正向引用!

Error: /tmp/pgacc2lMnIf9lMqx8.gpu (146, 24): parse invalid forward reference to function 'innerroutine_' with wrong type!

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

PGF90-S-0155-Compiler failed to translate accelerator region (see -Minfo messages): Device compiler exited with error status code (Test.f90: 1)

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

This same problem can be reproduced with the following simple fortran program :

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"编译以上程序.产生了问题.

Again, compiling the above program with "pgf90 -acc -Minfo=accel" yields the problem.

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

Does openacc support acc-enabled routines calling other acc-enabled routines ?

如果是,我在做什么错了?

If so, what am I doing wrong ?

推荐答案

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

You're using the OpenACC "routine" directive correctly. The problem here is that we (PGI) don't yet support using "routine" with array-valued functions. The problem being that this support requires the compiler to create a temp array to hold the return value. Meaning that every thread would need to allocate this temp array causing a severe performance penalty. Worse is how to handle sharing the temp array if is a gang or worker level routine.

我们确实对此功能有公开的要求,但是可能要过一段时间才能解决.同时,您可以尝试内联例程吗?即使用"-Minline"进行编译.

We do have open requests for this feature, but it may be awhile before we can address it. In the meantime, can you try inlining the routine? i.e. compile with "-Minline".

这篇关于一个Fortran-OpenACC例程如何调用另一个Fortran-OpenACC例程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-13 07:36