Next: Visualization of INDEPENDENT Directives
Up: INDEPENDENT and Related Directives
Previous: INDEPENDENT and Related Directives
The INDEPENDENT directive can precede an indexed DO
loop or FORALL statement. It asserts to the compiler that
the iterations in the following DO loop or the operations in
the following FORALL may be executed independently--that is,
in any order, or interleaved, or concurrently--without changing the
semantics of the program.
The INDEPENDENT directive precedes the DO loop or
FORALL for which it asserts behavior, and is said to
apply to that loop or FORALL. The syntax of the
INDEPENDENT directive is
H501 independent-directive | is INDEPENDENT [ , new-clause ]
[ , reduction-clause ] |
H502 new-clause | is NEW ( variable-name-list ) |
H503 reduction-clause | is REDUCTION ( reduction-variable-list ) |
H504 reduction-variable | is array-variable-name
or scalar-variable-name
or structure-component |
- The first non-comment line following an
independent-directive must be a do-stmt,
forall-stmt, or a forall-construct.
- If the first non-comment line following an
independent-directive is a do-stmt, then that
statement must contain a loop-control option containing a
do-variable.
- If either the NEW clause or the REDUCTION
clause is present, then the first non-comment line following the
directive must be a do-stmt.
- A variable named in the NEW or the
REDUCTION clause and any component or element thereof must
not:
- Be a dummy argument;
- Have the SAVE or TARGET attribute;
- Occur in a COMMON block;
- Be storage associated with another object as a result of appearing in an
EQUIVALENCE statement;
- Be use associated;
- Be host associated; or
- Be accessed in another scoping unit via host association.
- A variable that occurs as a reduction-variable may not
appear in a new-clause in the same
independent-directive, nor may it appear in either a
new-clause or a reduction-clause in the range
(i.e., the lexical body) of the following do-stmt,
forall-stmt, or forall-construct to which the
independent-directive applies.
- A structure-component in a reduction-variable
may not contain a subscript-section-list.
- A variable that occurs as a reduction-var must be of
intrinsic type. It may not be of type CHARACTER.
-
- Rationale.The second constraint means that an INDEPENDENT directive
cannot be applied to a WHILE loop or a simple DO
loop (i.e., a ``do forever''). An INDEPENDENT in such
cases could only correctly describe a loop with zero or one trips; the
potential confusion was felt to outweigh the possible benefits.
(End of rationale.)
When applied to a DO loop, an INDEPENDENT directive
is an assertion by the programmer that no iteration can interfere with
any other iteration, either directly or indirectly. The following
operations define such interference:
- Any two operations that assign to the same atomic object
interfere with each other. (A data object is called atomic
if it contains no subobjects.)
- Exception: If a variable appears in a NEW clause,
then operations assigning values to it in separate iterations of
the DO loop do not interfere. The reason for
this is explained in Section 5.1.2.
- Exception: If a variable appears in a REDUCTION
clause, then assignments to it by reduction statements in the
range of the DO loop do not interfere with
assignments to it by other reduction statements in the same loop.
The reason for this is explained in Section 5.1.3.
Operations that assign to objects include:
- Assignment statements assign to their left-hand side and all
its subobjects.
- ASSIGN statements assign to their integer variables.
- ALLOCATE and DEALLOCATE statements with the
STAT= specifier assign to the STAT variable.
- DO statements assign to their indices.
- I/O statements with the IOSTAT= specifier assign to
the IOSTAT variable. They may also assign to other
objects, as described below.
- Asynchronous READ and WRITE statements (as
described in Section 10) assign to their ID=
variable.
- READ statements assign to all variables in their
input item list and any variables accessed at runtime through
their NAMELIST. READ statements with the
SIZE= specifier assign to the SIZE variable.
- INQUIRE statements assign to all variables in their
specifier list, except the UNIT and FILE
specifiers.
- Compound statements (e.g., IF statements) cause
assignments to objects if their component statements do.
- Subprogram invocations cause assignments to objects if
operations in the subprogram execution do.
- An operation that assigns to an atomic object interferes with
any operation that uses the value of that object.
- Exception: If a variable appears in a NEW clause,
then operations assigning values to it in one iteration of the
DO loop do not interfere with uses of the
variable in other iterations. The reason for this is explained in
Section 5.1.2.
- Exception: If a variable appears in a REDUCTION
clause, then assignments to it by reduction statements in the
range of the DO loop do not interfere with the
allowed uses of it by reduction statements in the same loop. The
reason for this is explained in Section 5.1.3.
Any expression that computes the value of a variable uses that
object. This includes uses on the right-hand side of assignment
statements, uses in subscripts on the left-hand side of assignment
statements, conditional expressions, specification lists for I/O
statements, output lists for WRITE statements, allocation
shape specifications in ALLOCATE statements, and similar
situations.
-
- Rationale.These are the classic Bernstein conditions to enable parallel
execution. Note that two assignments of the same value
to a variable interfere with each other and thus an
INDEPENDENT loop with such assignments is not
HPF-conforming. This is not allowed because such overlapping
assignments are difficult to support on some hardware, and because
the given definition was felt to be conceptually clearer.
Similarly, it is not HPF-conforming to assert that assignment of
multiple values to the same location is INDEPENDENT, even
if the program logically can accept any of the possible values.
In this case, both the ``conceptually clearer'' argument and the
desire to avoid indeterminate behavior favored the given solution.
(End of rationale.)
- An ALLOCATE statement, DEALLOCATE statement,
NULLIFY statement or pointer assignment statement
interferes with any other access, pointer assignment, allocation,
deallocation, or nullification of the same pointer. In addition, an
ALLOCATE or DEALLOCATE statement interferes with
any other use of or assignment to the object that is allocated by
ALLOCATE or deallocated by DEALLOCATE.
-
- Rationale.These constraints extend Bernstein's conditions to pointers.
Because a Fortran pointer is an alias to an object or subobject
rather than a first-class data type, a bit more care is needed
than for other variables.
(End of rationale.)
- Any transfer of control to a branch target statement outside the
body of the loop interferes with all other operations in the loop.
- Any execution of an EXIT, STOP, or
PAUSE statement interferes with all other operations in the
loop.
-
- Rationale.Branching (by GOTO or ERR= branches in I/O
statements) implies that some iterations of the loop are not
executed, which is drastic interference with those computations.
The same is true for EXIT and the other statements.
Note that these conditions do not restrict procedure calls in
INDEPENDENT loops, except to disallow taking alternate
returns to statements outside the loop, executing a STOP,
or executing a PAUSE.
(End of rationale.)
- Any two file I/O operations except INQUIRE associated
with the same file or unit interfere with each other. Two
INQUIRE operations do not interfere with each other;
however, an INQUIRE operation interferes with any other I/O
operation associated with the same file.
-
- Rationale.Because Fortran carefully defines the file position after a data
transfer or file positioning statement, these operations affect
the global state of a program. (Note that file position is
defined even for direct access files.) Multiple non-advancing
data transfer statements affect the file position in ways similar
to multiple assignments of the same value to a variable, and is
disallowed for the same reason. Multiple OPEN and
CLOSE operations affect the status of files and units,
which is another global side effect. INQUIRE does not
affect the file status, and therefore does not affect other
inquiries. However, other file operations may affect the
properties reported by INQUIRE.
(End of rationale.)
- Any data realignment or redistribution performed by subprogram
invocation (see Section 4) interferes with any
access to or any other remapping of the same data.
-
- Rationale.Remapping may change the processor storing a particular array
element, which interferes with any assignment or use of that
element. This applies even though the remappings are ``undone''
when the call returns. During the execution of the call, the
homes of the array elements have changed, thus interfering with
accesses in the caller, accesses in other invocations of the same
procedure, and remappings of the array due to another procedure
call.
(End of rationale.)
-
- Advice to users.Data remapping performed by the REALIGN and
REDISTRIBUTE aproved extensions also causes interference
under this rule. See Chapter 8.5 for
details.
(End of advice to users.)
The interpretation of INDEPENDENT for FORALL is
similar to that for DO: it asserts that no combination of the
FORALL indices assigns to an atomic storage unit that is read
by another combination. A DO and a FORALL with the
same body are equivalent if they both have the INDEPENDENT
directive.
This is illustrated in Section 5.1.1.
If a procedure is called from within an INDEPENDENT loop or
FORALL, then any local variables in that procedure are
considered distinct on each call unless they have the SAVE
attribute. This is consistent with the Fortran standard. Therefore,
uses of local variables without the SAVE attribute in calls
from different iterations do not cause interference as defined above.
-
- Advice
to implementors.A conforming Fortran implementation can often avoid creating
distinct storage for locals on every call. The same is true for an
HPF implementation; however, such an implementation must still
interpret INDEPENDENT in the same way. If locals are not
allocated unique storage locations on every call, then the
INDEPENDENT loop must be serialized to respect these
semantics (or other techniques must be used to avoid conflicting
accesses).
(End of advice to implementors.)
Note that all these rules describe interfering behavior; they do not
disallow specific syntax. Statements that appear to violate one or
more of these restrictions are allowed in an INDEPENDENT
loop, if they are not executed due to control flow. These
restrictions allow an INDEPENDENT loop to be executed safely
in parallel if computational resources are available. The directive
is purely advisory and a compiler is free to ignore it if it cannot
make use of the information.
-
- Advice
to implementors.Although the restrictions allow safe parallel implementation of
INDEPENDENT loops, they do not imply that this will be
profitable (or even possible) on all architectures or all programs.
For example,
In all cases, it is the implementation's responsibility to produce
correct behavior, which may in turn limit optimization. It is
recommended that implementations provide some feedback if an
INDEPENDENT assertion may be ignored.
(End of advice to implementors.)
Next: Visualization of INDEPENDENT Directives
Up: INDEPENDENT and Related Directives
Previous: INDEPENDENT and Related Directives