[PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts

Thomas Schwinge thomas@codesourcery.com
Wed May 20 09:37:35 GMT 2020


Hi Julian!

Moving this over, from the "Fix component mappings with derived types for
OpenACC" thread,
<http://mid.mail-archive.com/20200110014945.5643ace5@squid.athome>, where
you propose to change this 'GOMP_MAP_STRUCT' handling code:

On 2019-12-17T22:03:47-0800, Julian Brown <julian@codesourcery.com> wrote:
> --- a/libgomp/oacc-mem.c
> +++ b/libgomp/oacc-mem.c

> @@ -1075,6 +1119,39 @@ goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
>             gomp_remove_var_async (acc_dev, n, aq);
>         }
>         break;
> +
> +     case GOMP_MAP_STRUCT:
> +       {
> +         int elems = sizes[i];
> +         for (int j = 1; j <= elems; j++)
> +           {
> +             struct splay_tree_key_s k;
> +             k.host_start = (uintptr_t) hostaddrs[i + j];
> +             k.host_end = k.host_start + sizes[i + j];
> +             splay_tree_key str;
> +             str = splay_tree_lookup (&acc_dev->mem_map, &k);
> +             if (str)
> +               {
> +                 if (finalize)
> +                   {
> +                     str->refcount -= str->virtual_refcount;
> +                     str->virtual_refcount = 0;
> +                   }
> +                 if (str->virtual_refcount > 0)
> +                   {
> +                     str->refcount--;
> +                     str->virtual_refcount--;
> +                   }
> +                 else if (str->refcount > 0)
> +                   str->refcount--;
> +                 if (str->refcount == 0)
> +                   gomp_remove_var_async (acc_dev, str, aq);
> +               }
> +           }
> +         i += elems;
> +       }
> +       break;
> +
>       default:
>         gomp_fatal (">>>> goacc_exit_data_internal UNHANDLED kind 0x%.2x",
>                         kind);

... into an "empty 'case GOMP_MAP_STRUCT:' as a no-op, so that we don't
run into 'default:' case 'goacc_exit_data_internal UNHANDLED kind'" (my
words/interpretation).

Further citing myself,
<http://mid.mail-archive.com/87ftbw9kqh.fsf@euler.schwinge.homeip.net>:

| Is my understanding correct that "fixed" GCC won't generate such
| 'GOMP_MAP_STRUCT' anymore (I have't studied in detail), and this empty
| 'case GOMP_MAP_STRUCT:' only remains in here for backwards compatibility?
| In this case, please add a comment to the code, stating this.

My guess was wrong: running a quick test, I do see that we still generate
'GOMP_MAP_STRUCT' for OpenACC unmap:

    --- libgomp/oacc-mem.c
    +++ libgomp/oacc-mem.c
    @@ -1163,6 +1165,7 @@ goacc_exit_data_internal
          break;

        case GOMP_MAP_STRUCT:
    +     assert (!"GOMP_MAP_STRUCT");
          break;

        default:
          gomp_fatal (">>>> goacc_exit_data_internal UNHANDLED kind 0x%.2x",
                          kind);

... regresses:

  - 'libgomp.oacc-c-c++-common/deep-copy-7.c'
  - 'libgomp.oacc-c-c++-common/deep-copy-8.c'
  - 'libgomp.oacc-fortran/classtypes-2.f95'
  - 'libgomp.oacc-fortran/deep-copy-4.f90'
  - 'libgomp.oacc-fortran/deep-copy-5.f90'
  - 'libgomp.oacc-fortran/deep-copy-6.f90'
  - 'libgomp.oacc-fortran/derivedtype-2.f95'

| Otherwise,
| please add a comment why "do nothing" is appropriate for
| 'GOMP_MAP_STRUCT'.

I suppose we still need to unmap the "'GOMP_MAP_STRUCT' components", but
can do that individually, outside of the 'GOMP_MAP_STRUCT' context.
That'd then also explain...

| In particular, for both scenarios, why we don't need
| to skip the following 'sizes[i]' mappings?

... this question.

But one step back.  Why generate 'GOMP_MAP_STRUCT' for unmap, if we then
just skip it in libgomp handling?  Cross checking, OpenMP
'libgomp/target.c:gomp_exit_data' also doesn't expect to see any
'GOMP_MAP_STRUCT'.

For example, 'libgomp.oacc-c-c++-common/deep-copy-7.c':

    #pragma acc exit data copyout(v.b[:n]) finalize
    #pragma acc exit data delete(v.a)

'deep-copy-7.c.004t.original':

    #pragma acc exit data finalize map(from:*v.b [len: (sizetype) n * 4]) map(attach_detach:v.b [bias: 0]);
    #pragma acc exit data map(release:v.a);

'deep-copy-7.c.005t.gimple':

    #pragma omp target oacc_enter_exit_data finalize map(struct:v [len: 1]) map(delete:v.b [len: 8]) map(force_from:*_15 [len: _14]) map(force_detach:v.b [bias: 0])
    #pragma omp target oacc_enter_exit_data map(struct:v [len: 1]) map(release:v.a [len: 4])

I haven't studied 'GOMP_MAP_STRUCT' in detail (so it may be easy to prove
me wrong), but for OpenACC 'exit data' etc., these 'map(struct:[...])'
seem "pointless" to me, given that in libgomp we (intend to) just skip
them?

Well, and quickly I find that's exactly what OpenMP 'target exit data' is
doing, and doing the same for OpenACC 'exit data':

    --- gcc/gimplify.c
    +++ gcc/gimplify.c
    @@ -10406,7 +10406,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
                }
            }
          else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
    -              && code == OMP_TARGET_EXIT_DATA)
    +              && (code == OMP_TARGET_EXIT_DATA
    +                  || code == OACC_EXIT_DATA))
            remove = true;
          else if (DECL_SIZE (decl)
                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST

..., 'deep-copy-7.c.005t.gimple' gets simplified as expected:

    -        #pragma omp target oacc_enter_exit_data finalize map(struct:v [len: 1]) map(delete:v.b [len: 8]) map(force_from:*_15 [len: _14]) map(force_detach:v.b [bias: 0])
    +        #pragma omp target oacc_enter_exit_data finalize map(delete:v.b [len: 8]) map(force_from:*_15 [len: _14]) map(force_detach:v.b [bias: 0])
    -        #pragma omp target oacc_enter_exit_data map(struct:v [len: 1]) map(release:v.a [len: 4])
    +        #pragma omp target oacc_enter_exit_data map(release:v.a [len: 4])

..., and all the "'assert' regressions" mentioned above again disappear,
and so 'GOMP_MAP_STRUCT' handling could be removed from
'libgomp/oacc-mem.c:goacc_exit_data_internal' (and 'default:'
'gomp_fatal' would then catch any such cases).

But of course, given that GCC 10.1 now does generate these
'GOMP_MAP_STRUCT's, we do have to support them in one way or another...


Grüße
 Thomas
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter


More information about the Gcc-patches mailing list