Re: [PATCH, OG10, OpenMP 5.0, committed] Remove array section base-pointer mapping semantics, and other front-end adjustments.

2021-05-14 Thread Chung-Lin Tang



On 2021/5/11 11:15 , Thomas Schwinge wrote:

Hi Chung-Lin!

On 2021-05-11T19:28:04+0800, Chung-Lin Tang  wrote:

This patch largely implements three pieces of functionality:

(1) Per discussion and clarification on the omp-lang mailing list,
standards conforming behavior for mapping array sections should *NOT* also map 
the base-pointer,
i.e for this code:

 struct S { int *ptr; ... };
 struct S s;
 #pragma omp target enter data map(to: s.ptr[:100])

Currently we generate after gimplify:
#pragma omp target enter data map(struct:s [len: 1]) map(alloc:s.ptr [len: 8]) \
map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 
0])

which is deemed incorrect. After this patch, the gimplify results are now 
adjusted to:
#pragma omp target enter data map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0])
(the attach operation is still generated, and if s.ptr is already mapped prior, 
attachment will happen)

The correct way of achieving the base-pointer-also-mapped behavior would be to 
use:
#pragma omp target enter data map(to: s.ptr, s.ptr[:100])

This adjustment in behavior required a number of small adjustments here and 
there in gimplify, including
to accomodate map sequences for C++ references.


I'm a bit confused by that -- this mandates the bulk of the testsuite
changes that you've included, and these seem a step backwards in terms of
user experience, but then, I have no state on the exact OpenMP
specification requirements, so you certainly may be right on that.  (And
also, as Julian mentioned, how this relates to OpenACC semantics, which I
also haven't considered in detail -- but I note you didn't adjust any
OpenACC testcases for that, so I suppose that's really conditionalized to
OpenMP only.)


It is indeed a bit awkward to use, but that's what the omp-lang list seemed to 
decide.

This change is OpenMP only. I took care to only handle OpenMP constructs like 
this in the middle-end,
of course this does not preclude some mistake in adjusting the shared code 
paths...




There is also a small Fortran front-end patch involved (hence CCing Tobias).
The new gimplify processing changed behavior in handling 
GOMP_MAP_ALWAYS_POINTER maps such that
the libgomp.fortran/struct-elem-map-1.f90 regressed. It appeared that the 
Fortran FE was generating
a GOMP_MAP_ALWAYS_POINTER for array types, which didn't seem quite correct, and 
the pre-patch behavior
was removing this map anyways. I have a small change in 
trans-openmp.c:gfc_trans_omp_array_section
to not generate the map in this case, and so far no bad test results.


Makes sense to argue that one separately, with testcases, for the master
branch submission?


Maybe. although this part was needed to solve a regression caused by the above 
changes.


(2) The second part (though kind of related to the first above) are fixes in 
libgomp/target.c
to not overwrite attached pointers when handling device<->host copies, mainly for the 
"always" case.
This behavior is also noted in the 5.0 spec, but not yet properly coded before.


Likewise, if that makes sense?


Some of the separation of base-pointer/array-section in map clauses seemed to 
step on this bug
(e.g. if one mechanically updates "s.ptr[:N]" into "s.ptr, s.ptr[:N]", and a 
target-update overwrites the
base-pointer)  So it's arguably separate, but also can cause some testsuite 
chaos if not included together.




(3) The third is a set of changes to the C/C++ front-ends to extend the allowed 
component access syntax
in map clauses. This is actually mainly an effort to allow SPEC HPC to compile, 
so despite in the long
term the entire map clause syntax parsing is probably going to be revamped, 
we're still adding this in
for now. These changes are enabled for both OpenACC and OpenMP.


Likewise, if that makes sense?  ;-)


Yeah, this might be separated :P


Tested on x86_64-linux with nvptx offloading with no regressions.


I'm seeing a regression with
'libgomp.oacc-c-c++-common/noncontig_array-1.c' execution testing, both C
and C++, for '-O2' (but not '-O0'), and only for about half of the
invocations.  But it seems to reliable reproduce in GDB:

 Thread 1 "a.out" received signal SIGSEGV, Segmentation fault.
 gomp_decrement_refcount (do_remove=, do_copy=, delete_p=false, refcount_set=0x0, k=0xc4d450) at 
