OpenACC, Procedures called in a compute region must have acc routine information (fortran)

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