Hello,
I have a puzzling behavior when calling an interface with OpenACC host_data
construct, from a data region created with !$acc data [...]
or !$acc enter data [...]
.
The Fortran code is compiled with PGI (v.21.5 aka nvfortran) ; the main program calls the following interface (minimal example):
! mod_interface.f90
MODULE mod_interface
IMPLICIT NONE
PUBLIC :: func
INTERFACE func
SUBROUTINE func_host(nd, arr1, arr2)
IMPLICIT NONE
INTEGER, INTENT(IN) :: nd
COMPLEX*16, INTENT(INOUT) :: arr1(:)
COMPLEX*16, INTENT(IN) :: arr2(:)
END SUBROUTINE
SUBROUTINE func_dev(nd, arr1, arr2)
USE cudafor
IMPLICIT NONE
INTEGER, INTENT(IN) :: nd
COMPLEX*16, DEVICE, INTENT(INOUT) :: arr1(:)
COMPLEX*16, INTENT(IN) :: arr2(:)
END SUBROUTINE
END INTERFACE
END MODULE mod_interface
In main.f90
both arr1 and arr2 are copied on device with OpenACC data directives, and the interface is called with the host_data use_device(arr1)
construct to resolve the interface (minimal example):
! main.f90
PROGRAM main
USE mod_interface
IMPLICIT NONE
INTEGER, PARAMETER :: nd=1000
COMPLEX*16, ALLOCATABLE, DIMENSION(:) :: ahost
COMPLEX*16, ALLOCATABLE, DIMENSION(:) :: adev
ALLOCATE( ahost(nd), adev(nd) )
!$acc data copyin(adev,ahost)
!$acc host_data use_device(adev)
CALL func(nd,adev,ahost)
!$acc end host_data
!$acc end data
END PROGRAM
I get an unexpected error message when compiling with pgf90 -acc -cuda -Minfo=accel mod_interface.f90 main.f90
:
NVFORTRAN-S-0155-Ambiguous interfaces for generic procedure func (main.f90: 13)
0 inform, 0 warnings, 1 severes, 0 fatal for main
However, when using the enter data directive as in the following,
!main.f90
PROGRAM main
USE mod_interface
IMPLICIT NONE
INTEGER, PARAMETER :: nd=1000
COMPLEX*16, ALLOCATABLE, DIMENSION(:) :: ahost
COMPLEX*16, ALLOCATABLE, DIMENSION(:) :: adev
ALLOCATE( ahost(nd), adev(nd) )
!$acc enter data copyin(adev,ahost)
!$acc host_data use_device(adev)
call func(nd,adev,ahost)
!$acc end host_data
!$acc exit data copyout(adev,ahost)
END PROGRAM
the code is compiled and executed without errors.
In both cases, I would expect that the host_data
region tells the compiler to use the device copy of arr1, while the host copy of arr2 is taken as a default, even if it is present on device. According to this minimal example, this seems to be true only whitin an enter data / exit data construct. Which is the difference between the two data constructs, and how is it related to the ambiguity of the interface?
Thank you for your help,
Laura