On 2/19/25 10:08 AM, Tobias Burnus wrote:
The attached patch does some ground-laying work for OpenMP
deep mapping - touching common gfortran code.
It does so by:
(1)gfc_tree_array_size now can determine the array size not only from
the passed Fortran gfc_expr but also using a descriptor, passed as
gimple 'tree'.
(2) Adds missingGFC_ARRAY_ASSUMED_RANK_{ALLOCATABLE,POINTER{,_CONT}} to
enum gfc_array_kind to complete the kinds – for non-assumed-rank, those
subtypes already existed, for assumed rank, the pointer/allocatable
flags were missing (and for pointer: contiguous, while allocatables are
always contigous).
Build and regtested on x86-64_gnu-linux.
OK for mainline?
Looks good Tobias. I don't know if anyone else was looking through it.
Jerry
* * *
When doing the change (2) back when I first created the patch, I
encountered an issue, which I could not fix quickly. Hence, I filed
https://gcc.gnu.org/PR104651 - see also the FIXME in the code which
should be IMHO be used but it causes fails. Although, the proper fix is
probably to change how CLASS/attributes in it are represented (cf. PR).
[I don't recall the details - and don't know more anymore than what's
in the FIXME comment and in the problem report.]
* * *
BACKGROUND/EXAMPLE
-> OpenMP + derived-type mapping with allocatable components
(i.e. why I need the modifications; for those changes, I will also
add testcases.)
Namely, assume:
type t
real, allocatable :: x(:)
real, pointer :: p(:)
end type t
type(t) :: var(4)
!$omp target enter data map(to:var)
This is supposed to copy 'var' onto an offloading device
(device = omp_get_default_device()) - by doing a deep
copying/mapping. Thus, the compiler needs to generate code
like - pseudocode:
map (to: var [size: 4*storage_size(type(t))])
for i = 1 to 4:
if (allocated (var(i)%x)
map (to: var(i)%x [size: size(var(i)%x) * sizeof(real)])
[plus attaching the just mapped data to the base_addr
of the array descriptor.]
Namely: var and also var(:)%x have to be copied to the device,
var(:)%p is not touched – as it is a pointer and not an allocatable.
Another example would be:
!$omp target
var(1)%x(2) = 7
!$omp end target
where 'map(tofrom:var)' is implicitly added, which happens
quite late in the game. Thus, the code handles the mapping
both by explicit and implicit mapping and does so very late.
(omp-low.cc calls back to the Fortran front-end to do the
work.)
* * *
Soon/next, I will post the patch that handles code above (for
nonpolymorphic allocatable components). However, if you want to
glance at the code, already you can find an older version at
* https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591144.html
And a re-based commit relative to GCC 14, applied to OG14
(devel/omp/gcc-14) at https://gcc.gnu.org/g:92c3af3d4f8
(or 'git log <hash>' or 'git log devel/omp/gcc-14' in any of
your GCC repos).
Note that the to-be-posted patch will differ a bit as:
- the middle end bits are already in
- the CLASS/polymorphic handling will be removed.
- minor cleanup/fixes
Reason for not including polymorphism support:
* As the vtab is not handled, there is no benefit of having it.
Additionally, the patch changes what's in the vtable/vtab by
adding an entry, breaking all backward compatibility of vtabs.
Thus, I only want to add it when it works properly.
* On the OpenMP spec side, it is similar: OpenMP 6.0 clarified
that mapping polymorphic variables in Fortran is not supported
(5.x was unclear) but it added full support for shared-memory
part (data sharing clauses). Plus there is on-going work to
add polymorphism support to OpenMP 6.1.
[For 6.1, parts of the GCC polymorphism patch will be resurrected
in some way, but for now not having polymorphism is simply better!]
* * *
Tobias