[...]/source-gcc/libgomp/target.c:468
 468   uintptr_t orig_refcount = *refcount_ptr;
 (gdb) bt
 #0  gomp_decrement_refcount (do_remove=, 
do_copy=, delete_p=false, refcount_set=0x0, k=0xc4d450) at 
[...]/source-gcc/libgomp/target.c:468
 #1  gomp_unmap_vars_internal (aq=0x0, aq@entry=0x8223c0, refcount_set=0x0, 
do_copyfrom=, do_copyfrom@entry=true, tgt=tgt@entry=0xc696a0) at 
[...]/source-gcc/libgomp/target.c:2065
 #2  goacc_unmap_vars (tgt=tgt@entry=0xc696a0, 
do_copyfrom=do_copyfrom@entry=true, aq=aq@entry=0x0) at 
[...]/source-gcc/libgomp/target.c:2118
 #3  0x77daa41c in GOACC_parallel_keyed (flags_m=flags_m@entry=-1, 

Re: [PATCH, OG10, OpenMP 5.0, committed] Remove array section base-pointer mapping semantics, and other front-end adjustments.

2021-05-11 Thread Thomas Schwinge
Hi Chung-Lin!

On 2021-05-11T19:28:04+0800, Chung-Lin Tang  wrote:
> This patch largely implements three pieces of functionality:
>
> (1) Per discussion and clarification on the omp-lang mailing list,
> standards conforming behavior for mapping array sections should *NOT* also 
> map the base-pointer,
> i.e for this code:
>
> struct S { int *ptr; ... };
> struct S s;
> #pragma omp target enter data map(to: s.ptr[:100])
>
> Currently we generate after gimplify:
> #pragma omp target enter data map(struct:s [len: 1]) map(alloc:s.ptr [len: 
> 8]) \
>map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 
> 0])
>
> which is deemed incorrect. After this patch, the gimplify results are now 
> adjusted to:
> #pragma omp target enter data map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 
> 0])
> (the attach operation is still generated, and if s.ptr is already mapped 
> prior, attachment will happen)
>
> The correct way of achieving the base-pointer-also-mapped behavior would be 
> to use:
> #pragma omp target enter data map(to: s.ptr, s.ptr[:100])
>
> This adjustment in behavior required a number of small adjustments here and 
> there in gimplify, including
> to accomodate map sequences for C++ references.

I'm a bit confused by that -- this mandates the bulk of the testsuite
changes that you've included, and these seem a step backwards in terms of
user experience, but then, I have no state on the exact OpenMP
specification requirements, so you certainly may be right on that.  (And
also, as Julian mentioned, how this relates to OpenACC semantics, which I
also haven't considered in detail -- but I note you didn't adjust any
OpenACC testcases for that, so I suppose that's really conditionalized to
OpenMP only.)

> There is also a small Fortran front-end patch involved (hence CCing Tobias).
> The new gimplify processing changed behavior in handling 
> GOMP_MAP_ALWAYS_POINTER maps such that
> the libgomp.fortran/struct-elem-map-1.f90 regressed. It appeared that the 
> Fortran FE was generating
> a GOMP_MAP_ALWAYS_POINTER for array types, which didn't seem quite correct, 
> and the pre-patch behavior
> was removing this map anyways. I have a small change in 
> trans-openmp.c:gfc_trans_omp_array_section
> to not generate the map in this case, and so far no bad test results.

Makes sense to argue that one separately, with testcases, for the master
branch submission?

> (2) The second part (though kind of related to the first above) are fixes in 
> libgomp/target.c
> to not overwrite attached pointers when handling device<->host copies, mainly 
> for the "always" case.
> This behavior is also noted in the 5.0 spec, but not yet properly coded 
> before.

Likewise, if that makes sense?

> (3) The third is a set of changes to the C/C++ front-ends to extend the 
> allowed component access syntax
> in map clauses. This is actually mainly an effort to allow SPEC HPC to 
> compile, so despite in the long
> term the entire map clause syntax parsing is probably going to be revamped, 
> we're still adding this in
> for now. These changes are enabled for both OpenACC and OpenMP.

Likewise, if that makes sense?  ;-)

> Tested on x86_64-linux with nvptx offloading with no regressions.

I'm seeing a regression with
'libgomp.oacc-c-c++-common/noncontig_array-1.c' execution testing, both C
and C++, for '-O2' (but not '-O0'), and only for about half of the
invocations.  But it seems to reliable reproduce in GDB:

