Permit more valid code by removing a too tight constraint – simple
patch, very long background & history (feel free to skip).
Arrays in Fortran are classified as:
* assumed-size: "… :: var(*)" – and array but only the caller knows the
size, which usually gets passed as some additional argument ("N") in the
function all. – But at least contiguous. Typical for FORTRAN 66 code.
* assumed-rank: "… :: var(..)" – array can be any rank (dimension);
provides full descriptor but the rank is not know at compile time, may
or may not contigous/allocatable/pointer. Introduced mainly for MPI to
avoid creating 16 versions of an interface (scalar to rank-15 arrays) –
but has many uses; requires 'select rank' to be consumable within
Fortran. — New with Fortran 2018 (or rather the TS29113, i.e. between
F2013 and F2018).
* assumed shape: "… :: var(:, :)" – nonallocatable, nonpointer. Uses an
array descriptor, can be contiguous or not (Always contiguous with
Fortran 2008's 'contiguous' attribute)
*deferred shape: "var(:, :, :)" with allocatable/pointer attribute.
'allocatable' implies contiguous by construction.
(* plus explicit-shape arrays like "… :: var(N,M)" and with constant
initialization: implied-shape arrays.)
openmp.c's "check_array_not_assumed" shows an error for:
* assumed-size arrays (makes totally sense)
* assumed-rank arrays (makes sense as long as TS29113/F2018 is not
supported)
* pointers which do not have the "contiguous" attribute
Not only function name wise, the latter is the odd one out. While in
many cases a contiguous memory is required, one can either make it a
compile-time testable constraint ('simply contiguous') – or one puts the
onus is on the programmer; the latter seems to be done in the
OpenACC/OpenMP specs.
(Of cause, it is also run-time checkable and gfortran uses a run-time
test when passing a potentially noncontiguous array to a dummy argument
with "contiguous" attribute; if the actual argument is contiguous, it is
passed as is - otherwise, a copy-in and copy-out is performed [for
intent(inout)].)
Currently, OpenACC 2.7 has:
* Based on Fortran 2003 – i.e. no 'contiguous attribute'.
* "2.7.1. Data Specification in Data Clauses": "Any array or subarray in
a data clause, including Fortran array pointers, must be a contiguous
block of memory, except for dynamic multidimensional C arrays."
* "2.14.4. Update Directive": "Noncontiguous subarrays may be specified.
It is implementation-specific whether noncontiguous regions are updated
by using one transfer for each contiguous subregion, or whether the
noncontiguous data is packed, transferred once, and unpacked, or whether
one or more larger subarrays (no larger than the smallest contiguous
region that contains the specified subarray) are updated."
Oddly enough, OpenACC 2.7 only refers to "Fortran 2003" (in 1.6) but
uses a TS29113/F2018 feature in "3.2.20. acc_copy_in": assumed-rank arrays.
OpenMP – OpenMP 4.0 and 4.5 are based on Fortran 2003 (hence: no
'contiguous' attribute), OpenMP 5.0 is based on Fortran 2008. Hence, it
explicitly uses the contiguous attribute. It also introduces 'simply
contiguous array section' which largely matches Fortran's simply
contiguous.Several contiguous restrictions were lifted with OpenMP 5.0;
one of the few remaining ones is:
* [OpenMP 5's map clause] "If a list item is an array section, it must
specify contiguous storage"
But this also does not require (simply) contiguous, i.e. compile-time
checking.
The current check is used by OpenACC in
* resolve_oacc_data_clauses
* resolve_oacc_deviceptr_clause
* resolve_omp_clauses for OpenACC loops/EXEC_OACC_PARALLEL
And by OpenMP in
* resolve_omp_clauses for OMP_LIST_USE_DEVICE/OMP_LIST_DEVICE_RESIDENT
Some more archeology (thanks Thomas!):
* PR fortran/65438 (of 2015-03-16) - requires to remove this check,
without providing any reasoning
* https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg145081.html
(of 2016-08-09) was an attempt to add a warning – which was rejected on
a similar ground then listed above: The 'contiguous' attribute (or
simply contiguous property) is not explicitly ask for in the spec – and
as OpenACC only supports Fortran < 2008, enforcing a Fortran 2008
feature does not make sense.
HENCE: Remove a compile-time check when both specs (OpenMP/OpenACC) put
the onus on the programmer. As compile-time checks are only a subset, we
reject valid contiguous memory which is just not simply contiguous.
Additionally, the check only works if only an identifier is permitted as
argument (it checks the symbol). For derived-type components, the check
is not effective. (Assumed rank and assumed size are properties of dummy
arguments, hence, those work fine.)
OK for the trunk?
Cheers,
Tobias
PS: This patch comes from the OG9 branch as
ac6c90812344f4f4cfe4d2f5901c1a9d038a4000 but was actually already in the
OG8 branch with commit d50862a7522446cf101eac9dc2e32967dc8318b7 from
2015 (!) – I have used the ChangeLog entry from the latter.
2015-05-11 James Norris <jnor...@codesourcery.com>
PR fortran/65438
* openmp.c (check_array_not_assumed): Remove pointer check.
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index cd28384589c..5c91fcdfd31 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -3861,10 +3861,6 @@ check_array_not_assumed (gfc_symbol *sym, locus loc, const char *name)
if (sym->as && sym->as->type == AS_ASSUMED_RANK)
gfc_error ("Assumed rank array %qs in %s clause at %L",
sym->name, name, &loc);
- if (sym->as && sym->as->type == AS_DEFERRED && sym->attr.pointer
- && !sym->attr.contiguous)
- gfc_error ("Noncontiguous deferred shape array %qs in %s clause at %L",
- sym->name, name, &loc);
}
static void