Subroutines called within an accelerator region

Hi,

I am working with PVF 14.6. I have a problem when I try to accelerate a code which contains calls to subroutines. I have read some posts and manuals related with that but I am still not able to fix my problem.

Firstly, I have used the –Minline and –Minfo=inline flags. I have noticed that my subroutines are not automatically inlineable and therefore the accelerator region which contains de calls to the subroutines is ignored. The error messages that I get are these:

Sub1_internal_cond:
1534, subprogram not inlineable -- contains data, save, or equivalence
Sub2_internal_cond_roof:
1728, subprogram not inlineable -- contains data, save, or equivalence
[...]
E:\Program_ACC\hidrodinamica2D.for(388) : error S0155 : Accelerator region ignored; see -Minfo messages
388, Accelerator region ignored
389, Accelerator restriction: function/procedure calls are not supported
762, Accelerator restriction: unsupported call to 'Sub2_internal_cond_roof'
0 inform,   0 warnings,   1 severes, 0 fatal for hidrodinamica2d

Then I have used the “acc routine” directive introduced in OpenACC 2.0 to build a device version of my subroutine. But again error messages appears:

E:\Program_ACC\aux2D.for(1) : error S0155 : Compiler failed to translate accelerator region (see -Minfo messages): Load of NULL symbol
Sub2_internal_cond_roof:
   1728, subprogram not inlineable -- contains data, save, or equivalence
         Generating acc routine seq
  0 inform,   0 warnings,   1 severes, 0 fatal for Sub2_internal_cond_roof

This is the code of one of the subroutines which I want to inline:

(1728)  subroutine Sub2_internal_cond_roof(iarista,lado,ielem,iel)

        use modul1_            
        use modul3
        use modul8
        use modul235
        use modul6i7
        use ccint
        implicit real*8(a-h,o-z)
        include 'Prog_commons.txt'

!$acc routine seq
	       
        if (iroof(ielem).eq.0 .and. iroof(iel).eq.1) then
         if(h(iel)+znod(iel).gt.zroof(1,iel)) then
            anx=anext(1,lado,ielem)
            any=anext(2,lado,ielem)
            ul=u(ielem)*anx+v(ielem)*any
            hl=max(h(ielem),0.)     
            ur=u(iel)*anx+v(iel)*any
            hr=max(h(iel),0.)                                   
            util=(ur*sqrt(hr)+ul*sqrt(hl))/(sqrt(hr)+sqrt(hl))
         if(fluxup(iarista).gt.0) then
            itag2=1
            salto_lambda_ar(iarista)=salto_lambda_ar(iarista)
     .      +alroof(1,ielem)*util**2./2./9.81
     .      *dble(itag2)
            continue
         elseif (fluxup(iarista).lt.0) then
            itag2=-1
            salto_lambda_ar(iarista)=salto_lambda_ar(iarista)
     .      +alroof(1,ielem)*util**2./2./9.81
     .      *dble(itag2)
            continue
         endif
       endif      
      endif
      
      if (iroof(ielem).eq.1 .and. iroof(iel).eq.0) then
       if(h(ielem)+znod(ielem).gt.zroof(1,ielem)) then
            anx=anext(1,lado,ielem)
            any=anext(2,lado,ielem)
            ul=u(ielem)*anx+v(ielem)*any
            hl=max(h(ielem),0.)     
            ur=u(iel)*anx+v(iel)*any
            hr=max(h(iel),0.)                                   
            util=(ur*sqrt(hr)+ul*sqrt(hl))/(sqrt(hr)+sqrt(hl))
         if(fluxup(iarista).gt.0) then
            itag2=1
            salto_lambda_ar(iarista)=salto_lambda_ar(iarista)
     .      +alroof(1,ielem)*util**2./2./9.81
     .      *dble(itag2)
            continue
         elseif (fluxup(iarista).lt.0) then
            itag2=-1
            salto_lambda_ar(iarista)=salto_lambda_ar(iarista)
     .      +alroof(1,ielem)*util**2./2./9.81
     .      *dble(itag2)
            continue
         endif
       endif      
      endif
      
      return
      end

The problem might come in the “use” clauses at the beginning of the subroutine because these modules contain “save”. I have changed the way the variables are called in the subroutine to avoid the “use” clause calling them by arguments instead of by modules. In this case (I do not understand why) the messages regarding if the subroutine is inlineable or not just do not appears but the problem of the ignored accelerator region because of the “unsupported call to 'Sub2_internal_cond_roof” still remains. In addition, the “acc routine” directive gives the same error as before.

Could you please give me some advice about why the automatically inlining and the “acc routine” directive do not work here and about how to call my subroutines inside the acceleration region in this particular case?

Thank you very much,
Martí

Hi Marti,

What is in Prog_commons.txt?

Read carefully the section in pgi documentation devoted to restrictions on function inlining.

Alexey

Hi Alexey,

Prog_commons.txt is just a file where there are variables which are common by the whole program. A piece of it is as follows:

common/dat001/xxr,nsecr
common/dat002/aaa,coment,gdib

But I have seen that I can get rid of it here. Maybe it is interfering in the inlining.

I will follow your suggestion and read again the documentation before asking you again.

Thank you,
Martí

Hi Martri,

We just added support to 14.7 to allow for extern data and module data in OpenACC “routines”. However, we’re still working on allowing common blocks.

If possible, please update to 14.7 and move the common block to a module. Also, make sure the “declare” directive in your modules so that the module data is available on the device. Using “routine” will be the better way to go since it will be more difficult to try and inline this routine.

Hope this helps,
Mat