Thread 1 "a.out" received signal SIGSEGV, Segmentation fault.
gomp_decrement_refcount (do_remove=, do_copy=, delete_p=false, refcount_set=0x0, k=0xc4d450) at 
[...]/source-gcc/libgomp/target.c:468
468   uintptr_t orig_refcount = *refcount_ptr;
(gdb) bt
#0  gomp_decrement_refcount (do_remove=, 
do_copy=, delete_p=false, refcount_set=0x0, k=0xc4d450) at 
[...]/source-gcc/libgomp/target.c:468
#1  gomp_unmap_vars_internal (aq=0x0, aq@entry=0x8223c0, refcount_set=0x0, 
do_copyfrom=, do_copyfrom@entry=true, tgt=tgt@entry=0xc696a0) at 
[...]/source-gcc/libgomp/target.c:2065
#2  goacc_unmap_vars (tgt=tgt@entry=0xc696a0, 
do_copyfrom=do_copyfrom@entry=true, aq=aq@entry=0x0) at 
[...]/source-gcc/libgomp/target.c:2118
#3  0x77daa41c in GOACC_parallel_keyed (flags_m=flags_m@entry=-1, 
fn=fn@entry=0x400ae0 , mapnum=mapnum@entry=2, 
hostaddrs=hostaddrs@entry=0x7fffd7a0, sizes=sizes@entry=0x604500 
, kinds=kinds@entry=0x6044f0 ) at 
[...]/source-gcc/libgomp/oacc-parallel.c:639
#4  0x00400f11 in test3 () at 
source-gcc/libgomp/testsuite/libgomp.oacc-c/../libgomp.oacc-c-c++-common/noncontig_array-1.c:75
#5  0x004008f3 in main () at 
source-gcc/libgomp/testsuite/libgomp.oacc-c/../libgomp.oacc-c-c++-common/noncontig_array-1.c:101
(gdb) print refcount_ptr
$1 = (uintptr_t *) 0x1
(gdb) list 457,468
457   uintptr_t *refcount_ptr = >refcount;
458
459   if (REFCOUNT_STRUCTELEM_FIRST_P (k->refcount))
460

Re: [PATCH, OG10, OpenMP 5.0, committed] Remove array section base-pointer mapping semantics, and other front-end adjustments.

2021-05-11 Thread Julian Brown
On Tue, 11 May 2021 19:28:04 +0800
Chung-Lin Tang  wrote:

> This patch largely implements three pieces of functionality:
> 
> (1) Per discussion and clarification on the omp-lang mailing list,
> standards conforming behavior for mapping array sections should *NOT*
> also map the base-pointer, i.e for this code:
> 
> struct S { int *ptr; ... };
> struct S s;
> #pragma omp target enter data map(to: s.ptr[:100])
> 
> Currently we generate after gimplify:
> #pragma omp target enter data map(struct:s [len: 1]) map(alloc:s.ptr
> [len: 8]) \ map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0])
> 
> which is deemed incorrect. After this patch, the gimplify results are
> now adjusted to: #pragma omp target enter data map(to:*_1 [len: 400])
> map(attach:s.ptr [bias: 0]) (the attach operation is still generated,
> and if s.ptr is already mapped prior, attachment will happen)

Oh, that's not going to play nicely (eventually?) with the patch series
I just posted... we probably need to clarify what the intention is for
OpenACC, but IIUC "user expectation" (i.e. existing code) expects the
base-pointer mapping to happen.

Julian


[PATCH, OG10, OpenMP 5.0, committed] Remove array section base-pointer mapping semantics, and other front-end adjustments.

2021-05-11 Thread Chung-Lin Tang

This patch largely implements three pieces of functionality:

(1) Per discussion and clarification on the omp-lang mailing list,
standards conforming behavior for mapping array sections should *NOT* also map 
the base-pointer,
i.e for this code:

   struct S { int *ptr; ... };
   struct S s;
   #pragma omp target enter data map(to: s.ptr[:100])

Currently we generate after gimplify:
#pragma omp target enter data map(struct:s [len: 1]) map(alloc:s.ptr [len: 8]) \
  map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0])

