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

Reply via email to