public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tobias Burnus <tobias@codesourcery.com>
To: <gcc-patches@gcc.gnu.org>, Julian Brown <julian@codesourcery.com>
Cc: <fortran@gcc.gnu.org>, <jakub@redhat.com>
Subject: Re: [PATCH v7 2/5] OpenMP/OpenACC: Rework clause expansion and nested struct handling
Date: Tue, 14 Nov 2023 11:21:30 +0100	[thread overview]
Message-ID: <ed9ed1ac-4c6c-460c-93f4-761682999b60@codesourcery.com> (raw)
In-Reply-To: <b96ae3b68fdc935bfd37f8343ba57e7058126c5d.1692398074.git.julian@codesourcery.com>

Hi Julian,

first round of comments - I think I need a second pass as the patch is
long and complex. The depth of review also was decreasing, hence, I
assume I will spot things in later parts of the compiler.

In any case, I think the patch is a huge leap forward and very useful!

Contrary to previous iterations of the patch series, it looks as if
{1,2}/5 could be sensibly applied before {3,4,5}/5. However, those are
smaller or tiny, it should be way quicker to review them!

* * *

CROSS REFS

This patch is part of the patch set
"[PATCH v7 0/5] OpenMP/OpenACC: map clause and OMP gimplify rework"
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627895.html

This patch set in turn is required for the follow-up patch set
https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629363.html
'[PATCH 0/8] OpenMP: lvalue parsing and "declare mapper" support'

and it looks as if it would be very useful for some other WIP patches
like map+iterator.

* * *

The patch 1/5 is just an indentation patch to make the following patch
smaller - and it has been approved multiple times.

This patch can be found at
   https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627897.html
in case someone wants to read the full patch or Julian's patch-intro
comments.

* * *

I do note that all 5 patches of this patch set apply cleanly with some
fuzzy line matching, but:

WARNING: at least for this patch (2/5), code gets wrongly applied
in (c-)parser.cc - see below.

On 19.08.23 00:47, Julian Brown wrote:
> This patch reworks clause expansion in the C, C++ and (to a lesser
> extent) Fortran front ends for OpenMP and OpenACC mapping nodes used in
> GPU offloading support.
>
> At present a single clause may be turned into several mapping nodes,
> or have its mapping type changed, in several places scattered through
> the front- and middle-end.  The analysis relating to which particular
> transformations are needed for some given expression has become quite hard
> to follow.  Briefly, we manipulate clause types in the following places:

[...]

[As the patch is very large, I copied the interesting bits out of the patch
and comment on them - I hope that preserves enough context to be useful.]


   tree c_omp_address_inspector::get_address ()


This class member function is unused. It returns 'orig' and that member variable
is used a couple of times in the member functions - but not this function.

I think it can be removed. (I also find the name slightly misleading.)

* * *


