| ! { 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 |