Hi PA,
Paul-Antoine Arras wrote:
Initially I crafted this patch for the "simple" case with only one
intermediate descriptor, leaving the more complex cases for later --
and kind of forgot about it.
I have another variant – see attachment – which also gives an ICE,
but this time for:
10971 node = OMP_CLAUSE_CHAIN (node);
10972 if (node && omp_map_clause_descriptor_p (node))
10973 {
10974 gcc_assert (node != grp->grp_end);
10975 node = OMP_CLAUSE_CHAIN (node);
10976 }
as the node == grp->grp_end.
The variable is:
<omp_clause 0x7ffff7073140 map
op-0: <component_ref 0x7ffff70ddab0>
op-1: <integer_cst 0x7ffff726fd08 64>
op-2:>
<component_ref 0x7ffff70ddab0
type <record_type 0x7ffff702ae70 array01_tile_type type_1 BLK
arg:0 <var_decl 0x7ffff7032390 chunk
arg:1 <field_decl 0x7ffff702cc80 tiles type <record_type 0x7ffff702ae70
array01_tile_type>
Also this variant shouldn't ICE - and also only gives an ICE with your patch.
Without, it works with host fallback or self mapping (unsurprisingly), but fails
with actual mapping with: "is already mapped"
(I have not thought about whether that code makes sense or not,
but an ICE is definitely wrong.)
* * *
To support additional layers in the FE would probably mean saving in a
vector all allocatables found while walking the chain of references.
Then loop through the vector and call gfc_map_array_descriptor for
each element. Hopefully that will just work with no changes in the ME.
If so, I'll come up with a revised version of the patch.
Fingers crossed!
Otherwise, if it entails much more work, what about putting sorry()
there and leaving a note in the PR?
Presumably, that's the best. — Although, the question is whether it
starts to make more sense to open a new PR for it. Additionally, I fear
that no one will pick up the follow up task if not done properly now.
(Whether in this patch or in a soon-to-follow follow-up patch.)
Tobias
! { dg-do run }
! PR fortran/120505
! Check that a nested allocatable DT component is mapped properly even when the
! first component is *not* mapped.
module m
type field_type
real(kind=8), allocatable :: density0(:,:), density1(:,:)
end type field_type
type tile_type
type(field_type),allocatable :: field(:)
end type tile_type
! type tile_type2
! type(tile_type),allocatable :: tiles_inner(:)
! end type tile_type2
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
allocate(chunk%tiles(1))
allocate(chunk%tiles(1)%field(1))
chunk%tiles(1)%field(1)%density1 = reshape([1,2,3,4],[2,2])
allocate(chunk%left_rcv_buffer(1))
!$omp target enter data &
!$omp map(to: chunk%tiles(1)%field(1)) &
!$omp map(to: chunk%tiles(1)%field(1)%density1) &
!$omp map(to: chunk%left_rcv_buffer)
!$omp target map(tofrom: chunk%tiles(1)%field(1)%density1, chunk)
if (any (chunk%tiles(1)%field(1)%density1 /= reshape([1,2,3,4],[2,2]))) stop 1
chunk%tiles(1)%field(1)%density1 = chunk%tiles(1)%field(1)%density1 + 5
chunk%left_rcv_buffer(1) = 42.0_8
!$omp end target
!$omp target exit data &
!$omp map(from: chunk%tiles(1)%field(1)%density1) &
!$omp map(from: chunk%left_rcv_buffer)
if (any (chunk%tiles(1)%field(1)%density1 /= 5 + reshape([1,2,3,4],[2,2]))) stop 2
if (chunk%left_rcv_buffer(1) /= 42.0_8) stop 3
end