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

Reply via email to