https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77371

Tobias Burnus <burnus at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |burnus at gcc dot gnu.org

--- Comment #11 from Tobias Burnus <burnus at gcc dot gnu.org> ---
(In reply to Gerhard Steinmetz from comment #0)
> Some snippets with allocatable scalars (valid code) combined with
> OpenACC. Similar issue for "pointer" instead of "allocatable".
> 
> $ cat z1.f90
> program p
>    character(:), allocatable :: z
>    !$acc parallel
>    z = 'abc'
>    !$acc end parallel
>    print *, z
> end

ZERO-TH ISSUE (OpenACC and OpenMP): I think with 'pointer', there are
additional issues:
– A pointer can be undefined (garbage address) besides not associated (NULL)
and associated.
– Depending on implicit vs. explicit mapping, OpenMP vs. OpenACC and the spec
version, the pointer target may or may not be mapped
– Changing the pointer address on the device is not permitted [except
intermittently] (OpenACC: "Data Structures with Pointers"; OpenMP 5.0, "map
clause", p. 317, ll. 22-25)



FIRST ISSUE (OpenACC only): 'firstprivate' of 'z'

Pre-remark:
* GCC -fopenacc: For "len=3" and "len=n" strings (dummy arg or stack alloc),
OpenACC uses in the dump "map(tofrom:str [len: 3])" etc.
* GCC -fopenmp uses map(tofrom: for all variants, including the test case
above. 


GCC 10 dump shows:
  #pragma omp target oacc_parallel firstprivate(z) firstprivate(.z)

The firstprivate is odd; I think it should also an implicit 'copy(z)' [alias
"map(tofrom:" as shown in the dump].

I think (cf. second issue) firstprivate(.z) is fine as modifying the pointer
target is not permitted in OpenACC (cf. "Data Structures with Pointers"). 


In any case, the OpenACC spec is also bad. (I have filled OpenACC Issue 254 for
this.) It has:

"an array or composite variable referenced in the parallel construct that does
not appear in a data clause for the construct or any enclosing data construct
will be treated as if it appeared in a copy clause for the parallel construct"
[…]
"A scalar variable referenced in the parallel construct that does not appear in
a data clause for the construct or any enclosing data construct will be treated
as if it appeared in a firstprivate clause"

Here, "z" is clearly not a scalar (see OpenACC Glossary) as it is of character
type. It is an aggregated variable (which encompasses nonscalar types). –
However, it is neither an array (Fortran sense as not in the glossary) nor a
composite type (as defined in the glossary); in particular, it is not a
'composite variable' as the latter requires nonallocatable/nonpointer
variables.

Side note: pointers will have additional issues, thus a spec fix probably
should distinguish between pointers and allocatables. In any case, current spec
already has problems without allocatable/pointer.

 * * *

SECOND ISSUE: 'firstprivate' of DECL_ARTIFICIAL string-length variable

OpenACC *and* OpenMP: occurs with implicit mapping in OpenMP – and with an
explicit  "copy(z)" / "map(tofrom:"

The dump shows:

  map(tofrom:*z [len: SAVE_EXPR <.z.5>]) map(alloc:z [pointer assign, bias: 0])
  firstprivate(.z)

Here ".z" is an artificial variable generated by the compiler and storing the
string length of the variable. 

That mapping is fine unless one does (re)allocations within the target/parallel
region – in particular, those which modify the string-length and, hence, the
artificial variable.


I am not sure whether (re)allocating within an omp target/acc parallel/acc
kernels section is permitted.  [If one has unified-shared memory, it will work,
except for the firstprivate(.z).]


*In OpenMP 5.0,* I find the restriction (2.12.5 target Construct):
"An attached pointer that is associated with a given pointer target must not
become associated with a different pointer target in a target region."

Which implies that re-allocation is permitted for 'allocatable' (as in the test
case, assuming 'omp target' instead of 'acc parallel').


In OpenACC 2.7 + 3.0, "Data Structures with Pointers", I only find:

"When the device pointer target is deallocated, the pointer in device memory
should be restored to the host value, so it can be safely copied back to host
memory"

This does not talk about re-allocation but could be read such that
(re)allocation on the device is not permitted.


HENCE, if I read the specs correctly, there are the following bugs:
* OpenACC in GCC:  should use "copy(z)" for the test case
* OpenACC as spec: needs to be fixed/clarified
* OpenMP in GCC:   assuming (re)allocation of 'allocatables' is permitted,
firstprivate(.z) should be a 'map(tofrom:'.

Reply via email to