[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