This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, OpenACC] Properly handle wait clause with no arguments
- From: Thomas Schwinge <thomas at codesourcery dot com>
- To: Chung-Lin Tang <cltang at codesourcery dot com>
- Cc: <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, <fortran at gcc dot gnu dot org>
- Date: Mon, 17 Dec 2018 16:27:14 +0100
- Subject: Re: [PATCH, OpenACC] Properly handle wait clause with no arguments
- References: <4f14f976-3677-9f94-2ca7-83f5dc8dd7ae@mentor.com> <87d0rgr99i.fsf@euler.schwinge.homeip.net> <b5f70b04-149b-4dda-67d7-99aaedfe2f33@mentor.com>
Hi Chung-Lin!
On Tue, 27 Nov 2018 22:41:54 +0800, Chung-Lin Tang <chunglin_tang@mentor.com> wrote:
> On 2018/11/8 3:13 AM, Thomas Schwinge wrote:
> > Now, why do we need the following changes, in this rather "convoluted"
> > form:
>
| --- gcc/omp-expand.c (revision 263981)
| +++ gcc/omp-expand.c (working copy)
| @@ -7381,16 +7381,32 @@ expand_omp_target (struct omp_region *region)
| /* ... push a placeholder. */
| args.safe_push (integer_zero_node);
|
| + bool noval_seen = false;
| + tree noval = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
| +
| for (; c; c = OMP_CLAUSE_CHAIN (c))
| if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT)
| {
> >> + tree wait_expr = OMP_CLAUSE_WAIT_EXPR (c);
> >> +
> >> + if (TREE_CODE (wait_expr) == INTEGER_CST
> >> + && tree_int_cst_compare (wait_expr, noval) == 0)
> >> + {
> >> + noval_seen = true;
> >> + continue;
> >> + }
> >> +
> >> args.safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c),
> >> - integer_type_node,
> >> - OMP_CLAUSE_WAIT_EXPR (c)));
> >> + integer_type_node, wait_expr));
> >> num_waits++;
> >> }
> >>
> >> - if (!tagging || num_waits)
> >> + if (noval_seen && num_waits == 0)
> >> + args[t_wait_idx] =
> >> + (tagging
> >> + ? oacc_launch_pack (GOMP_LAUNCH_WAIT, NULL_TREE, GOMP_ASYNC_NOVAL)
> >> + : noval);
> >> + else if (!tagging || num_waits)
> >> {
> >> tree len;
>
> >> case GOMP_LAUNCH_WAIT:
> >> {
> >> - unsigned num_waits = GOMP_LAUNCH_OP (tag);
> >> + /* Be careful to cast the op field as a signed 16-bit, and
> >> + sign-extend to full integer. */
> >> + int num_waits = ((signed short) GOMP_LAUNCH_OP (tag));
> >>
> >> - if (num_waits)
> >> + if (num_waits > 0)
> >> goacc_wait (async, num_waits, &ap);
> >> + else if (num_waits == acc_async_noval)
> >> + acc_wait_all_async (async);
>
> > Why can't we just pass "GOMP_ASYNC_NOVAL" through like any other
> > async-argument (that is, map a single "wait" clause to "num_waits == 1,
> > *ap == GOMP_ASYNC_NOVAL"), and then handle that case in "goacc_wait",
> > avoiding all these interface changes and special casing in different
> > functions?
> >
> > Or am I not understanding correctly what the purpose of this is?
>
> I think the original intention was that wait(acc_async_noval) should
> correspond to "wait all" semantics, hence we should be able to ignore
> and discard other wait(<arg>) clauses if they exist.
Ah, I see. But, I'm not sure whether an optimization for such "strange"
user code ("#pragma acc [...] wait(0, 1, acc_async_noval, 5, 0, [...])")
really warrants any such GCC code complications. ;-)
> Having that said, I think there is some incorrect code in my patch wrt
> this intended behavior, which I'll revise.
(OK, still waiting for that.)
> (The assumption of an argument-less wait clause to mean "wait all" is
> derived from the closely documented OpenACC wait *directive* specification.
> Frankly speaking, the prior section on the wait *clause* is not explicitly
> clear on this, though 'wait all' is a reasonable assumption. It would still
> be helpful if we asked the OpenACC SC to clarify)
(We're discussing that with them, but what you describe indeed I also
would agree to be what's intended, so OK to proceed assuming that.)
> As for the idea on stuffing more code into goacc_wait(), I think that's
> a pretty good suggestion, since all uses of it in oacc-parallel.c are
> actually quite similar; re-factoring this part should make things more elegant.
ACK.
> > My understanding is that before, GCC never generates "negative
> > async-arguments" (now used for "GOMP_ASYNC_NOVAL"), but only non-negative
> > ones (real "async-arguments"), which we continue to handle, as before.
>
> > Isn't that sufficient for the ABI compatibility that we promise, which is
> > (unless I'm confused now?) that old (existing) executables continue to
> > run correctly when dynamically linking against a new libgomp. Or do we
> > also have to care about the case that an executable built with a new
> > version of GCC has to work when dynamically linked against an old
> > libgomp?
>
> I think either way, encoding GOMP_ASYNC_NOVAL in num_waits or as an argument
> should be okay for backward compatibility, i.e. old binaries should still
> work with new libgomp with this modification.
>
> As for new binaries vs old libgomp, I believe with the original libgomp
> oacc-parallel.c code, it's not quite possible to achieve the intended wait all
> behavior by playing with num_waits or arguments.
>
> I'll revise the patch and re-submit later.
OK, thanks!
Grüße
Thomas