+c_omp_address_inspector::maybe_zero_length_array_section (tree clause)
+{
+  switch (OMP_CLAUSE_MAP_KIND (clause))
+    {
+    case GOMP_MAP_ALLOC:
+    case GOMP_MAP_IF_PRESENT:
+    case GOMP_MAP_TO:
+    case GOMP_MAP_FROM:
+    case GOMP_MAP_TOFROM:
+    case GOMP_MAP_ALWAYS_TO:
+    case GOMP_MAP_ALWAYS_FROM:
+    case GOMP_MAP_ALWAYS_TOFROM:
+    case GOMP_MAP_RELEASE:
+    case GOMP_MAP_DELETE:
+    case GOMP_MAP_FORCE_TO:
+    case GOMP_MAP_FORCE_FROM:
+    case GOMP_MAP_FORCE_TOFROM:
+    case GOMP_MAP_FORCE_PRESENT:

Shouldn't this also include:

GOMP_MAP_ALWAYS_PRESENT_TO:
GOMP_MAP_ALWAYS_PRESENT_FROM:
GOMP_MAP_ALWAYS_PRESENT_TOFROM:
GOMP_MAP_PRESENT_ALLOC:
GOMP_MAP_PRESENT_TO:

?

* * *

+omp_expand_access_chain (tree c, tree expr, vec<omp_addr_token *> &addr_tokens,
+                        unsigned *idx)
+{
+  using namespace omp_addr_tokenizer;
+  location_t loc = OMP_CLAUSE_LOCATION (c);
+  unsigned i = *idx;
+  tree c2 = NULL_TREE;
+  gomp_map_kind kind
+    = (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM
+       || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+          && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FROM
+              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE
+              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
+              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_FROM
+              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_FROM
+              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PRESENT_FROM)))
+      ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH;

GOMP_MAP_ALWAYS_PRESENT_FROM  missing?

And I personally find it more readable to have
   if (...
       ...
       ...)
     kind = GOMP_MAP_DETACH;
   else
     kind = GOMP_MAP_ATTACH;

as in the assignment above, the lhs is in this case really far from the rhs.


* * *

I do see in omp_expand_access_chain, which is shared by C and C++, that the following
accesses are handled:

   ACCESS_POINTER,
   ACCESS_POINTER_OFFSET,
   ACCESS_INDEXED_ARRAY,

But not:
   ACCESS_REF_TO_POINTER,
   ACCESS_REF_TO_POINTER_OFFSET,
   ACCESS_INDEXED_REF_TO_ARRAY

Do those need to be handled as well?

SIDENOTE: As Fortran allocatable components, reference-type variables in a C++ class ('class', 'struct')
are automatically be copied when doing 'map(var)' - contrary to pointer members that need to be explicitly
be mapped (either at mapping side or via a mapper). (And contrary to Fortran allocatables, reference-type members
are always "there" - not like with allocatables can change from unallocated to allocated - with all compilations
of polymorphism, array sizes, string lengths, ...).

* * *

+tree
+c_omp_address_inspector::expand_array_base (tree c,
...
+  bool map_p = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP;
+  bool implicit_p = (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+                    && OMP_CLAUSE_MAP_IMPLICIT (c));
...
+  if (!openmp
+      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP

How about using 'map_p' (twice), given that it is already
defined?

...

+       if (target)
+         {
+           c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
+           if (target
+               && !ref_to_ptr

Remove 'target &&' from the second condition.


* * *

+++ b/gcc/c/c-parser.cc
@@ -17659,7 +17659,8 @@ c_parser_omp_clause_detach (c_parser *parser, tree list)

  static tree
  c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
-                          const char *where, bool finish_p = true)
+                          const char *where, bool finish_p = true,
+                          bool target = false)

Here but also in gcc/c-family/c-omp.cc - I wonder whether this should be target_p for
consistency with most other boolean variables. The code is not really consistent,
but given that there is 'finish_p' here and map_p etc. in the other file, it seems
to make sense to use 'target_p.

* * *

If I try the example at
   https://discourse.llvm.org/t/how-do-i-map-an-array-of-pointers-using-array-notation/53640/3
it fails to compile with:

foo.c:11:34: error: ‘#pragma omp target enter data’ with map-type other than ‘to’, ‘tofrom’ or ‘alloc’ on ‘map’ clause
    11 | #pragma omp target enter data map(to: a[i][0:1])


The problem is that fuzzy 'patch' mis-apply the patch for c-parser.cc's

@@ -22106,6 +22111,7 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
           case GOMP_MAP_FIRSTPRIVATE_POINTER:
           case GOMP_MAP_ALWAYS_POINTER:
           case GOMP_MAP_ATTACH_DETACH:
+         case GOMP_MAP_ATTACH:
             break;
           default:
             map_seen |= 1;
@@ -22215,6 +22221,7 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
           case GOMP_MAP_FIRSTPRIVATE_POINTER:
           case GOMP_MAP_ALWAYS_POINTER:
           case GOMP_MAP_ATTACH_DETACH:
+         case GOMP_MAP_DETACH:
             break;
           default:
             map_seen |= 1;

Namely after applying it, the result is:


@@ -23329,0 +23335 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
+         case GOMP_MAP_ATTACH:
@@ -23494,0 +23501 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
+         case GOMP_MAP_DETACH:

That is, the new code is added
   to c_parser_omp_target_data       and c_parser_omp_target_enter_data
instead of
   to c_parser_omp_target_enter_data and c_parser_omp_target_exit_data.

* * *

Likewise issue for C++'s cp/parser.cc.

* * *

The first question is whether such code is also needed for 'target' and 'target data'
besides 'target enter/exit data'. It looks as if omp_expand_access_chain should also
apply here.

* * *

And trying the following snippet:

void f(){
   int **a,i,j,n;

   #pragma omp target enter data map(a[i][j:n])
   #pragma omp target exit data map(a[i][j:n])

   #pragma omp target data map(a[i][j:n])
   {
   #pragma omp target map(a[i][j:n])
      ;
   }
}

Results - when putting the enums to enter/exit data
instead of to target data / target enter data:


g++ fails, unless I messed up, with:

fiof.c:4:36: error: ‘#pragma omp target exit data’ with map-type other than ‘from’, ‘tofrom’, ‘release’ or ‘delete’ on ‘map’ clause
     4 |   #pragma omp target exit data map(a[i][j:n])
       |                                    ^
fiof.c:5:31: error: ‘#pragma omp target data’ with map-type other than ‘to’, ‘from’, ‘tofrom’ or ‘alloc’ on ‘map’ clause
     5 |   #pragma omp target data map(a[i][j:n])


And gcc fails with:

fiof.c:3:36: error: ‘a’ appears more than once in map clauses
     3 |   #pragma omp target enter data map(a[i][j:n])
       |                                    ^
fiof.c:4:35: error: ‘a’ appears more than once in map clauses
     4 |   #pragma omp target exit data map(a[i][j:n])
       |                                   ^
fiof.c:5:30: error: ‘a’ appears more than once in map clauses
     5 |   #pragma omp target data map(a[i][j:n])
       |                              ^
fiof.c:7:25: error: ‘a’ appears more than once in map clauses
     7 |   #pragma omp target map(a[i][j:n])

(Plus all '... data' ones: '... must contain at least one ...')


Can you fix this - and add an example in the spirit of the LLVM example above,
except that it should test all four 'target' variants.

Thanks,

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

  reply	other threads:[~2023-11-14 10:21 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-18 22:47 [PATCH v7 0/5] OpenMP/OpenACC: map clause and OMP gimplify rework Julian Brown
2023-08-18 22:47 ` [PATCH v7 1/5] OpenMP/OpenACC: Reindent TO/FROM/_CACHE_ stanza in {c_}finish_omp_clause Julian Brown
2023-08-18 22:47 ` [PATCH v7 2/5] OpenMP/OpenACC: Rework clause expansion and nested struct handling Julian Brown
2023-11-14 10:21   ` Tobias Burnus [this message]
2023-11-29 11:43     ` Julian Brown
2023-11-29 16:03       ` Tobias Burnus
2023-12-14  7:14       ` [committed] testsuite: Fix up target-enter-data-1.c on 32-bit targets Jakub Jelinek
2023-12-14 10:09         ` Julian Brown
2023-08-18 22:47 ` [PATCH v7 3/5] OpenMP: Pointers and member mappings Julian Brown
2023-12-06 11:36   ` Tobias Burnus
2023-12-07 17:24     ` Julian Brown
2023-12-11 11:44       ` Tobias Burnus
2023-08-18 22:47 ` [PATCH v7 4/5] OpenMP/OpenACC: Unordered/non-constant component offset runtime diagnostic Julian Brown
2023-12-14 14:26   ` Tobias Burnus
2023-12-15 13:00     ` Thomas Schwinge
2023-08-18 22:47 ` [PATCH v7 5/5] OpenMP/OpenACC: Reorganise OMP map clause handling in gimplify.cc Julian Brown
     [not found]   ` <20231216132507.5991c79e@squid.athome>
2023-12-19 15:41     ` Tobias Burnus
2023-12-20 21:29       ` Julian Brown
2023-12-21  8:51         ` Tobias Burnus

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=ed9ed1ac-4c6c-460c-93f4-761682999b60@codesourcery.com \
    --to=tobias@codesourcery.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=julian@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).