
\section{HPF extensions}

\subsection{FORALL assignments}

     Together, the features of Fortran 90 described so far provide
quite a powerful framework for implementing data parallel algorithms,
as the examples in section \ref{examples} will illustrate.

     High Performance Fortran extends the set of parallel statements in
one way---it includes a \verb$FORALL$ construct.  \verb$FORALL$ has
some similarities to the conventional \verb$DO$ loop; in some other
respects it resembles the Fortran 90 \verb$WHERE$ construct.
\begin{verbatim}
  FORALL (I = 0 : 9)
    X (I)  = X (IEOR (1, I))
  ENDFORALL
\end{verbatim}
is one way of achieving the exchange of adjacent odd and even
elements\footnote{\verb$IEOR$
is ``bitwise exclusive or''---combining a number with 1 using this
function inverts the least significant bit: \verb$IEOR (1, 0) = 1$,
\verb$IEOR (1, 1) = 0$, \verb$IEOR (1, 2) = 3$, \verb$IEOR (1, 3) = 2$,
etc.},
which we failed to effect straightforwardly with a \verb$WHERE$
construct at the end of section \ref{assignment}.
When a \verb$FORALL$ contains a single assignment, as here, all
expressions on the right-hand sides are evaluated before any element on
the left-hand side is assigned.  In this respect a single-assignment
\verb$FORALL$ is akin to a simple array assignment, rather than the
\verb$DO$ loop it superficially resembles.

     The body of a
\verb$FORALL$ may contain several statements, but these are essentially
restricted to assignments or nested \verb$FORALL$ constructs,
and as for a \verb$WHERE$
construct the meaning is as if there were several consecutive \verb$FORALL$s,
each containing a single statement.  Something like
\begin{verbatim}
  FORALL (I = 0 : 9 : 2)
    X (I)     = X (I + 1)
    X (I + 1) = X (I)
  ENDFORALL 
\end{verbatim}
(note the option of a stride in the \verb$FORALL$ index range) is
defined to be equivalent to
\begin{verbatim}
  FORALL (I = 0 : 9 : 2)
    X (I)     = X (I + 1)
  ENDFORALL 
  FORALL (I = 0 : 9 : 2)
    X (I + 1) = X (I)
  ENDFORALL 
\end{verbatim}
so it has a different effect from the first example in this subsection,
and the same effect as the earlier \verb$WHERE$/\verb$ELSEWHERE$
example.

     A single \verb$FORALL$ can define several indices.  So
\begin{verbatim}
  FORALL (I = 1 : SIZE (A, 1), J = 1 : SIZE (B, 2))
    MATPROD (I, J) = DOT_PRODUCT (A (I, :), B (:, J))
  ENDFORALL
\end{verbatim}
is a completely parallel version of the body of \verb$MATPROD$,
introduced in section \ref{array-args}.

\subsection{\label{pure}Pure procedures}

     The order of execution of the individual assignments in a
\verb$FORALL$ statement is undefined---ideally they all execute in
parallel.  Suppose arbitrary expressions could appear inside the body
of a \verb$FORALL$.  Then in particular calls to arbitrary user-defined
functions could appear.  A user-defined function may have a
variety of {\em side-effects}.  It might, for example, modify a
variable in a common block, or perform some read or write operation.

     Whenever side-effects like this can occur, it's preferable that
they should happen in a well-defined order, otherwise the net behaviour
of the program may be non-deterministic (to belabour the point, if one
statement modifies a variable which another reads, the overall
behaviour of the program depends on the order in which those statements
were executed).  Some parallel languages accept the possibility of
non-deterministic programs.  Fortran isn't one of them.

     Rather than completely forbid reference to user-defined functions
inside \verb$FORALL$ constructs, a special class of side-effect
free functions has been defined, which can safely be called in
parallel.  A {\em pure} procedure (function or subroutine) is defined
with the word \verb$PURE$ at the front of its header line:
\begin{verbatim}
  PURE FUNCTION PYTHAG (X, Y)
  REAL, INTENT (IN) :: X, Y
  REAL PYTHAG
    PYTHAG = SQRT (X**2 + Y**2)
  ENDFUNCTION
\end{verbatim}
and is then forbidden from modifying global data, or performing any IO
operation, or calling any non-pure procedure\footnote{Aside 1: In Fortran 90 it
is possible to specify the {\em intent} of a dummy argument.  If an
argument has the \verb$INTENT (IN)$ attribute, the programmer guarantees
not to change the value of the argument in the body of the procedure.
Rather pedantically, HPF insists that \verb$PURE$ functions have this
attribute explicitly specified for all dummy arguments.

Aside 2: The double colon form of declaration can be used to specify
more than one attribute---always including the type as the first---in a
single declaration.  In general a comma-separated list of attributes is
separated from the list of variables by \verb$::$}.

     A function like \verb$PYTHAG$ may now appear in the body
of a \verb$FORALL$
\begin{verbatim}
  FORALL (I = 1 : 10)
    HYPOT (I) = PYTHAG (HORIZ (I), VERT (I))
  ENDFORALL
\end{verbatim}

(It would be pleasant if \verb$PYTHAG$ could also be applied ``elementally''
to arrays, as in
\begin{verbatim}
  HYPOT (1 : 10) = PYTHAG (HORIZ (1 : 10), VERT (1 : 10))
\end{verbatim}
which would achieve the same effect as the \verb$FORALL$.  This
possibility has been omitted from the HPF language definition,
purely to minimise points of departure of HPF from the existing Fortran
90 standard.)

