blob: b06a88415b47f9cbd684ec607d294fd52c64cf85 [file] [log] [blame]
! { dg-do run }
! Check whether absent optional arguments are properly
! handled with use_device_{addr,ptr}.
program main
use iso_c_binding, only: c_ptr, c_loc, c_associated, c_f_pointer
implicit none (type, external)
integer, target :: u
integer, target :: v
integer, target :: w
integer, target :: x(4)
integer, target, allocatable :: y
integer, target, allocatable :: z(:)
type(c_ptr), target :: cptr
type(c_ptr), target :: cptr_in
integer :: dummy
u = 42
v = 5
w = 7
x = [3,4,6,2]
y = 88
z = [1,2,3]
!$omp target enter data map(to:u)
!$omp target data map(to:dummy) use_device_addr(u)
cptr_in = c_loc(u) ! Has to be outside 'foo' due to 'intent(in)'
!$omp end target data
call foo (u, v, w, x, y, z, cptr, cptr_in)
deallocate (y, z)
contains
subroutine foo (u, v, w, x, y, z, cptr, cptr_in)
integer, target, optional, value :: v
integer, target, optional :: u, w
integer, target, optional :: x(:)
integer, target, optional, allocatable :: y
integer, target, optional, allocatable :: z(:)
type(c_ptr), target, optional, value :: cptr
type(c_ptr), target, optional, value, intent(in) :: cptr_in
integer :: d
type(c_ptr) :: p_u, p_v, p_w, p_x, p_y, p_z, p_cptr, p_cptr_in
!$omp target enter data map(to:w, x, y, z)
!$omp target data map(dummy) use_device_addr(x)
cptr = c_loc(x)
!$omp end target data
! Need to map per-VALUE arguments, if present
if (present(v)) then
!$omp target enter data map(to:v)
else
stop 1
end if
if (present(cptr)) then
!$omp target enter data map(to:cptr)
else
stop 2
end if
if (present(cptr_in)) then
!$omp target enter data map(to:cptr_in)
else
stop 3
end if
!$omp target data map(d) use_device_addr(u, v, w, x, y, z)
!$omp target data map(d) use_device_addr(cptr, cptr_in)
if (.not. present(u)) stop 10
if (.not. present(v)) stop 11
if (.not. present(w)) stop 12
if (.not. present(x)) stop 13
if (.not. present(y)) stop 14
if (.not. present(z)) stop 15
if (.not. present(cptr)) stop 16
if (.not. present(cptr_in)) stop 17
p_u = c_loc(u)
p_v = c_loc(v)
p_w = c_loc(w)
p_x = c_loc(x)
p_y = c_loc(y)
p_z = c_loc(z)
p_cptr = c_loc(cptr)
p_cptr_in = c_loc(cptr_in)
!$omp end target data
!$omp end target data
call check(p_u, p_v, p_w, p_x, p_y, p_z, p_cptr, p_cptr_in, size(x), size(z))
end subroutine foo
subroutine check(p_u, p_v, p_w, p_x, p_y, p_z, p_cptr, p_cptr_in, Nx, Nz)
type(c_ptr), value :: p_u, p_v, p_w, p_x, p_y, p_z, p_cptr, p_cptr_in
integer, value :: Nx, Nz
integer, pointer :: c_u(:), c_v(:), c_w(:), c_x(:), c_y(:), c_z(:)
type(c_ptr), pointer :: c_cptr(:), c_cptr_in(:)
! As is_device_ptr does not handle scalars, we map them to a size-1 array
call c_f_pointer(p_u, c_u, shape=[1])
call c_f_pointer(p_v, c_v, shape=[1])
call c_f_pointer(p_w, c_w, shape=[1])
call c_f_pointer(p_x, c_x, shape=[Nx])
call c_f_pointer(p_y, c_y, shape=[1])
call c_f_pointer(p_z, c_z, shape=[Nz])
call c_f_pointer(p_cptr, c_cptr, shape=[1])
call c_f_pointer(p_cptr_in, c_cptr_in, shape=[1])
call run_target(c_u, c_v, c_w, c_x, c_y, c_z, c_cptr, c_cptr_in, Nx, Nz)
end subroutine check
subroutine run_target(c_u, c_v, c_w, c_x, c_y, c_z, c_cptr, c_cptr_in, Nx, Nz)
integer, target :: c_u(:), c_v(:), c_w(:), c_x(:), c_y(:), c_z(:)
type(c_ptr) :: c_cptr(:), c_cptr_in(:)
integer, value :: Nx, Nz
!$omp target is_device_ptr(c_u, c_v, c_w, c_x, c_y, c_z, c_cptr, c_cptr_in) map(to:Nx, Nz)
call target_fn(c_u(1), c_v(1), c_w(1), c_x, c_y(1), c_z, c_cptr(1), c_cptr_in(1), Nx, Nz)
!$omp end target
end subroutine run_target
subroutine target_fn(c_u, c_v, c_w, c_x, c_y, c_z, c_cptr, c_cptr_in, Nx, Nz)
!$omp declare target
integer, target :: c_u, c_v, c_w, c_x(:), c_y, c_z(:)
type(c_ptr), value :: c_cptr, c_cptr_in
integer, value :: Nx, Nz
integer, pointer :: u, x(:)
if (c_u /= 42) stop 30
if (c_v /= 5) stop 31
if (c_w /= 7) stop 32
if (Nx /= 4) stop 33
if (any (c_x /= [3,4,6,2])) stop 34
if (c_y /= 88) stop 35
if (Nz /= 3) stop 36
if (any (c_z /= [1,2,3])) stop 37
if (.not. c_associated (c_cptr)) stop 38
if (.not. c_associated (c_cptr_in)) stop 39
if (.not. c_associated (c_cptr, c_loc(c_x))) stop 40
if (.not. c_associated (c_cptr_in, c_loc(c_u))) stop 41
call c_f_pointer(c_cptr_in, u)
call c_f_pointer(c_cptr, x, shape=[Nx])
if (u /= c_u .or. u /= 42) stop 42
if (any (x /= c_x)) stop 43
if (any (x /= [3,4,6,2])) stop 44
end subroutine target_fn
end program main