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