blob: 52e32b1d6ccada61fb9a4b55634f69bc0dba6177 [file] [edit]
! Show that the ALWAYS map-type modifier on the outer map clause should be
! propagated to the entries pushed by a user-defined mapper. The test uses no
! target region at all: the device data is inspected with omp_get_mapped_ptr()
! and omp_target_memcpy(), so what is checked is purely the data-motion done by
! `target enter data`.
!
! The mapper transfers s%y. We pre-map s%y so that it already has a device copy
! with a nonzero reference count, and set that copy to a known value. Without
! ALWAYS, the `to` of the second `enter data` is suppressed (a present,
! ref-counted entry is not copied), so the host's 111 does not reach the device.
! ALWAYS must force the copy -- but only if ALWAYS is propagated from the outer
! clause to the mapper's s%y entry.
!
! FIXME: ALWAYS is not propagated to the mapper's entries yet, so the transfer
! is currently suppressed and the device copy still reads as 0 (its pre-set
! value). Once ALWAYS is propagated:
! EXPECTED: device s%y = 111
! REQUIRES: flang
! RUN: %libomptarget-compile-fortran-generic
! RUN: %libomptarget-run-generic | %fcheck-generic
program main
use omp_lib
use iso_c_binding
implicit none
type :: s_type
integer(c_int) :: x
integer(c_int) :: y
integer(c_int) :: z
end type s_type
!$omp declare mapper(s_type :: s) map(tofrom: s%y)
type(s_type), target :: s
integer(c_int), target :: dev_y_val
integer :: dev, host, rc
type(c_ptr) :: dev_y
dev = omp_get_default_device()
host = omp_get_initial_device()
s%y = 0
!$omp target enter data map(alloc: s%y)
! The device copy of s%y is uninitialized after `alloc`; set it to 0 so that
! a missing transfer below is distinguishable from garbage.
dev_y = omp_get_mapped_ptr(c_loc(s%y), dev)
rc = omp_target_memcpy(dev_y, c_loc(s%y), int(c_sizeof(s%y), c_size_t), &
0_c_size_t, 0_c_size_t, dev, host)
s%y = 111
!$omp target enter data map(always, to: s)
! ALWAYS should force s%y to the device even though it is already mapped
! (ref count > 0), but the modifier is not propagated yet, so the transfer
! does not happen.
dev_y_val = -1
rc = omp_target_memcpy(c_loc(dev_y_val), dev_y, &
int(c_sizeof(dev_y_val), c_size_t), &
0_c_size_t, 0_c_size_t, host, dev)
print *, "device s%y =", dev_y_val
! CHECK: device s%y = 0
!$omp target exit data map(delete: s%y)
end program main