Hello,
Here i am trying to parallelize my sequencial fortran code and offload to NVIDIA GPU with OpenACC (PGF90 compiler).
My code (test.f90) is written in following way-
Program main
use openacc
IMPLICIT NONE
// variable declarations
//blah blah
!$acc parallel loop
do i =1,1000
p(i) = a(i) + BESS(i*a(i))
enddo
!$acc end parallel
//blah blah
End Program main
Function BESS(x)
IMPLICIT NONE
REAL*8 x, BESS
BESS = SQRT(5)*(COS(x)*3-SIN(x)) // example
RETURN
END FUNCTION BESS
When i am trying to compile using below command -
pgf90 -acc test.f90
It giving me the following massage-
Procedures called in a compute region must have acc routine information: BESS (test.f90: 85)
Can someone help me to figure out this problem?
Hi aviggupta0123,
In order to call a routine within device code, there must be a device callable version available. To do this in OpenACC, you’ll need to decorate the routine with a “!$acc routine” directive so the compiler knows to create the device version. Something like:
Function BESS(x)
IMPLICIT NONE
!$acc routine
REAL*8 x, BESS
BESS = SQRT(5)*(COS(x)*3-SIN(x)) // example
RETURN
While this creates the device version of BESS, the compiler also needs to know at call site that there is a device version available. If BESS is in a module, the compiler has access to this information from the module prototype. However if the code is using F77 style API calling (as you show it in the example), you’ll also need to include a second routine directive in the same unit as the call.
IMPLICIT NONE
! variable declarations
! I assume you have something like so the compile knows BESS is a function
REAL*8 BESS
! add routine just after this
!$acc routine(BESS)
! code
!$acc parallel loop
do i =1,1000
p(i) = a(i) + BESS(i*a(i))
enddo
Hope this helps,
Mat