mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
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.
269 lines
8.5 KiB
Fortran
269 lines
8.5 KiB
Fortran
module m
|
|
implicit none (type, external)
|
|
type t
|
|
integer, allocatable :: A(:)
|
|
end type t
|
|
type t2
|
|
type(t), allocatable :: vT
|
|
integer, allocatable :: x
|
|
end type t2
|
|
|
|
contains
|
|
|
|
subroutine test_alloc()
|
|
type(t) :: var
|
|
type(t), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%A(4), var2%A(5))
|
|
|
|
!$omp target enter data map(alloc: var, var2)
|
|
!$omp target
|
|
if (.not. allocated(Var2)) stop 1
|
|
if (.not. allocated(Var%A)) stop 2
|
|
if (.not. allocated(Var2%A)) stop 3
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) stop 4
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) stop 5
|
|
var%A = [1,2,3,4]
|
|
var2%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
!$omp target exit data map(from: var, var2)
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%A)) error stop
|
|
if (.not. allocated(Var2%A)) error stop
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) error stop
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) error stop
|
|
if (any(var%A /= [1,2,3,4])) error stop
|
|
if (any(var2%A /= [11,22,33,44,55])) error stop
|
|
end subroutine test_alloc
|
|
|
|
subroutine test2_alloc()
|
|
type(t2) :: var
|
|
type(t2), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%x, var2%x)
|
|
|
|
!$omp target enter data map(alloc: var, var2)
|
|
!$omp target
|
|
if (.not. allocated(Var2)) stop 6
|
|
if (.not. allocated(Var%x)) stop 7
|
|
if (.not. allocated(Var2%x)) stop 8
|
|
var%x = 42
|
|
var2%x = 43
|
|
!$omp end target
|
|
!$omp target exit data map(from: var, var2)
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
if (var%x /= 42) error stop
|
|
if (var2%x /= 43) error stop
|
|
|
|
allocate(var%vt, var2%vt)
|
|
allocate(var%vt%A(-1:3), var2%vt%A(0:4))
|
|
|
|
!$omp target enter data map(alloc: var, var2)
|
|
!$omp target
|
|
if (.not. allocated(Var2)) stop 11
|
|
if (.not. allocated(Var%x)) stop 12
|
|
if (.not. allocated(Var2%x)) stop 13
|
|
if (.not. allocated(Var%vt)) stop 14
|
|
if (.not. allocated(Var2%vt)) stop 15
|
|
if (.not. allocated(Var%vt%a)) stop 16
|
|
if (.not. allocated(Var2%vt%a)) stop 17
|
|
var%x = 42
|
|
var2%x = 43
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) stop 4
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) stop 5
|
|
var%vt%A = [1,2,3,4,5]
|
|
var2%vt%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
!$omp target exit data map(from: var, var2)
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
if (.not. allocated(Var%vt)) error stop
|
|
if (.not. allocated(Var2%vt)) error stop
|
|
if (.not. allocated(Var%vt%a)) error stop
|
|
if (.not. allocated(Var2%vt%a)) error stop
|
|
if (var%x /= 42) error stop
|
|
if (var2%x /= 43) error stop
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) error stop
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) error stop
|
|
if (any(var%vt%A /= [1,2,3,4,5])) error stop
|
|
if (any(var2%vt%A /= [11,22,33,44,55])) error stop
|
|
end subroutine test2_alloc
|
|
|
|
|
|
subroutine test_alloc_target()
|
|
type(t) :: var
|
|
type(t), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%A(4), var2%A(5))
|
|
|
|
!$omp target map(alloc: var, var2)
|
|
if (.not. allocated(Var2)) stop 1
|
|
if (.not. allocated(Var%A)) stop 2
|
|
if (.not. allocated(Var2%A)) stop 3
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) stop 4
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) stop 5
|
|
var%A = [1,2,3,4]
|
|
var2%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%A)) error stop
|
|
if (.not. allocated(Var2%A)) error stop
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) error stop
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) error stop
|
|
end subroutine test_alloc_target
|
|
|
|
subroutine test2_alloc_target()
|
|
type(t2) :: var
|
|
type(t2), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%x, var2%x)
|
|
|
|
!$omp target map(alloc: var, var2)
|
|
if (.not. allocated(Var2)) stop 6
|
|
if (.not. allocated(Var%x)) stop 7
|
|
if (.not. allocated(Var2%x)) stop 8
|
|
var%x = 42
|
|
var2%x = 43
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
|
|
allocate(var%vt, var2%vt)
|
|
allocate(var%vt%A(-1:3), var2%vt%A(0:4))
|
|
|
|
!$omp target map(alloc: var, var2)
|
|
if (.not. allocated(Var2)) stop 11
|
|
if (.not. allocated(Var%x)) stop 12
|
|
if (.not. allocated(Var2%x)) stop 13
|
|
if (.not. allocated(Var%vt)) stop 14
|
|
if (.not. allocated(Var2%vt)) stop 15
|
|
if (.not. allocated(Var%vt%a)) stop 16
|
|
if (.not. allocated(Var2%vt%a)) stop 17
|
|
var%x = 42
|
|
var2%x = 43
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) stop 4
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) stop 5
|
|
var%vt%A = [1,2,3,4,5]
|
|
var2%vt%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
if (.not. allocated(Var%vt)) error stop
|
|
if (.not. allocated(Var2%vt)) error stop
|
|
if (.not. allocated(Var%vt%a)) error stop
|
|
if (.not. allocated(Var2%vt%a)) error stop
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) error stop
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) error stop
|
|
end subroutine test2_alloc_target
|
|
|
|
|
|
|
|
subroutine test_from()
|
|
type(t) :: var
|
|
type(t), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%A(4), var2%A(5))
|
|
|
|
!$omp target map(from: var, var2)
|
|
if (.not. allocated(Var2)) stop 1
|
|
if (.not. allocated(Var%A)) stop 2
|
|
if (.not. allocated(Var2%A)) stop 3
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) stop 4
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) stop 5
|
|
var%A = [1,2,3,4]
|
|
var2%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%A)) error stop
|
|
if (.not. allocated(Var2%A)) error stop
|
|
if (lbound(var%A, 1) /= 1 .or. ubound(var%A, 1) /= 4) error stop
|
|
if (lbound(var2%A, 1) /= 1 .or. ubound(var2%A, 1) /= 5) error stop
|
|
if (any(var%A /= [1,2,3,4])) error stop
|
|
if (any(var2%A /= [11,22,33,44,55])) error stop
|
|
end subroutine test_from
|
|
|
|
subroutine test2_from()
|
|
type(t2) :: var
|
|
type(t2), allocatable :: var2
|
|
|
|
allocate(var2)
|
|
allocate(var%x, var2%x)
|
|
|
|
!$omp target map(from: var, var2)
|
|
if (.not. allocated(Var2)) stop 6
|
|
if (.not. allocated(Var%x)) stop 7
|
|
if (.not. allocated(Var2%x)) stop 8
|
|
var%x = 42
|
|
var2%x = 43
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
if (var%x /= 42) error stop
|
|
if (var2%x /= 43) error stop
|
|
|
|
allocate(var%vt, var2%vt)
|
|
allocate(var%vt%A(-1:3), var2%vt%A(0:4))
|
|
|
|
!$omp target map(from: var, var2)
|
|
if (.not. allocated(Var2)) stop 11
|
|
if (.not. allocated(Var%x)) stop 12
|
|
if (.not. allocated(Var2%x)) stop 13
|
|
if (.not. allocated(Var%vt)) stop 14
|
|
if (.not. allocated(Var2%vt)) stop 15
|
|
if (.not. allocated(Var%vt%a)) stop 16
|
|
if (.not. allocated(Var2%vt%a)) stop 17
|
|
var%x = 42
|
|
var2%x = 43
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) stop 4
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) stop 5
|
|
var%vt%A = [1,2,3,4,5]
|
|
var2%vt%A = [11,22,33,44,55]
|
|
!$omp end target
|
|
|
|
if (.not. allocated(Var2)) error stop
|
|
if (.not. allocated(Var%x)) error stop
|
|
if (.not. allocated(Var2%x)) error stop
|
|
if (.not. allocated(Var%vt)) error stop
|
|
if (.not. allocated(Var2%vt)) error stop
|
|
if (.not. allocated(Var%vt%a)) error stop
|
|
if (.not. allocated(Var2%vt%a)) error stop
|
|
if (var%x /= 42) error stop
|
|
if (var2%x /= 43) error stop
|
|
if (lbound(var%vt%A, 1) /= -1 .or. ubound(var%vt%A, 1) /= 3) error stop
|
|
if (lbound(var2%vt%A, 1) /= 0 .or. ubound(var2%vt%A, 1) /= 4) error stop
|
|
if (any(var%vt%A /= [1,2,3,4,5])) error stop
|
|
if (any(var2%vt%A /= [11,22,33,44,55])) error stop
|
|
end subroutine test2_from
|
|
|
|
end module m
|
|
|
|
use m
|
|
implicit none (type, external)
|
|
call test_alloc
|
|
call test2_alloc
|
|
call test_alloc_target
|
|
call test2_alloc_target
|
|
|
|
call test_from
|
|
call test2_from
|
|
end
|