Files
gcc-reflection/libgomp/testsuite/libgomp.fortran/map-alloc-comp-4.f90
Tobias Burnus 99cd28c473 Fortran/OpenMP: Support automatic mapping allocatable components (deep mapping)
When mapping an allocatable variable (or derived-type component), explicitly
or implicitly, all its allocated allocatable components will automatically be
mapped. The patch implements the target hooks, added for this feature to
omp-low.cc with commit r15-3895-ge4a58b6f28383c.

Namely, there is a check whether there are allocatable components at all:
gfc_omp_deep_mapping_p. Then gfc_omp_deep_mapping_cnt, counting the number
of required mappings; this is a dynamic value as it depends on array
bounds and whether an allocatable is allocated or not.
And, finally, the actual mapping: gfc_omp_deep_mapping.

Polymorphic variables are partially supported: the mapping of the _data
component is fully supported, but only components of the declared type
are processed for additional allocatables. Additionally, _vptr is not
touched. This means that everything needing _vtab information requires
unified shared memory; in particular, _size data is required when
accessing elements of polymorphic arrays.
However, for scalar arrays, accessing components of the declare type
should work just fine.

As polymorphic variables are not (really) supported and OpenMP 6
explicitly disallows them, there is now a warning (-Wopenmp) when
they are encountered. Unlimited polymorphics are rejected (error).

Additionally, PRIVATE and FIRSTPRIVATE are not quite supported for
allocatable components, polymorphic components and as polymorphic
variable. Thus, those are now rejected as well.

gcc/fortran/ChangeLog:

	* f95-lang.cc (LANG_HOOKS_OMP_DEEP_MAPPING,
	LANG_HOOKS_OMP_DEEP_MAPPING_P, LANG_HOOKS_OMP_DEEP_MAPPING_CNT):
	Define.
	* openmp.cc (gfc_match_omp_clause_reduction): Fix location setting.
	(resolve_omp_clauses): Permit allocatable components, reject
	them and polymorphic variables in PRIVATE/FIRSTPRIVATE.
	* trans-decl.cc (add_clause): Set clause location.
	* trans-openmp.cc (gfc_has_alloc_comps): Add ptr_ok and
	shallow_alloc_only Boolean arguments.
	(gfc_omp_replace_alloc_by_to_mapping): New.
	(gfc_omp_private_outer_ref, gfc_walk_alloc_comps,
	gfc_omp_clause_default_ctor, gfc_omp_clause_copy_ctor,
	gfc_omp_clause_assign_op, gfc_omp_clause_dtor): Update call to it.
	(gfc_omp_finish_clause): Minor cleanups, improve location data,
	handle allocatable components.
	(gfc_omp_deep_mapping_map, gfc_omp_deep_mapping_item,
	gfc_omp_deep_mapping_comps, gfc_omp_gen_simple_loop,
	gfc_omp_get_array_size, gfc_omp_elmental_loop,
	gfc_omp_deep_map_kind_p, gfc_omp_deep_mapping_int_p,
	gfc_omp_deep_mapping_p, gfc_omp_deep_mapping_do,
	gfc_omp_deep_mapping_cnt, gfc_omp_deep_mapping): New.
	(gfc_trans_omp_array_section): Save array descriptor in case
	deep-mapping lang hook will need it.
	(gfc_trans_omp_clauses): Likewise; use better clause location data.
	* trans.h (gfc_omp_deep_mapping_p, gfc_omp_deep_mapping_cnt,
	gfc_omp_deep_mapping): Add function prototypes.

libgomp/ChangeLog:

	* libgomp.texi (5.0 Impl. Status): Mark mapping alloc comps as 'Y'.
	* testsuite/libgomp.fortran/allocatable-comp.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-3.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-4.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-5.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-6.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-7.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-8.f90: New test.
	* testsuite/libgomp.fortran/map-alloc-comp-9.f90: New test.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/map-alloc-comp-1.f90: Remove dg-error.
	* gfortran.dg/gomp/polymorphic-mapping-2.f90: Update warn wording.
	* gfortran.dg/gomp/polymorphic-mapping.f90: Change expected
	diagnostic; some tests moved to ...
	* gfortran.dg/gomp/polymorphic-mapping-1.f90: ... here as new test.
	* gfortran.dg/gomp/polymorphic-mapping-3.f90: New test.
	* gfortran.dg/gomp/polymorphic-mapping-4.f90: New test.
	* gfortran.dg/gomp/polymorphic-mapping-5.f90: New test.
2025-04-15 16:42:42 +02:00

125 lines
3.7 KiB
Fortran

