[Patch][v2] OpenMP: 'interop' construct - add C parser support, improve Fortran pasing

2024-11-12 Thread Tobias Burnus

Minor update: Main change is to use 'char' more consistently
(e.g. for omp_get_fr_id_from_name and GOMP_INTEROP_IFR_UNKNOWN etc.)
in the hope that it will fix the build bot issues for ARM.

Additionally, I fixed some indentation "issues" in one testcase and
in for C++, the __GOMP_UINTPTR_T_ENUM macro definitions.

Otherwise it is unchanged.

Tobias

Tobias Burnus wrote:

Background:
   omp interop device(1) init(prefer_type("cuda"), targetsync: obj) 
depend(inout: x) nowait
 …
   omp interop destroy(obj)

initializes the omp_interop_t / integer(omp_interop_kind) variable for device 
'1'
and (thanks to 'targetsync') creates a stream object. 'obj' can then be used as
follows: first, we have to check the returned type (e.g. CUDA as wished for or
something else including N/A alias omp_interop_fr_none).
The (CUDA) stream, (cuda) device number etc. can then be extracted and used with
CUDA calls.

In terms of the parser, that's quite boring if there wasn't the prefer_type 
modifier.
Besides taking a list of strings and constant integer expressions, OpenMP 6.0 
also
permits:
prefer_type( {fr("cuda"), attr("ompx_1", "ompx_2")},
  {attr("ompx_2"), attr("ompx_4")} )
i.e. the same to 'fr' and a string to 'attr' that must start with 'ompx_'. There
can be 0 or 1 'fr' and >= 0 'attr' per curly brace (but at least one 'fr'/'attr'
must be specified).

* * *

The attached patch add the C parser, which in turn means that there is now a
middle-end representation for it. Additionally, it fixes the Fortran compiler
for issues found while doing so - and for a newer OpenMP 6 spec change, i.e.
only one 'fr' value permitted per {…} and the constant integer value to 'fr'
may be any const integer expr not only an identifier, which is the same as
for the old, simpler 'prefer_type("hip",int_expr,"sycl")' syntax.

Comments, remarks, concerns, suggestions before I commit it?

Tobias

* * *

PS: Once 'omp interop' has returned the object, the
https://gcc.gnu.org/onlinedocs/libgomp/Interoperability-Routines.html
can be used to access it. See libgomp.*/interop-routines*.{F,F90,c} for
some testcases. - Proper combined testcases will be added once the
compiler middle-end + libgomp parts have been implemented to connect the
two. → TODO: C++ parser, middle-end code including calling new libgomp function.

Once done, the AMD GPU (gcn) and Nvidia GPU libgomp plugins need to handle
it to return an interop object for CUDA/CUDA_DRIVER/HIP/HSA; I posted an
RFC patch the other day, which should mostly work once (↑) is done; it still
requires some updates, cleanups and additions, but otherwise … :-)
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661207.htmlOpenMP: 'interop' construct - add C parser support, improve Fortran pasing

Add middle end support for the 'interop' directive and the 'init', 'use',
and 'destroy' clauses - but fail with a sorry, unimplemented in gimplify.cc.

For Fortran, generate the tree code, update the internal representation,
add some more diagnostic checks and update for newer specification changes
('fr' only takes a single value, but it integer expressions are permitted
again [like with the old syntax] not only constant identifiers).

For C, this patch adds the full parser support for 'interop'.

Still missing (later commit) is parsing support in C++ and actually
handling the directive in the middle end and in libgomp.

The GOMP_INTEROP_IFR_* internal values have been changed to have space
for vendor specific values that are adjacent to the existing values
but negative, if needed.

gcc/c-family/ChangeLog:

	* c-common.h (c_omp_interop_t_p): New prototype.
	* c-omp.cc (c_omp_interop_t_p): Check whether the type is
	omp_interop_t.
	(c_omp_directives): Uncomment 'interop'.
	* c-pragma.cc (omp_pragmas): Add 'interop'.
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_INTEROP.
	(enum pragma_omp_clause): Add init, use, and destroy clauses.

gcc/c/ChangeLog:

	* c-parser.cc (INCLUDE_STRING): Define.
	(c_parser_pragma): Handle 'interop' directive.
	(c_parser_omp_clause_name, c_parser_omp_all_clauses): Handle init,
	use, and destroy clauses.
	(c_parser_omp_clause_destroy, c_parser_omp_modifier_prefer_type,
	c_parser_omp_clause_init, c_parser_omp_clause_use,
	OMP_INTEROP_CLAUSE_MASK, c_parser_omp_interop): New.
	* c-typeck.cc (c_finish_omp_clauses): Add missing OPT_Wopenmp to
	a warning; handle new clauses.

gcc/fortran/ChangeLog:

	* gfortran.h (gfc_omp_namelist): Cleanup interop internal
	representation.
	* dump-parse-tree.cc (show_omp_namelist): Update for changed
	internal representation.
	* match.cc (gfc_free_omp_namelist): Likewise.
	* openmp.cc (gfc_match_omp_prefer_type, gfc_match_omp_init):
	Likewise; also handle some corner cases better and update for
	newer 6.0 changes related to 'fr'.
	(resolve_omp_clauses): Add type-check for interop variables.
	* trans-openmp.cc (gfc_trans_omp_clauses): Handle init, use
	and destroy clauses.
	(gfc_trans_openmp_interop): New.
	(gfc_trans_omp_directive): Call it.

