]> git.ipfire.org Git - thirdparty/gcc.git/commit
Fortran: Replace getting of coarray data with accessor-based version. [PR107635]
authorAndre Vehreschild <vehre@gcc.gnu.org>
Fri, 6 Dec 2024 07:57:34 +0000 (08:57 +0100)
committerAndre Vehreschild <vehre@gcc.gnu.org>
Sun, 22 Dec 2024 15:28:47 +0000 (16:28 +0100)
commit586477d67bf2e320e8ec41f82b194259c1dcc43a
treec2bc83584499c325dcf4362c68deb76484225bf5
parent91d52f87c5bc48eacaf305d515e7cce192c2cf9c
Fortran: Replace getting of coarray data with accessor-based version. [PR107635]

Getting coarray data from remote images was slow, inefficient and did
not work for object files that where not compiled with coarray support
for derived types with allocatable/pointer components.  The old approach
emulated accessing data through a whole structure ref, which was error
prone for corner cases.  Furthermore was did it have a runtime
complexity of O(N), where N is the number of allocatable/pointer
components and descriptors involved.  Each of those needed communication
twice.  The new approach creates a routine for each access into a
coarray object putting all required operations there.  Looking a
tree-dump one will see those small routines.  But this time it is just
compiled fortran with all the knowledge of the compiler of bounds and so
on.  New paradigms will be available out of the box.  Furthermore is the
complexity of the communication reduced to be O(1).  E.g. the mpi
implementation sends one message for the parameters of the access and
one message back with the results without caring about the number of
allocatable/pointer/descriptor components in the access.

Identification of access routines is done be adding them to a hash map,
where the hash is the same on all images.  Translating the hash to an
index, which is the same on all images again, allows for fast calls of
the access routines.  Resolving the hash to an index is cached at
runtime, preventing additional hash map lookups.  A hashmap was use
because not all processor OS combinations may use the same address for
the access routine.

gcc/fortran/ChangeLog:

PR fortran/107635

* gfortran.h (gfc_add_caf_accessor): New function.
* gfortran.texi: Document new API routines.
* resolve.cc (get_arrayspec_from_expr): Synthesize the arrayspec
resulting from an expression, i.e. not only the rank, but also
the bounds.
(remove_coarray_from_derived_type): Remove coarray ref from a
derived type to access it in access routine.
(convert_coarray_class_to_derived_type): Same but for classes.
The result is a derived type.
(split_expr_at_caf_ref): Split an expression at the coarray
reference to move the reference after the coarray ref into the
access routine.
(check_add_new_component): Helper to add variables as
components to derived type transfered to the access routine.
(create_get_parameter_type): Create the derived type to transfer
addressing data to the access routine.
(create_get_callback): Create the access routine.
(add_caf_get_intrinsic): Use access routine instead of old
caf_get.
* trans-decl.cc (gfc_build_builtin_function_decls): Register new
API routines.
(gfc_create_module_variable): Use renamed flag.
(gfc_emit_parameter_debug_info):
(struct caf_accessor): Linked list of hash-access routine pairs.
(gfc_add_caf_accessor): Add a hash-access routine pair to above
linked list.
(create_caf_accessor_register): Add all registered hash-access
routine pairs to the current caf_init.
(generate_coarray_init): Use routine above.
(gfc_generate_module_vars): Use renamed flag.
(generate_local_decl): Same.
(gfc_generate_function_code): Same.
(gfc_process_block_locals): Same.
* trans-intrinsic.cc (conv_shape_to_cst): Build the product of a
shape.
(gfc_conv_intrinsic_caf_get): Create call to access routine.
(conv_caf_send): Adapt to caf_get using less arguments.
(gfc_conv_intrinsic_function): Same.
* trans.cc (gfc_trans_force_lval): Helper to ensure that an
expression can be used as an lvalue-ref.
* trans.h (gfc_trans_force_lval): See above.

libgfortran/ChangeLog:

* caf/libcaf.h (_gfortran_caf_register_accessor): New function
to register access routines at runtime.
(_gfortran_caf_register_accessors_finish): New function to
finish registration of access routine and sort hash map.
(_gfortran_caf_get_remote_function_index): New function to
convert an hash to an index.
(_gfortran_caf_get_by_ct): New function to get data from a
remote image using the access routine given by an index.
* caf/single.c (struct accessor_hash_t): Hashmap type.
(_gfortran_caf_send): Fixed formatting.
(_gfortran_caf_register_accessor): Register a hash accessor
routine.
(hash_compare): Compare two hashes for sort() and bsearch().
(_gfortran_caf_register_accessors_finish): Sort the hashmap to
allow bsearch()'s quick lookup.
(_gfortran_caf_get_remote_function_index): Map a hash to an
index.
(_gfortran_caf_get_by_ct): Get data from a remote image using
the index provided by get_remote_function_index().

gcc/testsuite/ChangeLog:

* gfortran.dg/coarray_atomic_5.f90: Adapted to look for
get_by_ct.
* gfortran.dg/coarray_lib_comm_1.f90: Same.
* gfortran.dg/coarray_stat_function.f90: Same.
12 files changed:
gcc/fortran/gfortran.h
gcc/fortran/gfortran.texi
gcc/fortran/resolve.cc
gcc/fortran/trans-decl.cc
gcc/fortran/trans-intrinsic.cc
gcc/fortran/trans.cc
gcc/fortran/trans.h
gcc/testsuite/gfortran.dg/coarray_atomic_5.f90
gcc/testsuite/gfortran.dg/coarray_lib_comm_1.f90
gcc/testsuite/gfortran.dg/coarray_stat_function.f90
libgfortran/caf/libcaf.h
libgfortran/caf/single.c