Compiler confusing arrays for functions

We have a problem where the compiler is supressing acceleration becuase it believes some of our arrays are functions. At first I assumed this was due to it being a part of a large and complex code (MFIX), but we have boiled it down to the demonstration code below (which I would be happy to send through other channels). This code generates:

PGF90-W-0155-Accelerator region ignored; see -Minfo messages (test.f90: 51)
main:
51, Accelerator region ignored
56, Accelerator restriction: function/procedure calls are not supported
60, Accelerator restriction: function/procedure calls are not supported

If we simply comment out line 60 (array PFN), then it will generate a kernel. Grateful for any insight.

John


!!! Update the list of particles contacting a given particle, by removing particles no longer in contact
!!! Compile with
!!! pgf90 -Munixlogical -o test test.f90
!!! or
!!! pgf90 -acc -ta=nvidia,time -Minfo=accel -Munixlogical -o test-gpu test.f90

PROGRAM MAIN

IMPLICIT NONE

INTEGER, DIMENSION(3,11) :: PN, PV
DOUBLE PRECISION, DIMENSION(3,11,2) :: PFN
INTEGER LL, NI, NLIM, MAXNEIGHBORS, MAX_PIP

!!! Extra variables needed for new algorithm
INTEGER CHK1, CHK2, SHIFT

!!! Input data for the test
MAX_PIP=3
MAXNEIGHBORS = 10

PN(1,:)=(/7, 5,11,33,20,17,35,4,-1,-1,-1/)
PV(1,:)=(/7, 1, 0, 1, 1, 0, 0,1, 0, 0, 0/)
PFN(1,:,1)=PN(1,:)
PFN(1,:,2)=PV(1,:)

PN(2,:)=(/10, 5,11,33,20,17,35,4,111,12,13/)
PV(2,:)=(/10, 0, 0, 0, 0, 0, 0,0, 1, 0, 0/)
PFN(2,:,1)=PN(1,:)
PFN(2,:,2)=PV(1,:)

PN(3,:)=(/2, 39,101,-1,-1,-1,-1,-1,-1,-1,-1/)
PV(3,:)=(/2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/)
PFN(3,:,1)=PN(1,:)
PFN(3,:,2)=PV(1,:)
!!! End of input data

!!! Print the input data
PRINT , ‘Before update:’
PRINT , ‘==============’
DO LL=1, MAX_PIP
WRITE (
,‘(1X,I3,1X,A,I3)’) &
PN(LL,1), ’ particles in contact with particle ', LL
WRITE (
,‘(A,$)’) ‘They are: ’
DO NI=2,PN(LL,1)+1
WRITE (*,’(I4,1X,$)‘), PN(LL,NI)
ENDDO
PRINT *,’\n\n’
ENDDO

!$acc kernels
DO LL=1,MAX_PIP !Loop over particles

!!! New update algorithm without if statement
SHIFT=0
DO NI=2,PN(LL,1)+1
CHK1 = (PV(LL,NI).EQ.0)
CHK2 = (PV(LL,NI).NE.0)
PN(LL,NI-SHIFTCHK2)=PN(LL,NI)
PFN(LL,NI-SHIFT
CHK2,:)=PFN(LL,NI,:)
SHIFT=SHIFT+CHK1
ENDDO
PN(LL,1)=PN(LL,1)-SHIFT

ENDDO !Loop over particles
!$acc end kernels

!!! Print the results
PRINT , ‘After update:’
PRINT , ‘=============’
DO LL=1,MAX_PIP
WRITE (
,‘(1X,I3,1X,A,I3)’) &
PN(LL,1), " particles in contact with particle ", LL
WRITE (
,‘(A,$)’) "They are: "
DO NI=2,PN(LL,1)+1
WRITE (*,‘(I4,1X,$)’), PN(LL,NI)
ENDDO
PRINT *,‘\n’

! PRINT *, “The full arrays PN and PV are :”
! DO NI=2,MAX_NEIGHBOURS+1
! PRINT *, PN(LL,NI), " ",PV(LL,NI)
! ENDDO

ENDDO

END

Hi Urban,

What’s happening is the compiler is creating a temp array to hold the right-hand side evaluation of the “PVN=PVN” assignment. This causes an implicit allocate/deallocate in the loop and it’s these routines that this preventing the creation of the accelerator region.

This is one of those cases were the compiler is being more safe than smart. The temp array isn’t really needed but the compiler is doing it in case their is an overlap in the assignment. While ok (at least for CPU execution) it is at least a performance bug. Hence we have opened TPR#18865 to have it fixed.

For your code, you can work around the problem by pre-computing the second index before using it in the PVN assignment. For example:

#ifdef NOTEMP
idx=ni-shift*chk2
pfn(ll,idx,:)=pfn(ll,ni,:)
#else
pfn(ll,ni-shift*chk2,:)=pfn(ll,ni,:)
#endif

Thanks,
Mat

Thanks, Mat.

Makes perfect sense and I suspect this workaround will be useful for similar code that lies ahead.

I would suggest that the offending “procedure” always be named. If we had seen a malloc reported here, it would have been a useful clue.

John

I would suggest that the offending “procedure” always be named. If we had seen a malloc reported here, it would have been a useful clue.

Added a feature request, TPR#18875.

  • Mat

I’ve got similar error on PGI 12.8.

With test file

Program test
real, device :: H(2,32,10), F(2,32,10)
!$cuf kernel do(1) <<< *, 32>>>      
Do i=1, 32
  H(1,i,1)=F(1,i,1)+12
End Do
end

I get error when trying to compile with some debug options:

pgf95 -g -O0 -C -Mcuda=cc11 -ta=nvidia:cc11 -tp=amd64 -Minfo test.f95
PGF90-S-0155-Kernel region ignored; see -Minfo messages (test.f95: 3)
test:
4, Accelerator restriction: function/procedure calls are not supported
5, Accelerator restriction: function/procedure calls are not supported
0 inform, 0 warnings, 1 severes, 0 fatal for test

But when i remove -O0, this error goes away

pgf95 -g -C -Mcuda=cc11 -ta=nvidia:cc11 -tp=amd64 -Minfo test.f95
PGF90-S-0155-Kernel region ignored; no parallel loops (test.f95: 3)
0 inform, 0 warnings, 1 severes, 0 fatal for test

In my large project, the same error produced with -C option enabled, instead of -O0. But i think, reason is similar.

Hi Senya,

“-C” adds bounds checking which is not supported on the device. Please remove this flag.

The reason why removing “-O0” works, is because dead code elimination optimization will remove this code since “H” is never used. Hence the “-Kernel region ignored; no parallel loops” message.

Hope this helps,
Mat

Is it possible to make -C option work only for host, when using device code also? Array bounds checking is critical for finding code errors sometimes.

Hi Sayan,

Let me check. Though the person best qualified to answer this is out till Monday.

  • Mat

TPR 18875 - ACC: Add which procedure i spreventing acceleration in -Minfo msg
has been implemented in the 14.9 release.

thanks for the observation.

dave