type t2
integer x, y, z
end type t2
type t
integer, allocatable :: A
integer, allocatable :: B(:)
type(t2), allocatable :: C
type(t2), allocatable :: D(:,:)
end type t
type t3
type(t) :: Q
type(t) :: R(5)
end type
type(t) :: var, var2
type(t3) :: var3, var4
! --------------------------------------
! Assign + allocate
var%A = 45
var%B = [1,2,3]
var%C = t2(6,5,4)
var%D = reshape([t2(1,2,3), t2(4,5,6), t2(11,12,13), t2(14,15,16)], [2,2])
! Assign + allocate
var2%A = 145
var2%B = [991,992,993]
var2%C = t2(996,995,994)
var2%D = reshape([t2(199,299,399), t2(499,599,699), t2(1199,1299,1399), t2(1499,1599,1699)], [2,2])
!$omp target map(to: var%A, var%B, var%C, var%D) &
!$omp& map(tofrom: var2%A, var2%B, var2%C, var2%D)
call foo(var, var2)
!$omp end target
if (var2%A /= 45) stop 9
if (any (var2%B /= [1,2,3])) stop 10
if (var2%C%x /= 6) stop 11
if (var2%C%y /= 5) stop 11
if (var2%C%z /= 4) stop 11
if (any (var2%D(:,:)%x /= reshape([1, 4, 11, 14], [2,2]))) stop 12
if (any (var2%D(:,:)%y /= reshape([2, 5, 12, 15], [2,2]))) stop 12
if (any (var2%D(:,:)%z /= reshape([3, 6, 13, 16], [2,2]))) stop 12
! --------------------------------------
! Assign + allocate
var3%Q%A = 45
var3%Q%B = [1,2,3]
var3%Q%C = t2(6,5,4)
var3%Q%D = reshape([t2(1,2,3), t2(4,5,6), t2(11,12,13), t2(14,15,16)], [2,2])
var3%R(2)%A = 45
var3%R(2)%B = [1,2,3]
var3%R(2)%C = t2(6,5,4)
var3%R(2)%D = reshape([t2(1,2,3), t2(4,5,6), t2(11,12,13), t2(14,15,16)], [2,2])
! Assign + allocate
var4%Q%A = 145
var4%Q%B = [991,992,993]
var4%Q%C = t2(996,995,994)
var4%Q%D = reshape([t2(199,299,399), t2(499,599,699), t2(1199,1299,1399), t2(1499,1599,1699)], [2,2])
var4%R(3)%A = 145
var4%R(3)%B = [991,992,993]
var4%R(3)%C = t2(996,995,994)
var4%R(3)%D = reshape([t2(199,299,399), t2(499,599,699), t2(1199,1299,1399), t2(1499,1599,1699)], [2,2])
!$omp target map(to: var3%Q%A, var3%Q%B, var3%Q%C, var3%Q%D) &
!$omp& map(tofrom: var4%Q%A, var4%Q%B, var4%Q%C, var4%Q%D)
call foo(var3%Q, var4%Q)
!$omp end target
if (var4%Q%A /= 45) stop 13
if (any (var4%Q%B /= [1,2,3])) stop 14
if (var4%Q%C%x /= 6) stop 15
if (var4%Q%C%y /= 5) stop 15
if (var4%Q%C%z /= 4) stop 15
if (any (var4%Q%D(:,:)%x /= reshape([1, 4, 11, 14], [2,2]))) stop 16
if (any (var4%Q%D(:,:)%y /= reshape([2, 5, 12, 15], [2,2]))) stop 16
if (any (var4%Q%D(:,:)%z /= reshape([3, 6, 13, 16], [2,2]))) stop 16
!$omp target map(to: var3%R(2)%A, var3%R(2)%B, var3%R(2)%C, var3%R(2)%D) &
!$omp& map(tofrom: var4%R(3)%A, var4%R(3)%B, var4%R(3)%C, var4%R(3)%D)
call foo(var3%R(2), var4%R(3))
!$omp end target
if (var4%R(3)%A /= 45) stop 17
if (any (var4%R(3)%B /= [1,2,3])) stop 18
if (var4%R(3)%C%x /= 6) stop 19
if (var4%R(3)%C%y /= 5) stop 19
if (var4%R(3)%C%z /= 4) stop 19
if (any (var4%R(3)%D(:,:)%x /= reshape([1, 4, 11, 14], [2,2]))) stop 20
if (any (var4%R(3)%D(:,:)%y /= reshape([2, 5, 12, 15], [2,2]))) stop 20
if (any (var4%R(3)%D(:,:)%z /= reshape([3, 6, 13, 16], [2,2]))) stop 20
contains
subroutine foo(x, y)
type(t) :: x, y
if (x%A /= 45) stop 1
if (any (x%B /= [1,2,3])) stop 2
if (x%C%x /= 6) stop 3
if (x%C%y /= 5) stop 3
if (x%C%z /= 4) stop 3
if (any (x%D(:,:)%x /= reshape([1, 4, 11, 14], [2,2]))) stop 4
if (any (x%D(:,:)%y /= reshape([2, 5, 12, 15], [2,2]))) stop 4
if (any (x%D(:,:)%z /= reshape([3, 6, 13, 16], [2,2]))) stop 4
if (y%A /= 145) stop 5
if (any (y%B /= [991,992,993])) stop 6
if (y%C%x /= 996) stop 7
if (y%C%y /= 995) stop 7
if (y%C%z /= 994) stop 7
if (any (y%D(:,:)%x /= reshape([199, 499, 1199, 1499], [2,2]))) stop 8
if (any (y%D(:,:)%y /= reshape([299, 599, 1299, 1599], [2,2]))) stop 8
if (any (y%D(:,:)%z /= reshape([399, 699, 1399, 1699], [2,2]))) stop 8
y%A = x%A
y%B(:) = x%B
y%C = x%C
y%D(:,:) = x%D(:,:)
end
end