(j3.2006) [ukfortran] (SC22WG5.5025) Canada's national body report to WG 9 (Ada)

Van Snyder Van.Snyder
Tue Jul 9 20:12:11 EDT 2013

On Tue, 2013-07-09 at 07:57 -0500, Bill Long wrote:
> On 7/9/13 3:38 AM, N.M. Maclaren wrote:
> > I believe that it would be straightforward to add a tasking facility to
> > Fortran, if restricted to PURE procedures, and feasible if not.  Defining
> > asynchronous procedures would not be trivial, of course.  However, I
> > cannot see how to fit it in with coarrays.
> We already have one form of tasking - asynchronous I/O.  That was 
> extended to cover asynchronous "communication" with the TS, with the 
> non-blocking MPI routines as the obvious targets.  Vendors have 
> supported automatic parallelization options for years. (We even used to 
> call it 'autotasking'.)  Compilers are free to defer execution of PURE 
> procedures as long as there are no data conflicts.  Indeed, most of the 
> coarray transfers are, at least theoretically, asynchronous within 
> bounds of the segment and local ordering requirements.  The key is that 
> all of this "tasking" is of the local, SMP, threaded form.  That makes 
> it orthogonal to the distributed-memory coarray parallelism.  Indeed, 
> OpenMP supports all of this type of local parallelism, and coexists 
> happily with coarrays in the same code (even though the OpenMP committee 
> is vastly tardy in writing the specs).   I guess the obvious push-back 
> on a TASK concept for Fortran is that OpenMP already explicitly supports 
> the same concept.

Ada has had tasking, and not limited to the local SMP threaded form,
since 1983.  Another device, called a "protected object," was added in
Ada 95.  I remember these being very well described in "Concurrent and
Real-Time Programming in Ada" by Alan Burns and Andy Wellings.  The
Ravenscar Profile defined a subset oriented toward more efficiency for
high-integrity applications.

I have proposed at least three asynchronous computation and data
transfer mechanisms:

1. Asynchronous unformatted internal-file I/O.

2. An asynchronous construct of the form

  <construct-label>: <asynchronous-construct-stmt>
    [ <specification-part> ]
  <end-asynchronous-construct-stmt> <construct-label>
  WAIT ( <construct-label> )

(see 97-114r2).  An alternative to waiting using the construct label is
to name an object of EVENT type in the <asynchronous-construct-stmt> and
wait for it using an EVENT WAIT statement.  An obvious extension of the
latter is that if a list or array of events appears in the WAIT, the
statement waits for all of them.

3. A fork-join construct of the form

<parallel-construct> <<is>> PARALLEL
                              [ <fork> ] ...
                            END PARALLEL

<fork> <<is>> FORK [ IF ( <logical-expr) ]
                [ <specification-part> ]

Upon executing a PARALLEL statement the processor may divide the
sequence of execution into a number of sequences not exceeding the
number of FORK blocks. Each of these sequences begins execution at the
start of a different FORK block; after finishing execution of one FORK
block a sequence may continue into a different one, or may continue by
executing the END PARALLEL statement. In any case, each FORK block that
does not have IF ( <logical-expr> ) or for which logical-expr is true is
executed exactly once, and ones that have IF ( <logical-expr> ) and for
which <logical-expr> is false are not executed. After all of the
required FORK blocks are executed, all sequences of execution that were
created by execution of the PARALLEL statement are condensed into a
single sequence, and execution proceeds at the first statement after the
END PARALLEL statement. Notice that this definition permits the
processor to rearrange the forks into an arbitrary order, replace FORK
statements that have IF ( <logical-expr> ) with IF constructs, and then
ignore the PARALLEL, FORK, and END PARALLEL statements.

Bill has suggested that this is syntactic sugar for

  DO CONCURRENT ( I = 1:3 )
  CASE ( 1 )
      [ <specification-part> ]
  CASE ( 2 )
      [ <specification-part> ]
  CASE ( 3 )
      [ <specification-part> ]

perhaps with embedded IF constructs, but there is an important
difference:  A task/thread/activity is not created if "IF
( <logical-expr> )" appears and the <logical-expr> is false.

(see 00-317 and 06-187).

In either case, a variable that is not declared within a
<specification-part> within the construct should not be allowed in a
variable definition context, except within a CRITICAL construct, which
needs to be extended beyond images to sequences of execution. Similarly,
an impure procedure can only be invoked from within a CRITICAL
construct. An alternative is a new PARALLEL attribute for procedures,
which indicates that any alteration to a nonlocal variable or dummy
argument occurs within a CRITICAL construct.

More information about the J3 mailing list