gc

Re: [Patch, fortran] PR105054 - [12/13/14/15 Regression] Using one kind of pointer functions causes the compiler to hang since r11-3029-g2b0df0a6ac79b34f

2024-11-12 Thread Jerry D

On 11/12/24 5:23 AM, Paul Richard Thomas wrote:

Hi All,

The ChangeLog and comment make it clear what this patch does and why.

OK for mainline and backporting after a week or so?

Regards

Paul



In the test case:

A comment s/resul/result/

Also the test conditional

if (trim (array_strings2(i)) /= trim(chr(i))) print *, i, 
trim(array_strings2(i)), ' xx ',trim (chr(i))


Change print to a STOP ?

Otherwise looks good to me and OK

Jerry


[Patch, fortran] PR105054 - [12/13/14/15 Regression] Using one kind of pointer functions causes the compiler to hang since r11-3029-g2b0df0a6ac79b34f

2024-11-12 Thread Paul Richard Thomas
Hi All,

The ChangeLog and comment make it clear what this patch does and why.

OK for mainline and backporting after a week or so?

Regards

Paul
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 51e0af410c1..c54b3c85621 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -12108,6 +12108,17 @@ get_temp_from_expr (gfc_expr *e, gfc_namespace *ns)
   tmp->n.sym->attr.use_assoc = 0;
   tmp->n.sym->attr.intent = INTENT_UNKNOWN;
 
+  /* A new charlen is required to ensure that the variable string length
+ is different to that of the original lhs for deferred fcn results.  */
+  if (e->expr_type == EXPR_FUNCTION
+  && e->ts.type == BT_CHARACTER
+  && e->symtree->n.sym->result->ts.deferred)
+{
+  tmp->n.sym->ts.u.cl = gfc_get_charlen();
+  tmp->n.sym->ts.deferred = 1;
+  tmp->n.sym->ts.u.cl->next = gfc_current_ns->cl_list;
+  gfc_current_ns->cl_list = tmp->n.sym->ts.u.cl;
+}
 
   if (as)
 {
diff --git a/gcc/testsuite/gfortran.dg/ptr_func_assign_6.f08 b/gcc/testsuite/gfortran.dg/ptr_func_assign_6.f08
new file mode 100644
index 000..1fc0d69616a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ptr_func_assign_6.f08
@@ -0,0 +1,89 @@
+! { dg-do run }
+!
+! Test the fix for PR105054.
+!
+! Contributed by Arjen Markus  
+!
+module string_pointers
+implicit none
+character(len=20), dimension(10), target :: array_strings
+character(len=:), dimension(:), target, allocatable :: array_strings2
+
+contains
+
+function pointer_to_string( i , flag)
+ integer, intent(in) :: i, flag
+
+ character(len=:), pointer :: pointer_to_string
+
+ if (flag == 1) then
+   pointer_to_string => array_strings(i)
+   return
+ endif
+
+ if (.not.allocated (array_strings2)) allocate (array_strings2(4), &
+mold = '')
+ pointer_to_string => array_strings2(i)
+end function pointer_to_string
+
+function pointer_to_string2( i , flag) result (res)
+ integer, intent(in) :: i, flag
+
+ character(len=:), pointer :: res
+
+ if (flag == 1) then
+   res => array_strings(i)
+   return
+ endif
+
+ if (.not.allocated (array_strings2)) allocate (array_strings2(4), &
+mold = '')
+ res => array_strings2(i)
+end function pointer_to_string2
+
+end module string_pointers
+
+program chk_string_pointer
+use string_pointers
+implicit none
+integer :: i
+character(*), parameter :: chr(4) = ['1234  ','ABCDefgh  ', &
+ '12345678  ','  ']
+
+pointer_to_string(1, 1) = '1234567890'
+pointer_to_string(2, 1) = '12345678901234567890'
+
+if (len(pointer_to_string(3, 1)) /= 20) stop 1
+
+array_strings(1) = array_strings(1)(1:4) // 'ABC'
+if (pointer_to_string(1, 1) /= '1234ABC') stop 2
+
+pointer_to_string(1, 2) = '1234'
+pointer_to_string(2, 2) = 'ABCDefgh'
+pointer_to_string(3, 2) = '12345678'
+
+do i = 1, 3
+  if (trim (array_strings2(i)) /= trim(chr(i))) print *, i, trim(array_strings2(i)), ' xx ',trim (chr(i))
+enddo
+
+! Clear the target arrays
+array_strings = repeat (' ', 20)
+deallocate (array_strings2)
+
+! Repeat with an explicit resul.
+pointer_to_string2(1, 1) = '1234567890'
+pointer_to_string2(2, 1) = '12345678901234567890'
+
+if (len(pointer_to_string(3, 1)) /= 20) stop 1
+
+array_strings(1) = array_strings(1)(1:4) // 'ABC'
+if (pointer_to_string(1, 1) /= '1234ABC') stop 2
+
+pointer_to_string2(1, 2) = '1234'
+pointer_to_string2(2, 2) = 'ABCDefgh'
+pointer_to_string2(3, 2) = '12345678'
+
+do i = 1, 3
+  if (trim (array_strings2(i)) /= trim(chr(i))) print *, i, trim(array_strings2(i)), ' xx ',trim (chr(i))
+enddo
+end program chk_string_pointer


Change.Logs
Description: Binary data