! PR libgomp/109837 program main use iso_c_binding use iso_fortran_env use omp_lib implicit none (external, type) !$omp requires unified_address integer(c_intptr_t), parameter :: N = 15 integer :: i, ntgts ntgts = omp_get_num_devices(); if (ntgts > 0) then write (ERROR_UNIT, '(a)') "Offloading devices exist" ! { dg-output "Offloading devices exist(\n|\r\n|\r)" { target offload_device } } else write (ERROR_UNIT, '(a)') "Only host fallback" ! { dg-output "Only host fallback(\n|\r\n|\r)" { target { ! offload_device } } } endif do i = 0, ntgts call test_device (i); end do contains subroutine test_device (dev) integer, value, intent(in) :: dev type t integer(c_intptr_t) :: n, m integer, pointer :: fptr(:) type(c_ptr) :: cptr end type t type(t) :: s type(c_ptr) :: cptr, qptr, cptr2, cptr2a integer, target :: q(4) integer, pointer :: fptr(:) integer(c_intptr_t) :: i s%n = 10; s%m = 23; s%cptr = omp_target_alloc (s%n * NUMERIC_STORAGE_SIZE/CHARACTER_STORAGE_SIZE, dev); cptr = omp_target_alloc (s%m * NUMERIC_STORAGE_SIZE/CHARACTER_STORAGE_SIZE, dev); if (.not. c_associated(s%cptr)) stop 1 if (.not. c_associated(cptr)) stop 2 call c_f_pointer (cptr, s%fptr, [s%m]) cptr = omp_target_alloc (N * NUMERIC_STORAGE_SIZE/CHARACTER_STORAGE_SIZE, dev); if (.not. c_associated(cptr)) stop 3 q = [1, 2, 3, 4] !$omp target enter data map(q) device(device_num: dev) !$omp target data use_device_addr(q) device(device_num: dev) qptr = c_loc(q) !$omp end target data !$omp target map(to:s) device(device_num: dev) block integer, pointer :: iptr(:) call c_f_pointer(s%cptr, iptr, [s%n]) do i = 1, s%n iptr(i) = 23 * int(i) end do do i = 1, s%m s%fptr(i) = 35 * int(i) end do end block cptr2 = c_loc(s%fptr(4)) cptr2a = s%cptr !$omp target firstprivate(qptr) map(tofrom: cptr2) map(to :cptr2a) device(device_num: dev) block integer, pointer :: iptr(:), iptr2(:), qvar(:) call c_f_pointer(cptr2, iptr, [4]) call c_f_pointer(cptr2a, iptr2, [4]) call c_f_pointer(qptr, qvar, [4]) qvar = iptr + iptr2 end block !$omp target exit data map(q) device(device_num: dev) do i = 1, 4 if (q(i) /= 23 * int(i) + 35 * (int(i) + 4 - 1)) stop 4 end do !$omp target map(to: cptr) device(device_num: dev) block integer, pointer :: p(:) call c_f_pointer(cptr, p, [N]) do i = 1, N p(i) = 11 * int(i) end do end block allocate(fptr(N)) if (0 /= omp_target_memcpy (c_loc(fptr), cptr, & N * NUMERIC_STORAGE_SIZE/CHARACTER_STORAGE_SIZE, & 0_c_intptr_t, 0_c_intptr_t, & omp_get_initial_device(), dev)) & stop 5 do i = 1, N if (fptr(i) /= 11 * int(i)) stop 6 end do deallocate (fptr); call omp_target_free (cptr, dev); call omp_target_free (s%cptr, dev); call omp_target_free (c_loc(s%fptr), dev); end end