which is deemed incorrect. After this patch, the gimplify results are now 
adjusted to:
#pragma omp target enter data map(to:*_1 [len: 400]) map(attach:s.ptr [bias: 0])
(the attach operation is still generated, and if s.ptr is already mapped prior, 
attachment will happen)

The correct way of achieving the base-pointer-also-mapped behavior would be to 
use:
#pragma omp target enter data map(to: s.ptr, s.ptr[:100])

This adjustment in behavior required a number of small adjustments here and 
there in gimplify, including
to accomodate map sequences for C++ references.

There is also a small Fortran front-end patch involved (hence CCing Tobias).
The new gimplify processing changed behavior in handling 
GOMP_MAP_ALWAYS_POINTER maps such that
the libgomp.fortran/struct-elem-map-1.f90 regressed. It appeared that the 
Fortran FE was generating
a GOMP_MAP_ALWAYS_POINTER for array types, which didn't seem quite correct, and 
the pre-patch behavior
was removing this map anyways. I have a small change in 
trans-openmp.c:gfc_trans_omp_array_section
to not generate the map in this case, and so far no bad test results.

(2) The second part (though kind of related to the first above) are fixes in 
libgomp/target.c
to not overwrite attached pointers when handling device<->host copies, mainly for the 
"always" case.
This behavior is also noted in the 5.0 spec, but not yet properly coded before.

(3) The third is a set of changes to the C/C++ front-ends to extend the allowed 
component access syntax
in map clauses. This is actually mainly an effort to allow SPEC HPC to compile, 
so despite in the long
term the entire map clause syntax parsing is probably going to be revamped, 
we're still adding this in
for now. These changes are enabled for both OpenACC and OpenMP.

Tested on x86_64-linux with nvptx offloading with no regressions. Pushed to 
devel/omp/gcc-10, will
send mainline version of patch later.

Chung-Lin

2021-05-11  Chung-Lin Tang  

gcc/c/ChangeLog:

* c-parser.c (struct omp_dim): New struct type for use inside
c_parser_omp_variable_list.
(c_parser_omp_variable_list): Allow multiple levels of array and
component accesses in array section base-pointer expression.
(c_parser_omp_clause_to): Set 'allow_deref' to true in call to
c_parser_omp_var_list_parens.
(c_parser_omp_clause_from): Likewise.
* c-typeck.c (handle_omp_array_sections_1): Extend allowed range
of base-pointer expressions involving INDIRECT/MEM/ARRAY_REF and
POINTER_PLUS_EXPR.
(c_finish_omp_clauses): Extend allowed ranged of expressions
involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR.

gcc/cp/ChangeLog:

* parser.c (struct omp_dim): New struct type for use inside
cp_parser_omp_var_list_no_open.
(cp_parser_omp_var_list_no_open): Allow multiple levels of array and
component accesses in array section base-pointer expression.
(cp_parser_omp_all_clauses): Set 'allow_deref' to true in call to
cp_parser_omp_var_list for to/from clauses.
* semantics.c (handle_omp_array_sections_1): Extend allowed range
of base-pointer expressions involving INDIRECT/MEM/ARRAY_REF and
POINTER_PLUS_EXPR.
(handle_omp_array_sections): Adjust pointer map generation of
references.
(finish_omp_clauses): Extend allowed ranged of expressions
involving INDIRECT/MEM/ARRAY_REF and POINTER_PLUS_EXPR.

gcc/fortran/ChangeLog:

* trans-openmp.c (gfc_trans_omp_array_section): Do not generate
GOMP_MAP_ALWAYS_POINTER map for main array maps of ARRAY_TYPE type.


gcc/ChangeLog:

* gimplify.c (extract_base_bit_offset): Add 'tree *offsetp' parameter,
accomodate case where 'offset' return of get_inner_reference is
non-NULL.
(is_or_contains_p): Further robustify conditions.
(omp_target_reorder_clauses): In alloc/to/from sorting phase, also
move following GOMP_MAP_ALWAYS_POINTER maps along.  Add new sorting
phase where we make sure pointers with an attach/detach map are ordered
correctly.
(gimplify_scan_omp_clauses): Add modifications to avoid creating
GOMP_MAP_STRUCT and associated alloc map for attach/detach maps.

gcc/testsuite/ChangeLog:

* c-c++-common/goacc/deep-copy-arrayofstruct.c: Adjust testcase.
* c-c++-common/gomp/target-enter-data-1.c: