Re: [Patch] OpenMP: Add iterator support to Fortran's depend; add affinity clause

2021-04-28 Thread Jakub Jelinek via Fortran
On Tue, Apr 27, 2021 at 03:36:38PM +0200, Tobias Burnus wrote:
> OpenMP 5's iterator can be used for
> - depend clause
> - affinity clause
> - mapping (unsupported and not touched)
> 
> (a) This patch add the iterator support to the Fortran FE
> and adds support for it to the depend clause.
> 
> (b) It also adds a conforming stub implementation (parse & ignore in ME)
>   for 'affinity' (Fortran, C, C++)
> 
> (c) Fortran's taskwait did not handle the depend clause, now it does.
> 
> The way the iterator is stored in Fortran is a bit convoluted,
> but should be fine:
> new namespace (such that symbols can be overridden and resolution works),
> using symbol->value for the iteration (begin:end:step) as array constructor,
> and abusing the ns->proc_name + its '->tlink' to generate an linked list,
> which avoids walking the ns->sym_root tree and has the user's order in
> the dump instead of the tree-walking order.
> 
> The ME implementation also seems to require a very special way the
> variables are stored. – It seems as if it works correctly for depend;
> hence, I hope I did correctly read the dump and tree sharing is correctly
> handled.
> 
> NOTE: The iterator Fortran patch includes one change from the post-OpenMP-5.0 
> spec:
> The '::' after the typespec in order to avoid Fortran free-form source issues 
> with:

Is the :: optional or required in free-form?

> 'iterator(integer i=1:10)' – namely: is this the integer 'i' or the variable
> 'integeri' (as spaces are ignored in fixed-form Fortran)?
> NOTE 2: The way it is implemented, the 'begin:end:step' expression is 
> evaluated
> multiple times - once per list item; I think this matches C, but I am not 
> completely
> sure nor whether that is a problem. (Unlikely a real-world problem.)

I believe C evaluates them just once and it would be nice if that could be
the case for Fortran too.
At least, looking at:
int bar (int);
void
foo (void)
{
  int a[64];
#pragma omp task depend (iterator (j=bar(0):bar(1):bar(2)) , out : a[j])
  ;
}
I see all the bar calls just once:
  saved_stack.6 = __builtin_stack_save ();
  try
{
  _1 = bar (0);
  _2 = bar (1);
  D.2078 = bar (2);
and never afterwards.  So, it would be nice if Fortran could do the same,
wrap stuff in SAVE_EXPR or whatever is needed for that.
And even
void
qux (void)
{
  int a[64], b[64], c[64];
#pragma omp task depend (iterator (j=bar(0):bar(1):bar(2)) , out : a[j], b[j], 
c[j])
  ;
}
seems to evaluate just once.

> NOTE 3: I did have some trouble reading the spec with regards to what in C is 
> permitted
> for 'affinity' ('locator-list); the code now mostly follows what is permitted 
> for 'depend'.

locator-list is used for both affinity and depend, so I guess the same.
I think at least for the latter C/C++ arranges that by using the same
iterator tree for the adjacent vars, so that the middle-end knows it can
just evaluate it once and emit one loop instead of one loop for each
variable separately.  Of course, depend (iterator (...),out : a[j]) 
depend(iterator (...),out : b[j])
will emit two different loops.

> @@ -15508,6 +15511,52 @@ c_parser_omp_iterators (c_parser *parser)
>return ret ? ret : error_mark_node;
>  }
>  
> +/* OpenMP 5.0:
> +   affinity( [depend-modifier :] variable-list)

For consistency, I think the syntax for other clauses puts space
before ( and before ) too.
Also, s/depend-modifier/aff-modifier/

> +   depend-modifier:

Likewise.

> + iterator ( iterators-definition )  */
> +
> +static tree
> +c_parser_omp_clause_affinity (c_parser *parser, tree list)
> +{
> +  location_t clause_loc = c_parser_peek_token (parser)->location;
> +  tree nl, iterators = NULL_TREE;
> +
> +  matching_parens parens;
> +  if (!parens.require_open (parser))
> +return list;
> +
> +  if (c_parser_next_token_is (parser, CPP_NAME))
> +{
> +  const char *p = IDENTIFIER_POINTER (c_parser_peek_token 
> (parser)->value);
> +  if (strcmp ("iterator", p) == 0)
> + {
> +   iterators = c_parser_omp_iterators (parser);
> +if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
> +  return list;

I think in this case it should
  if (iterators)
pop_scope ();
  parens.skip_until_found_close (parser);
before doing return list;

> + }
> +}
> +  nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
> +list);
> +  if (iterators)
> +{
> +  tree block = pop_scope ();
> +  if (iterators == error_mark_node)
> + iterators = NULL_TREE;
> +  else
> + {
> +   TREE_VEC_ELT (iterators, 5) = block;
> +   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
> + OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
> +OMP_CLAUSE_DECL (c));
> + }
> +}
> +
> +  parens.skip_until_found_close (parser);
> +  return nl;
> +}
> +
> +

