On 20/01/2026 13:17, Tobias Burnus wrote:
The original starting point is the following program where for
the first 'target' region, Cray ftn works (accepting the 'present')
but gfortran fails with:

The following program fails with GCC (and hopefully
correctly applied patches) with:
   libgomp: Trying to map into
     device [0x62d1a50..0x62d1b00) object
     when   [0x62d1a50..0x62d1aa8) is already mapped

which I find rather odd. If one uses 'to' instead of 'present'
(+ some ignored map type, let's pick: 'alloc'), it works with
GCC as well.
...
-------------------------
module m
   implicit none
   type field_type
     real(kind=8), allocatable :: density0(:,:), density1(:,:)
   end type field_type

   type tile_type
     type(field_type) :: field
   end type tile_type

   type chunk_type
     real(kind=8), allocatable :: left_rcv_buffer(:)
     type(tile_type), allocatable :: tiles(:)
   end type chunk_type

   type(chunk_type) :: chunk
end

use m
implicit none
allocate(chunk%tiles(1))
chunk%tiles(1)%field%density0 = reshape([1,2,3,4],[2,2])

!$omp target enter data &
!$omp   map(to: chunk%tiles(1)%field%density0) &
!$omp   map(to: chunk%tiles(1)%field%density1)

!$omp target map(present, alloc: chunk%tiles(1)%field%density0)
!  if (.not. allocated(chunk%tiles(1)%field%density0)) stop 1
!  if (any (chunk%tiles(1)%field%density0 /= reshape([1,2,3,4],[2,2]))) stop 1
   chunk%tiles(1)%field%density0 = chunk%tiles(1)%field%density0 * 2
!$omp end target

chunk%tiles(1)%field%density1 = reshape([11,22,33,44],[2,2])

!$omp target map(present, alloc: chunk%tiles(1)%field%density0) &
!$omp        map(always, present, to: chunk%tiles(1)%field%density1)
!  if (.not. allocated(chunk%tiles(1)%field%density0)) stop 1
!  if (.not. allocated(chunk%tiles(1)%field%density1)) stop 1
!  if (any (chunk%tiles(1)%field%density0 /= 2*reshape([1,2,3,4],[2,2]))) stop 1
!  if (any (chunk%tiles(1)%field%density1 /= reshape([11,22,33,44],[2,2]))) 
stop 1
   chunk%tiles(1)%field%density0 = chunk%tiles(1)%field%density0 * 7
   chunk%tiles(1)%field%density1 = chunk%tiles(1)%field%density1 * 3
!$omp end target

!$omp target exit data &
!$omp   map(from: chunk%tiles(1)%field%density0) &
!$omp   map(from: chunk%tiles(1)%field%density1)

print *, chunk%tiles(1)%field%density0
print *, chunk%tiles(1)%field%density1

if (any (chunk%tiles(1)%field%density0 /= 7*2*reshape([1,2,3,4],[2,2]))) stop 1
if (any (chunk%tiles(1)%field%density1 /= 3*reshape([11,22,33,44],[2,2]))) stop 
2

end
-------------------------
The attached diff fixes the overlapping-maps error for the testcase above. However it then fails for `map(always, present, to: chunk%tiles(1)%field%density1)` with:

libgomp: present clause: not present on the device (addr: 0x4bd95b0, size: 32 (0x20), dev: 0)

This does not seem to be caused by my intermediate-descriptor patch though, as the equivalent testcase without DT (see attachment) fails the same way. I think I see what the problem is though and will try to come up with a separate patch. At this point, my understanding is that the array *descriptor* of density1 is mapped by `target enter data` but, because it is unallocated, the array itself is not added to the present table.
--
PA
diff --git gcc/fortran/trans-openmp.cc gcc/fortran/trans-openmp.cc
index 7e32671073c..5eb24ea51be 100644
--- gcc/fortran/trans-openmp.cc
+++ gcc/fortran/trans-openmp.cc
@@ -1,3 +1,5 @@
+#pragma GCC optimize("O0")
+
 /* OpenMP directive translation -- generate GCC trees from gfc_code.
    Copyright (C) 2005-2026 Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <[email protected]>
@@ -3566,6 +3568,11 @@ gfc_map_array_descriptor (
     ;
   else if (op == EXEC_OMP_TARGET_EXIT_DATA || op == EXEC_OACC_EXIT_DATA)
     map_kind = GOMP_MAP_RELEASE;
+  else if (mid_desc_p)
+    {
+      OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
+      OMP_CLAUSE_SIZE (node) = size_int (0);
+    }
   else
     map_kind = GOMP_MAP_ALLOC;
 
  implicit none
    real(kind=8), allocatable :: density0(:,:), density1(:,:)


density0 = reshape([1,2,3,4],[2,2])

!$omp target enter data &
!$omp   map(to: density0) &
!$omp   map(to: density1)

!$omp target map(present, alloc: density0)
!  if (.not. allocated(density0)) stop 1
!  if (any (density0 /= reshape([1,2,3,4],[2,2]))) stop 1
  density0 = density0 * 2
!$omp end target

density1 = reshape([11,22,33,44],[2,2])

!$omp target map(present, alloc: density0) &
!$omp        map(always, present, to: density1)
!  if (.not. allocated(density0)) stop 1
!  if (.not. allocated(density1)) stop 1
!  if (any (density0 /= 2*reshape([1,2,3,4],[2,2]))) stop 1
!  if (any (density1 /= reshape([11,22,33,44],[2,2]))) stop 1
  density0 = density0 * 7
  density1 = density1 * 3
!$omp end target

!$omp target exit data &
!$omp   map(from: density0) &
!$omp   map(from: density1)

print *, density0
print *, density1

if (any (density0 /= 7*2*reshape([1,2,3,4],[2,2]))) stop 1
if (any (density1 /= 3*reshape([11,22,33,44],[2,2]))) stop 2

end

Reply via email to