Intel® Fortran Compiler 17.0 Developer Guide and Reference

CRITICAL Statement

Statement: Marks the beginning of a CRITICAL construct. A CRITICAL construct limits execution of a block to one image at a time.

[name:] CRITICAL

   block

END CRITICAL [name]

name

(Optional) Is the name of the CRITICAL construct.

block

Is a sequence of zero or more statements or constructs.

Description

If a construct name is specified in a CRITICAL statement, the same name must appear in the corresponding END CRITICAL statement. If no name is specified at the beginning of a CRITICAL statement, you cannot specify one following the END CRITICAL statement. The same construct name must not be used for different named constructs in the same scoping unit.

The block of a CRITICAL construct must not contain a RETURN statement or an image control statement.

A branch within a CRITICAL construct must not have a branch target that is outside the construct.

Execution of the CRITICAL construct is completed when execution of its block is completed. A procedure that is invoked, directly or indirectly, from a CRITICAL construct must not execute an image control statement.

The processor ensures that once an image has commenced executing block, no other image can start executing block until this image has completed executing block. The image must not execute an image control statement during the execution of block. The sequence of executed statements is therefore a segment. If image S is the next to execute the construct after image N, the segment on image N precedes the segment on image S.

If more than one image executes the block of a CRITICAL construct, its execution by one image always precedes or succeeds its execution by another image. Normally no other statement ordering is needed.

Example

Consider the following example:

CONA: CRITICAL
  MY_COUNTER[1] = MY_COUNTER[1] + 1
END CRITICAL CONA

The definition of MY_COUNTER [1] by a particular image will always precede the reference to the same variable by the next image to execute the block.

The following example shows a way to share a large number of tasks among images:

INTEGER :: NUMBER_TASKS[*], TASK
IF (THIS_IMAGE() == 1) READ(*,*) NUMBER_TASKS
SYNC ALL
DO
   CRITICAL
      TASK = NUMBER_TASKS[1]
      NUMBER_TASKS[1] = TASK - 1
   END CRITICAL
IF (TASK > 0) THEN
ELSE
   EXIT
END IF
END DO
SYNC ALL

See Also