> @@ -14578,17 +14592,24 @@ c_finish_omp_clauses (tree clauses, enum 
> c_omp_region_typ

[Patch] Fortran/OpenMP: Fix var-list expr parsing with array/dt (was: [Patch] OpenMP: Add iterator support to Fortran's depend; add affinity clause)

2021-04-28 Thread Tobias Burnus

On 28.04.21 15:41, Jakub Jelinek wrote:

@@ -261,6 +263,7 @@ gfc_match_omp_variable_list (const char *str, 
gfc_omp_namelist **list,
+  gfc_gobble_whitespace ();
   if ((allow_sections && gfc_peek_ascii_char () == '(')
   || (allow_derived && gfc_peek_ascii_char () == '%')

Is this change specific to depend/affinity or iterators?
If not, shouldn't it go in separately and with a testcase that shows when it
is needed?


I encountered it when writing a testcase - and the testcase was using it.
However, if you think it makes sense to have it separately.

It fixes the issue:

7 | !$omp target enter data map( to: a (:) )
  |   1
Error: Syntax error in OpenMP variable list at (1)

OK for mainline?

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Fortran/OpenMP: Fix var-list expr parsing with array/dt

gcc/fortran/ChangeLog:

	* openmp.c (gfc_match_omp_variable_list): Gobble whitespace before
	checking whether a '%' or '(' follows as next character.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/map-5.f90: New test.

 gcc/fortran/openmp.c |  1 +
 gcc/testsuite/gfortran.dg/gomp/map-5.f90 | 13 +
 2 files changed, 14 insertions(+)

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index a1b057227b7..7eeabff8e76 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -261,6 +261,7 @@ gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
 	case MATCH_YES:
 	  gfc_expr *expr;
 	  expr = NULL;
+	  gfc_gobble_whitespace ();
 	  if ((allow_sections && gfc_peek_ascii_char () == '(')
 	  || (allow_derived && gfc_peek_ascii_char () == '%'))
 	{
diff --git a/gcc/testsuite/gfortran.dg/gomp/map-5.f90 b/gcc/testsuite/gfortran.dg/gomp/map-5.f90
new file mode 100644
index 000..2b4b341bc51
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/map-5.f90
@@ -0,0 +1,13 @@
+implicit none
+type t
+  integer :: b(5)
+end type t
+integer :: a(5), x, y(5)
+type(t) :: b
+!$omp target enter data map( to: a (:) )
+!$omp target enter data map( to: b % b )
+!$omp target enter data map( to: a(:) )
+!$omp target depend(out: y (2)) nowait
+!$omp end target
+
+end


Re: [Patch] Fortran/OpenMP: Fix var-list expr parsing with array/dt (was: [Patch] OpenMP: Add iterator support to Fortran's depend; add affinity clause)

2021-04-28 Thread Jakub Jelinek via Fortran
On Wed, Apr 28, 2021 at 10:26:44PM +0200, Tobias Burnus wrote:
> On 28.04.21 15:41, Jakub Jelinek wrote:
> > > @@ -261,6 +263,7 @@ gfc_match_omp_variable_list (const char *str, 
> > > gfc_omp_namelist **list,
> > > +  gfc_gobble_whitespace ();
> > >if ((allow_sections && gfc_peek_ascii_char () == '(')
> > >|| (allow_derived && gfc_peek_ascii_char () == '%')
> > Is this change specific to depend/affinity or iterators?
> > If not, shouldn't it go in separately and with a testcase that shows when it
> > is needed?
> 
> I encountered it when writing a testcase - and the testcase was using it.
> However, if you think it makes sense to have it separately.
> 
> It fixes the issue:
> 
> 7 | !$omp target enter data map( to: a (:) )
>   |   1
> Error: Syntax error in OpenMP variable list at (1)
> 
> OK for mainline?

Yes, thanks.
And IMHO also should be backported at least to 11.

Jakub