Hi!

On Wed, 05 Jun 2019 11:25:07 +0200, I wrote:
> I [...] had a look at what OpenMP 5.0
> is saying about Fortran 'allocatable' in 'map' clauses [...]

Will you (Jakub, and/or Fortran guys), please have a look at the attached
test case.

If I disable the '!$omp declare target (ar)', then this works with
offloading enabled, otherwise it fails, and here is my understanding what
happens.

With '!$omp declare target (ar)' active, the array descriptor globally
gets allocated on the device, via the 'offload_vars' handling in
'gcc/omp-offload.c' etc.

Then, in 'gcc/omp-low.c:scan_sharing_clauses', the 'GOMP_MAP_TO_PSET(ar)'
(which would update the array descriptor on the device after the
host-side 'allocate') gets removed, because 'Global variables with "omp
declare target" attribute don't need to be copied, the receiver side will
use them directly'.  So, on the device, we'll still have the dummy
(unallocated) array descriptor, and will thus fail.

But even with that behavior disabled, we'll still fail, because in
'libgomp/target.c:gomp_map_vars_internal', when processing the
'GOMP_MAP_TO_PSET(ar)', we find that 'ar' has already been mapped
(globally, as mentioned above), so for 'n && n->refcount !=
REFCOUNT_LINK', we'll call 'gomp_map_vars_existing', and that one again
won't update device-side the array descriptor, because it's not
'GOMP_MAP_ALWAYS_TO_P'.

Indeed, if I use '!$omp declare target link(ar)' ('link' added), then
things seem to work as expected.

Unless I got something wrong, at which level do you suggest this should
be fixed?


Grüße
 Thomas


! { dg-do run }

module mod
  implicit none
  integer, parameter :: n = 40
  integer, allocatable :: ar(:,:,:)
  !$omp declare target (ar)
end module mod

program main
  use mod
  implicit none

  integer :: i
  integer, parameter :: ar_rank = rank(ar)
  integer :: ar_rank_v
  integer :: ar_size_v
  integer, dimension(ar_rank) :: ar_extent_v
  integer, dimension(ar_rank) :: ar_shape_v

  allocate (ar(n,0:n+1,-1:n+2))
  !$omp target enter data map(alloc:ar)

  !$omp target map(from:ar_rank_v, ar_size_v, ar_extent_v, ar_shape_v)
  ar_rank_v = rank(ar)
  ar_size_v = size(ar)
  do i = 1, ar_rank
     ar_extent_v(i) = size(ar, i)
  end do
  ar_shape_v = shape(ar)
  !$omp end target

  print *, ar_rank_v
  if (ar_rank_v /= rank(ar)) error stop
  print *, ar_size_v
  if (ar_size_v /= size(ar)) error stop
  print *, ar_extent_v
  if (any (ar_extent_v /= shape(ar))) error stop
  print *, ar_shape_v
  if (any (ar_shape_v /= shape(ar))) error stop
end program main

Attachment: signature.asc
Description: PGP signature

Reply via email to