Re: [PATCH 1/2] OpenMP/Fortran: Map intermediate array descriptor [PR120505]

Paul-Antoine Arras <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
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
present.diff (text/x-patch, 742 B)
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;
present-nodt.f90 (text/x-fortran, 1 KB)
  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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.