public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Tobias Burnus <tobias@codesourcery.com>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>, fortran <fortran@gcc.gnu.org>
Subject: Re: [Patch][v2] OpenMP/Fortran: Partially fix non-rect loop nests [PR107424]
Date: Tue, 31 Jan 2023 12:37:09 +0100	[thread overview]
Message-ID: <Y9j9ZX8mhMqYQUi4@tucnak> (raw)
In-Reply-To: <a07aa9bd-b07c-8c6d-29a8-1b3475639124@codesourcery.com>

On Wed, Jan 25, 2023 at 03:47:18PM +0100, Tobias Burnus wrote:
> updated patch included, i.e. avoiding 'count' for 'j' when a 'j.0' would
> do (i.e. only local var without the different step calculation). I also
> now reject if there is a non-unit step on the loop using an outer var.
> 
> Eventually still to be done: replace the 'sorry' by working code, i.e.
> implement the suggestions to handle some/all non-unit iteration steps as
> proposed in this thread.
> 
> On 20.01.23 18:39, Jakub Jelinek wrote:
> > I think instead of non-unity etc. it is better to talk about constant
> > step 1 or -1.
> 
> I concur.
> 
> 
> > The actual problem with non-simple loops for non-rectangular loops is
> > both in case it is an inner loop which uses some outer loop's iterator,
> > or if it is outer loop whose iterator is used, both of those cases
> > will not be handled properly.
> 
> I have now added a check for the other case as well.
> 
> Just to confirm, the following is fine, isn't it?
> 
> !$omp simd collapse(4)
> do i = 1, 10, 2
>   do outer_var = 1, 10  ! step = + 1
>     do j = 1, 10, 2
>       do inner_var = 1, outer_var  ! step = 1
> 
> i.e. both the inner_var and outer_var have 'step = 1',
> even if other loops in the 'collapse' have step != 1.
> I think it should be fine.

Yes, the loops which don't define outer_var for other loops nor
use outer_var from other loops can be in any form, we can compute
their number of iterations before the whole loop nest for them,
so for the non-rectangular iterations computations we can ignore
those except for multiplication by the pre-computed count.

> OpenMP/Fortran: Partially fix non-rect loop nests [PR107424]
> 
> This patch ensures that loop bounds depending on outer loop vars use the
> proper TREE_VEC format. It additionally gives a sorry if such an outer
> var has a non-one/non-minus-one increment as currently a count variable
> is used in this case (see PR).
> 
> Finally, it avoids 'count' and just uses a local loop variable if the
> step increment is +/-1.
> 
> 	PR fortran/107424
> 
> gcc/fortran/ChangeLog:
> 
> 	* trans-openmp.cc (struct dovar_init_d): Add 'sym' and
> 	'non_unit_incr' members.
> 	(gfc_nonrect_loop_expr): New.
> 	(gfc_trans_omp_do): Call it; use normal loop bounds
> 	for unit stride - and only create local loop var.
> 
> libgomp/ChangeLog:
> 
> 	* testsuite/libgomp.fortran/non-rectangular-loop-1.f90: New test.
> 	* testsuite/libgomp.fortran/non-rectangular-loop-1a.f90: New test.
> 	* testsuite/libgomp.fortran/non-rectangular-loop-2.f90: New test.
> 	* testsuite/libgomp.fortran/non-rectangular-loop-3.f90: New test.
> 	* testsuite/libgomp.fortran/non-rectangular-loop-4.f90: New test.
> 	* testsuite/libgomp.fortran/non-rectangular-loop-5.f90: New test.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gfortran.dg/goacc/privatization-1-compute-loop.f90: Update dg-note.
> 	* gfortran.dg/goacc/privatization-1-routine_gang-loop.f90: Likewise.
> 
> +static bool
> +gfc_nonrect_loop_expr (stmtblock_t *pblock, gfc_se *sep, int loop_n,
> +		       gfc_code *code, gfc_expr *expr, vec<dovar_init> *inits,
> +		       int simple, gfc_expr *curr_loop_var)
> +{
> +  int i;
> +  for (i = 0; i < loop_n; i++)
> +    {
> +      gcc_assert (code->ext.iterator->var->expr_type == EXPR_VARIABLE);
> +      if (gfc_find_sym_in_expr (code->ext.iterator->var->symtree->n.sym, expr))
> +	break;
> +      code = code->block->next;
> +    }
> +  if (i >= loop_n)
> +    return false;
> +
> +  /* Canonic format: TREE_VEC with [var, multiplier, offset].  */

I think we use everywhere Canonical rather than Canonic

> +  gfc_symbol *var = code->ext.iterator->var->symtree->n.sym;
> +
> +  tree tree_var = NULL_TREE;
> +  tree a1 = integer_one_node;
> +  tree a2 = integer_zero_node;
> +
> +  if (!simple)
> +    {
> +      /* FIXME: Handle non-unit iter steps, cf. PR fortran/107424.  */
> +      sorry_at (gfc_get_location (&curr_loop_var->where),
> +		"non-rectangular loop nest with step other than constant 1 "
> +		"or -1 for %qs", curr_loop_var->symtree->n.sym->name);
> +      return false;
> +    }
> +
> +  dovar_init *di;
> +  unsigned ix;
> +  FOR_EACH_VEC_ELT (*inits, ix, di)
> +    if (di->sym == var && !di->non_unit_iter)
> +      {
> +	tree_var = di->init;
> +	gcc_assert (DECL_P (tree_var));
> +	break;
> +      }
> +    else if (di->sym == var)
> +      {
> +	/* FIXME: Handle non-unit iter steps, cf. PR fortran/107424.  */
> +	sorry_at (gfc_get_location (&code->loc),
> +		"non-rectangular loop nest with step other than constant 1 "
> +		"or -1 for %qs", var->name);
> +	inform (gfc_get_location (&expr->where), "Used here");
> +	return false;
> +      }

I think it would be better formatted as
    if (di->sym == var)
      {
	if (!di->non_unit_iter)
	  {
	    ...
	  }
	else
	  {
	    ...
	  }
      }

> +      if (simple && !DECL_P (dovar))
> +	{
> +	  const char *name = code->ext.iterator->var->symtree->n.sym->name;
> +	  local_dovar = gfc_create_var (type, name);
> +	  dovar_init e = {code->ext.iterator->var->symtree->n.sym,
> +			  dovar, local_dovar, false};
> +	  inits.safe_push (e);
> +	}

For the separate local_dovar case, I'd be worried if we handle lastprivate
right.  From quick skimming I see some lastprivate clauses in some of
the tests, so if they verify the right value has been computed (say the
same as one would get with -fno-openmp), then fine.

	Jakub


  reply	other threads:[~2023-01-31 11:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-19 14:40 [Patch] " Tobias Burnus
2023-01-20 17:39 ` Jakub Jelinek
2023-01-20 18:00   ` Jakub Jelinek
2023-01-20 20:02     ` Jakub Jelinek
2023-01-25 14:47   ` [Patch][v2] " Tobias Burnus
2023-01-31 11:37     ` Jakub Jelinek [this message]
2023-02-09 14:46       ` Tobias Burnus
2023-02-09 14:49         ` Jakub Jelinek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y9j9ZX8mhMqYQUi4@tucnak \
    --to=jakub@redhat.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=tobias@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).