Subset Co-Array Fortran has been designed to be implementable by mapping co-arrays onto arrays of higher rank. In particular, they are implementable as shared OpenMP Fortran arrays.
Any saved or module variables must be placed in THREADPRIVATE named common. Any named common that does not contain co-arrays must be made THREADPRIVATE. All co-arrays must be placed in named common, so that they are shared objects. Square brackets are merged to create arrays of higher rank. The convention that references to a co-array without square brackets is a reference to the local part of the co-array requires first expanding the reference to include both round brackets and square brackets, and then merging square brackets to create an array sub-object. References without square brackets to co-arrays in procedure calls are unambiguous because the interface must be explicit when the dummy argument is a co-array. If the dummy argument is not a co-array, the reference must be expanded to explicitly pass the local part of the co-array to the procedure. If the dummy argument is an assumed-shape co-array (with co-rank one), the dummy is translated to an assumed-shape array with one higher rank and special handling may also be required on the calling side.
Co-Array intrinsic procedures can be implemented as an OpenMP module. A reference implementation is available. All caf-procedure calls must be bracketed by a FLUSH directive that explicitly names all actual co-arrays in the local scope. A generic FLUSH without arguments would also be sufficient, but is less efficient because OpenMP would then flush objects that the original Co-Array source has identified as not being thread visible. All of Co-Array I/O maps directly onto thread-safe OpenMP I/O, so the translator may have to explicitly make I/O thread safe, using critical directives, but the mapping is otherwise straightforward.
As a "proof of concept'' a nawk script has been developed to translate Subset Co-Array Fortran directly into OpenMP Fortran. Since this is a pattern matching script, rather than a compiler, it treats some keywords as reserved and requires some statements be expressed in one of the several alternatives that Fortran provides. In order to implement TEAM read, I/O unit numbers are restricted to be less than 100,000. The only other significant variances from the Subset Co-Array Fortran language are those made necessary by the translator's lack of a symbol table identifying modules and co-arrays by name. The most serious of these is that the local part of a co-array cannot be referenced without square brackets. To simplify local parts, the script will automatically translate a copy of the co-array's declaration square brackets, with "*" replaced by "@", into square brackets identifying the local part. For example:
COMMON/XCTILB4/ B(N,4)[0:MP-1,0:*] SAVE /XCTILB4/ CALL SYNC_ALL( WAIT=(/IMG_S,IMG_N/) ) B(:,3)[0:MP-1,0:@] = B(:,1)[I_IMG_S,J_IMG_S] B(:,4)[0:MP-1,0:@] = B(:,2)[I_IMG_S,J_IMG_N] CALL SYNC_ALL( WAIT=(/IMG_S,IMG_N/) )Only the local part of B(:,3) and B(:,4) is used, but square brackets are still required and have been provided by replicating the square bracket declaration of B with "*" replaced by "@". The advantage of this extension to the language is that these square brackets can be removed by a batch stream editor to produce a legal Subset program. Absent a symbol table for explicit interfaces, passing co-arrays to subroutines also requires extensions to the Subset language. A whole co-array can be passed to a co-array dummy just as in the Subset, but all other cases rely on an extension to the Subset to allow co-array sections to be passed as arguments. A co-array section passed to a co-array dummy must include square brackets that cover the entire co-extent. A local part passed to a dummy of co-rank zero must use square brackets, perhaps via the "@" extension, to form the corresponding co-array section.
A more complete list of caf2omp's limitations is available here.
The nawk script obviously provides a way of running Co-Array Fortran programs (after some manual tweaking) via an OpenMP compiler. But it can also be simply viewed as a pre-processor that provides an improved SPMD interface for OpenMP. It has several major advantages over native OpenMP Fortran for SPMD programs. For example, I/O is consistent with process-based SPMD programming models and the mapping of variables onto shared and private memory is greatly enhanced (because the script automatically places variables in COMMON as necessary). Co-Array Fortran intrinsic procedures provide a much richer set of synchronization options than OpenMP, and the special handling of caf-procedures ensures that synchronization of threads implies synchronization of co-arrays. A disadvantage of the nawk script is that it provides no error checking. Legal Co-Array Fortran programs are translated to legal OpenMP Fortran programs, but illegal programs will also be translated and it is up to the OpenMP compiler to detect the error. Error messages are likely to be obscure, but relatively few lines are modified in the translation so inspection of the OpenMP source should provide an indication of the error. A true Subset Co-Array compiler, either provided as an addition to an OpenMP compiler or as a stand-alone source to source compiler, would not have any of the restrictions of the nawk script and would be able to provide clear and relevant error diagnostics for non-conforming syntax.
The nawk script and several non-trivial Co-Array Fortran programs that it successfully translates into OpenMP Fortran are included with the reference implementation of Co-Array intrinsics for OpenMP.