Hi,
We have some utility fonctions which may be either run on the CPU or on the GPU. In oder to distinguish between the 2 cases we introduced some logical so as to ignore the directives or not. This use to work with PGI 12.10 but not anymore with 13.2 (I didn’t try 13.1).
I’ve made a reproducible example:
module data_field
implicit none
real*8, allocatable :: a(:,:,:),b(:,:,:)
END module data_field
module computation
implicit none
contains
! compute a=a+b
subroutine my_add(n1,n2,n3,a,b,lgpu)
integer, intent(in) :: n1,n2,n3
real*8, intent(inout) :: a(n1,n2,n3)
real*8, intent(in) :: b(n1,n2,n3)
logical, intent(in) :: lgpu
integer :: i,j,k
!$acc data present(a,b) if(lgpu)
!$acc parallel vector_length(64) if(lgpu)
DO k=1,n3
!$acc loop gang
DO j=1,n2
!$acc loop vector
DO i=1,n1
a(i,j,k)=a(i,j,k)+b(i,j,k)
END DO
END DO
END DO
!$acc end parallel
!$acc end data
end subroutine my_add
end module computation
program main
USE data_field, only: a,b
USE computation, only: my_add
implicit none
integer :: nargs
character*10 arg
integer :: n1,n2,n3
nargs = command_argument_count()
n3=60
if( nargs == 2 ) then
call getarg( 1, arg )
read(arg,"(I8)") n1
call getarg( 2, arg )
read(arg,"(I8)") n2
else
print*, 'usage ./test n1 n2'
STOP
endif
allocate(a(n1,n2,n3),b(n1,n2,n3))
!init
a(:,:,:)=0.1D0
b(:,:,:)=0.2D0
!some computation on the CPU
!a,b are not allocated on the GPU
!at this point
call my_add(n1,n2,n3,a,b,.FALSE.)
!some computation on the GPU
!$acc data copy(a), copyin(b)
!a,b are on the GPU
call my_add(n1,n2,n3,a,b,.TRUE.)
!$acc end data
write(*,'(A,F10.1)') 'Result: ', sum(a)
DEALLOCATE(a,b)
end program main
With pgi 12.10 I get:
> pgf90 -acc -ta=nvidia -o test_if test_if.f90
Result: 491520.0
With pgi 13.2:
> pgf90 -acc -ta=nvidia -o test_if test_if.f90
FATAL ERROR: data in PRESENT clause was not found on device 1: name=b
file:/users/lapixa/GPU/test_openacc/PGI_bug/test_if.f90 my_add line:23
This looks to me like a bug ? Or is it not a valide way of using if statment with OpenACC directives ?
Best regards,
Xavier