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:'.