Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 3/22/2024
Public
Document Table of Contents

PARALLEL and NOPARALLEL General Directives

General Compiler Directives: PARALLEL facilitates auto-parallelization by assisting the compiler's dependence analysis of the immediately following DO loop. NOPARALLEL prevents this auto-parallelization. This feature is only available for ifort.

Syntax

!DIR$ PARALLEL [clause[[,] clause] ... ]

!DIR$ NOPARALLEL

clause

Is one or more of the following:

  • ALWAYS [ASSERT]

  • FIRSTPRIVATE (list)

    Provides a superset of the functionality provided by the PRIVATE clause. Variables that appear in a FIRSTPRIVATE list are subject to PRIVATE clause semantics. In addition, private (local) copies of each variable in the different iterations are initialized to the value the variable had upon entering the parallel loop.

  • LASTPRIVATE (list)

    Provides a superset of the functionality provided by the PRIVATE clause. Variables that appear in a LASTPRIVATE list are subject to PRIVATE clause semantics. In addition, once the parallel loop is exited, each variable has the value that resulted from the sequentially last iteration of the parallel loop.

  • NUM_THREADS (scalar_integer_expression)

    Specifies the number of threads to be used to parallelize the immediately following DO loop. The scalar_integer_expression must evaluate to a positive scalar integer value. Only a single NUM_THREADS clause can appear in the directive. Once specified, the number of threads used remains constant for the duration of that parallelized DO loop.

  • PRIVATE (list)

    Declares specified variables to be private to each thread in a team. The declared variables become private to a task.

list

Is one or more items in the form: var [:expr]…. Each list item must be separated by a comma.

var

Is a scalar or array variable. The following rules apply:

  • Assumed-size arrays cannot appear in a PRIVATE clause.

  • A variable that is part of another variable (for example, as an array or structure element) cannot appear in a PRIVATE clause.

  • A variable that appears in a PRIVATE clause must either be definable, or an allocatable array. This restriction does not apply to the FIRSTPRIVATE clause.

  • Variables that appear in namelist statements, in variable format expressions, and in expressions for statement function definitions, cannot appear in a PRIVATE clause.

expr

Is an integer expression denoting the number of array elements to privatize. When expr is specified, var must be an array or a pointer variable. The following rules also apply:

  • If var is an array, then only its first expr elements are privatized. If expr is omitted, the entire array is privatized.

  • If var is a pointer, then the first expr elements are privatized (element size is provided by the pointer's target type). If expr is omitted, only the pointer variable itself is privatized.

  • Program behavior is undefined if expr evaluates to a non-positive value, or if it exceeds the array size.

PARALLEL helps the compiler to resolve dependencies, facilitating auto-parallelization of the immediately following DO loop. It instructs the compiler to ignore dependencies that it assumes may exist and which would prevent correct parallelization in the loop. However, if dependencies are proven, they are not ignored.

In addition, PARALLEL ALWAYS overrides the compiler heuristics that estimate the likelihood that parallelization of a loop will increase performance. It allows a loop to be parallelized even if the compiler thinks parallelization may not improve performance. If the ASSERT keyword is added, the compiler will generate an error-level assertion message saying that the compiler analysis and cost model indicate that the loop cannot be parallelized.

NOPARALLEL prevents auto-parallelization of the immediately following DO loop.

These directives take effect only if you specify the compiler option that enables auto-parallelization.

CAUTION:

The directive PARALLEL ALWAYS should be used with care. Overriding the heuristics of the compiler should only be done if you are absolutely sure the parallelization will improve performance.

Example

program main
parameter (n=100)
integer x(n), a(n), k
!DIR$ NOPARALLEL
   do i=1,n
     x(i) = i
   enddo
!DIR$ PARALLEL LASTPRIVATE (k)
   do i=1,n
     a( x(i) ) = i
     k = x(i)
   enddo
   print *, k     ! print 100, the value of x(n)
end