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.
309 lines
9.3 KiB
Fortran
309 lines
9.3 KiB
Fortran
! NOTE: This code uses POINTER.
|
|
! While map(p, var%p) etc. maps the ptr/ptr comp p / var%p (incl. allocatable comps),
|
|
! map(var) does not map var%p.
|
|
|
|
use iso_c_binding
|
|
implicit none
|
|
type t2
|
|
integer, allocatable :: x, y, z
|
|
end type t2
|
|
type t
|
|
integer, pointer :: A => null()
|
|
integer, pointer :: B(:) => null()
|
|
type(t2), pointer :: C => null()
|
|
type(t2), pointer :: D(:,:) => null()
|
|
end type t
|
|
|
|
type t3
|
|
type(t) :: Q
|
|
type(t) :: R(5)
|
|
end type
|
|
|
|
type(t) :: var, var2
|
|
type(t3) :: var3, var4
|
|
integer(c_intptr_t) :: iptr
|
|
|
|
! --------------------------------------
|
|
! Assign + allocate
|
|
allocate (var%A, source=45)
|
|
allocate (var%B(3), source=[1,2,3])
|
|
allocate (var%C)
|
|
var%C%x = 6; var%C%y = 5; var%C%z = 4
|
|
allocate (var%D(2,2))
|
|
var%D(1,1)%x = 1
|
|
var%D(1,1)%y = 2
|
|
var%D(1,1)%z = 3
|
|
var%D(2,1)%x = 4
|
|
var%D(2,1)%y = 5
|
|
var%D(2,1)%z = 6
|
|
var%D(1,2)%x = 11
|
|
var%D(1,2)%y = 12
|
|
var%D(1,2)%z = 13
|
|
var%D(2,2)%x = 14
|
|
var%D(2,2)%y = 15
|
|
var%D(2,2)%z = 16
|
|
|
|
! Assign + allocate
|
|
allocate (var2%A, source=145)
|
|
allocate (var2%B, source=[991,992,993])
|
|
allocate (var2%C)
|
|
var2%C%x = 996; var2%C%y = 995; var2%C%z = 994
|
|
allocate (var2%D(2,2))
|
|
var2%D(1,1)%x = 199
|
|
var2%D(1,1)%y = 299
|
|
var2%D(1,1)%z = 399
|
|
var2%D(2,1)%x = 499
|
|
var2%D(2,1)%y = 599
|
|
var2%D(2,1)%z = 699
|
|
var2%D(1,2)%x = 1199
|
|
var2%D(1,2)%y = 1299
|
|
var2%D(1,2)%z = 1399
|
|
var2%D(2,2)%x = 1499
|
|
var2%D(2,2)%y = 1599
|
|
var2%D(2,2)%z = 1699
|
|
|
|
block
|
|
integer(c_intptr_t) :: loc_a, loc_b, loc_c, loc_d, loc2_a, loc2_b, loc2_c, loc2_d
|
|
loc_a = loc (var%a)
|
|
loc_b = loc (var%b)
|
|
loc_c = loc (var%d)
|
|
loc_d = loc (var%d)
|
|
loc2_a = loc (var2%a)
|
|
loc2_b = loc (var2%b)
|
|
loc2_c = loc (var2%c)
|
|
loc2_d = loc (var2%d)
|
|
! var/var2 are mapped, but the pointer components aren't
|
|
!$omp target map(to: var) map(tofrom: var2)
|
|
if (loc_a /= loc (var%a)) stop 31
|
|
if (loc_b /= loc (var%b)) stop 32
|
|
if (loc_c /= loc (var%d)) stop 33
|
|
if (loc_d /= loc (var%d)) stop 34
|
|
if (loc2_a /= loc (var2%a)) stop 35
|
|
if (loc2_b /= loc (var2%b)) stop 36
|
|
if (loc2_c /= loc (var2%c)) stop 37
|
|
if (loc2_d /= loc (var2%d)) stop 38
|
|
!$omp end target
|
|
if (loc_a /= loc (var%a)) stop 41
|
|
if (loc_b /= loc (var%b)) stop 42
|
|
if (loc_c /= loc (var%d)) stop 43
|
|
if (loc_d /= loc (var%d)) stop 44
|
|
if (loc2_a /= loc (var2%a)) stop 45
|
|
if (loc2_b /= loc (var2%b)) stop 46
|
|
if (loc2_c /= loc (var2%c)) stop 47
|
|
if (loc2_d /= loc (var2%d)) stop 48
|
|
end block
|
|
|
|
block
|
|
! Map only (all) components, but this maps also the alloc comps
|
|
!$omp target map(to: var%a, var%b, var%c, var%d) map(tofrom: var2%a, var2%b, var2%c, var2%d)
|
|
call foo (var,var2)
|
|
!$omp end target
|
|
end block
|
|
|
|
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
|
|
block
|
|
integer :: tmp_x(2,2), tmp_y(2,2), tmp_z(2,2), i, j
|
|
tmp_x = reshape([1, 4, 11, 14], [2,2])
|
|
tmp_y = reshape([2, 5, 12, 15], [2,2])
|
|
tmp_z = reshape([3, 6, 13, 16], [2,2])
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
if (var2%D(i,j)%x /= tmp_x(i,j)) stop 12
|
|
if (var2%D(i,j)%y /= tmp_y(i,j)) stop 12
|
|
if (var2%D(i,j)%z /= tmp_z(i,j)) stop 12
|
|
end do
|
|
end do
|
|
end block
|
|
|
|
! Extra deallocates due to PR fortran/104697
|
|
deallocate(var%C%x, var%C%y, var%C%z)
|
|
deallocate(var%D(1,1)%x, var%D(1,1)%y, var%D(1,1)%z)
|
|
deallocate(var%D(2,1)%x, var%D(2,1)%y, var%D(2,1)%z)
|
|
deallocate(var%D(1,2)%x, var%D(1,2)%y, var%D(1,2)%z)
|
|
deallocate(var%D(2,2)%x, var%D(2,2)%y, var%D(2,2)%z)
|
|
deallocate(var%A, var%B, var%C, var%D)
|
|
|
|
deallocate(var2%C%x, var2%C%y, var2%C%z)
|
|
deallocate(var2%D(1,1)%x, var2%D(1,1)%y, var2%D(1,1)%z)
|
|
deallocate(var2%D(2,1)%x, var2%D(2,1)%y, var2%D(2,1)%z)
|
|
deallocate(var2%D(1,2)%x, var2%D(1,2)%y, var2%D(1,2)%z)
|
|
deallocate(var2%D(2,2)%x, var2%D(2,2)%y, var2%D(2,2)%z)
|
|
deallocate(var2%A, var2%B, var2%C, var2%D)
|
|
|
|
! --------------------------------------
|
|
! Assign + allocate
|
|
allocate (var3%Q%A, source=45)
|
|
allocate (var3%Q%B, source=[1,2,3])
|
|
allocate (var3%Q%C, source=t2(6,5,4))
|
|
allocate (var3%Q%D(2,2))
|
|
var3%Q%D(1,1) = t2(1,2,3)
|
|
var3%Q%D(2,1) = t2(4,5,6)
|
|
var3%Q%D(1,2) = t2(11,12,13)
|
|
var3%Q%D(2,2) = t2(14,15,16)
|
|
|
|
allocate (var3%R(2)%A, source=45)
|
|
allocate (var3%R(2)%B, source=[1,2,3])
|
|
allocate (var3%R(2)%C, source=t2(6,5,4))
|
|
allocate (var3%R(2)%D(2,2))
|
|
var3%R(2)%D(1,1) = t2(1,2,3)
|
|
var3%R(2)%D(2,1) = t2(4,5,6)
|
|
var3%R(2)%D(1,2) = t2(11,12,13)
|
|
var3%R(2)%D(2,2) = t2(14,15,16)
|
|
|
|
! Assign + allocate
|
|
allocate (var4%Q%A, source=145)
|
|
allocate (var4%Q%B, source=[991,992,993])
|
|
allocate (var4%Q%C, source=t2(996,995,994))
|
|
allocate (var4%Q%D(2,2))
|
|
var4%Q%D(1,1) = t2(199,299,399)
|
|
var4%Q%D(2,1) = t2(499,599,699)
|
|
var4%Q%D(1,2) = t2(1199,1299,1399)
|
|
var4%Q%D(2,2) = t2(1499,1599,1699)
|
|
|
|
allocate (var4%R(3)%A, source=145)
|
|
allocate (var4%R(3)%B, source=[991,992,993])
|
|
allocate (var4%R(3)%C, source=t2(996,995,994))
|
|
allocate (var4%R(3)%D(2,2))
|
|
var4%R(3)%D(1,1) = t2(199,299,399)
|
|
var4%R(3)%D(2,1) = t2(499,599,699)
|
|
var4%R(3)%D(1,2) = t2(1199,1299,1399)
|
|
var4%R(3)%D(2,2) = t2(1499,1599,1699)
|
|
|
|
!$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
|
|
|
|
iptr = loc(var3%R(2)%A)
|
|
|
|
!$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%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
|
|
block
|
|
integer :: tmp_x(2,2), tmp_y(2,2), tmp_z(2,2), i, j
|
|
tmp_x = reshape([1, 4, 11, 14], [2,2])
|
|
tmp_y = reshape([2, 5, 12, 15], [2,2])
|
|
tmp_z = reshape([3, 6, 13, 16], [2,2])
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
if (var4%Q%D(i,j)%x /= tmp_x(i,j)) stop 16
|
|
if (var4%Q%D(i,j)%y /= tmp_y(i,j)) stop 16
|
|
if (var4%Q%D(i,j)%z /= tmp_z(i,j)) stop 16
|
|
end do
|
|
end do
|
|
end block
|
|
|
|
! Cf. PR fortran/104696
|
|
! { dg-output "valid mapping, OK" { xfail { offload_device_nonshared_as } } }
|
|
if (iptr /= loc(var3%R(2)%A)) then
|
|
print *, "invalid mapping, cf. PR fortran/104696"
|
|
else
|
|
|
|
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
|
|
block
|
|
integer :: tmp_x(2,2), tmp_y(2,2), tmp_z(2,2), i, j
|
|
tmp_x = reshape([1, 4, 11, 14], [2,2])
|
|
tmp_y = reshape([2, 5, 12, 15], [2,2])
|
|
tmp_z = reshape([3, 6, 13, 16], [2,2])
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
if (var4%R(3)%D(i,j)%x /= tmp_x(i,j)) stop 20
|
|
if (var4%R(3)%D(i,j)%y /= tmp_y(i,j)) stop 20
|
|
if (var4%R(3)%D(i,j)%z /= tmp_z(i,j)) stop 20
|
|
end do
|
|
end do
|
|
end block
|
|
|
|
! Extra deallocates due to PR fortran/104697
|
|
deallocate(var3%Q%C%x, var3%Q%D(1,1)%x, var3%Q%D(2,1)%x, var3%Q%D(1,2)%x, var3%Q%D(2,2)%x)
|
|
deallocate(var3%Q%C%y, var3%Q%D(1,1)%y, var3%Q%D(2,1)%y, var3%Q%D(1,2)%y, var3%Q%D(2,2)%y)
|
|
deallocate(var3%Q%C%z, var3%Q%D(1,1)%z, var3%Q%D(2,1)%z, var3%Q%D(1,2)%z, var3%Q%D(2,2)%z)
|
|
deallocate(var3%Q%A, var3%Q%B, var3%Q%C, var3%Q%D)
|
|
|
|
deallocate(var4%Q%C%x, var4%Q%D(1,1)%x, var4%Q%D(2,1)%x, var4%Q%D(1,2)%x, var4%Q%D(2,2)%x)
|
|
deallocate(var4%Q%C%y, var4%Q%D(1,1)%y, var4%Q%D(2,1)%y, var4%Q%D(1,2)%y, var4%Q%D(2,2)%y)
|
|
deallocate(var4%Q%C%z, var4%Q%D(1,1)%z, var4%Q%D(2,1)%z, var4%Q%D(1,2)%z, var4%Q%D(2,2)%z)
|
|
deallocate(var4%Q%A, var4%Q%B, var4%Q%C, var4%Q%D)
|
|
|
|
deallocate(var3%R(2)%C%x, var3%R(2)%D(1,1)%x, var3%R(2)%D(2,1)%x, var3%R(2)%D(1,2)%x, var3%R(2)%D(2,2)%x)
|
|
deallocate(var3%R(2)%C%y, var3%R(2)%D(1,1)%y, var3%R(2)%D(2,1)%y, var3%R(2)%D(1,2)%y, var3%R(2)%D(2,2)%y)
|
|
deallocate(var3%R(2)%C%z, var3%R(2)%D(1,1)%z, var3%R(2)%D(2,1)%z, var3%R(2)%D(1,2)%z, var3%R(2)%D(2,2)%z)
|
|
deallocate(var3%R(2)%A, var3%R(2)%B, var3%R(2)%C, var3%R(2)%D)
|
|
|
|
deallocate(var4%R(3)%C%x, var4%R(3)%D(1,1)%x, var4%R(3)%D(2,1)%x, var4%R(3)%D(1,2)%x, var4%R(3)%D(2,2)%x)
|
|
deallocate(var4%R(3)%C%y, var4%R(3)%D(1,1)%y, var4%R(3)%D(2,1)%y, var4%R(3)%D(1,2)%y, var4%R(3)%D(2,2)%y)
|
|
deallocate(var4%R(3)%C%z, var4%R(3)%D(1,1)%z, var4%R(3)%D(2,1)%z, var4%R(3)%D(1,2)%z, var4%R(3)%D(2,2)%z)
|
|
deallocate(var4%R(3)%A, var4%R(3)%B, var4%R(3)%C, var4%R(3)%D)
|
|
|
|
print *, "valid mapping, OK"
|
|
endif
|
|
|
|
contains
|
|
subroutine foo(x, y)
|
|
type(t) :: x, y
|
|
intent(in) :: x
|
|
intent(inout) :: y
|
|
integer :: tmp_x(2,2), tmp_y(2,2), tmp_z(2,2), i, j
|
|
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
|
|
|
|
tmp_x = reshape([1, 4, 11, 14], [2,2])
|
|
tmp_y = reshape([2, 5, 12, 15], [2,2])
|
|
tmp_z = reshape([3, 6, 13, 16], [2,2])
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
if (x%D(i,j)%x /= tmp_x(i,j)) stop 4
|
|
if (x%D(i,j)%y /= tmp_y(i,j)) stop 4
|
|
if (x%D(i,j)%z /= tmp_z(i,j)) stop 4
|
|
end do
|
|
end do
|
|
|
|
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
|
|
tmp_x = reshape([199, 499, 1199, 1499], [2,2])
|
|
tmp_y = reshape([299, 599, 1299, 1599], [2,2])
|
|
tmp_z = reshape([399, 699, 1399, 1699], [2,2])
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
if (y%D(i,j)%x /= tmp_x(i,j)) stop 8
|
|
if (y%D(i,j)%y /= tmp_y(i,j)) stop 8
|
|
if (y%D(i,j)%z /= tmp_z(i,j)) stop 8
|
|
end do
|
|
end do
|
|
|
|
y%A = x%A
|
|
y%B(:) = x%B
|
|
y%C%x = x%C%x
|
|
y%C%y = x%C%y
|
|
y%C%z = x%C%z
|
|
do j = 1, 2
|
|
do i = 1, 2
|
|
y%D(i,j)%x = x%D(i,j)%x
|
|
y%D(i,j)%y = x%D(i,j)%y
|
|
y%D(i,j)%z = x%D(i,j)%z
|
|
end do
|
|
end do
|
|
end
|
|
end
|