OpenMP directive clauses

The following OpenMP directive clauses allow you to specify the scope attributes of variables within a parallel construct. The IF, NUM_THREADS, ORDERED, and SCHEDULE clauses, also in this section, allow you to control the parallel environment of a parallel region. See the detailed directive descriptions for more information.

Global rules for directive clauses

You must not specify a variable or common block name more than once in a clause.

A variable, common block name, or variable name that is a member of a common block must not appear in more than one clause on the same directive, with the following exceptions:

If you do not specify a clause that changes the scope of a variable, the default scope for variables affected by a directive is SHARED.

A local variable with the SAVE or STATIC attribute declared in a procedure referenced within the dynamic extent of a parallel region has an implicit SHARED attribute. A local variable without the SAVE or STATIC attribute declared in a procedure referenced within the dynamic extent of a parallel region has an implicit PRIVATE attribute.

Members of common blocks and variables of modules declared in procedure referenced within the dynamic extent of a parallel region have an implicit SHARED attribute, unless they are THREADLOCAL or THREADPRIVATE common blocks and module variables.

While a parallel or work-sharing construct is running, a variable or variable subobject used in a PRIVATE, FIRSTPRIVATE, LASTPRIVATE or REDUCTION clause of the directive must not be referenced, become defined, become undefined, have its association status or allocation status changed, or appear as an actual argument:

You can declare a variable as PRIVATE, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION, even if that variable is already storage associated with other variables. Storage association may exist for variables declared in EQUIVALENCE statements or in COMMON blocks. If a variable is storage associated with a PRIVATE, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION variable, then:

Pointers and OpenMP API Version 2.5

OpenMP API Version 2.5 allows a variable or variable subobject of a PRIVATE clause to have the POINTER or ALLOCATABLE attribute. The association status of the pointer is undefined at thread creation and when the thread is destroyed. The allocatable array must have an allocation status of "not currently allocated" on entry to and exit from OpenMP constructs.

IBM Extension

XL Fortran provides an extension which allows a variable or variable subobject of a FIRSTPRIVATE or LASTPRIVATE clause to have the POINTER attribute. For FIRSTPRIVATE pointers at thread creation, each copy of the pointer receives the same association status as the original. If the pointer is used in a LASTPRIVATE clause, the pointer retains its association status at the end of the last iteration or SECTION.

End of IBM Extension

To maintain full compliance with the OpenMP API Version 2.5 standard, ensure that a POINTER variable applies only to a PRIVATE clause.

COPYIN

Purpose

If you specify the COPYIN clause, the master thread's copy of each variable, or common block declared in the copyin_entity_list is duplicated at the beginning of a parallel region. Each thread in the team that will execute within that parallel region receives a private copy of all entities in the copyin_entity_list. All variables declared in the copyin_entity_list must be THREADPRIVATE or members of a common block that appears in a THREADPRIVATE directive.

Syntax

Read syntax diagramSkip visual syntax diagram>>-COPYIN--(--copyin_entity_list--)----------------------------><
 
copyin_entity
Read syntax diagramSkip visual syntax diagram>>-+-variable_name-----------+---------------------------------><
   '-/--common_block_name--/-'
 
variable
is a THREADPRIVATE variable, or THREADPRIVATE variable in a common block
common_block_name
is a THREADPRIVATE common block name

Rules

If you specify a COPYIN clause, you cannot:

When the master thread of a team of threads reaches a directive containing the COPYIN clause, thread's private copy of a variable or common block specified in the COPYIN clause will have the same value as the master thread's copy.

On entry into any parallel region, a THREADPRIVATE variable, or a variable in a THREADPRIVATE common block is subject to the following criteria when declared in a COPYIN clause:

The COPYIN clause applies to:

COPYPRIVATE

Purpose

If you specify the COPYPRIVATE clause, the value of a private variable or pointer to a shared object from one thread in a team is copied into the corresponding variables of all other threads in that team. If the variable in copyprivate_entity_list is not a pointer, then the corresponding variables of all threads within that team are defined with the value of that variable. If the variable is a pointer, then the corresponding variables of all threads within that team are defined with the association status of the pointer. Integer pointers and assumed-size arrays must not appear in copyprivate_entity_list.

Syntax

Read syntax diagramSkip visual syntax diagram>>-COPYPRIVATE--(--copyprivate_entity_list--)------------------><
 
copyprivate_entity
Read syntax diagramSkip visual syntax diagram>>-+-variable----------------+---------------------------------><
   '-/--common_block_name--/-'
 
variable
is a private variable within the enclosing parallel region
common_block_name
is a THREADPRIVATE common block name

Rules

If a common block is part of the copyprivate_entity_list, then it must appear in a THREADPRIVATE directive. Furthermore, the COPYPRIVATE clause treats a common block as if all variables within its object_list were specified in the copyprivate_entity_list.

A COPYPRIVATE clause must occur on an END SINGLE directive at the end of a SINGLE construct. The compiler evaluates a COPYPRIVATE clause before any threads have passed the implied BARRIER directive at the end of that construct. The variables you specify in copyprivate_entity_list must not appear in a PRIVATE or FIRSTPRIVATE clause for the SINGLE construct. If the END SINGLE directive occurs within the dynamic extent of a parallel region, the variables you specify in copyprivate_entity_list must be private within that parallel region.

A COPYPRIVATE clause must not appear on the same END SINGLE directive as a NOWAIT clause.

A THREADLOCAL common block, or members of that common block, are not permitted as part of a COPYPRIVATE clause.

A COPYPRIVATE clause applies to the following directives:

DEFAULT

Purpose

If you specify the DEFAULT clause, all variables in the lexical extent of the parallel construct will have a scope attribute of default_scope_attr.

If you specify DEFAULT(NONE), there is no default scope attribute. Therefore, you must explicitly list each variable you use in the lexical extent of the parallel construct in a data scope attribute clause on the parallel construct, unless the variable is:

The DEFAULT clause specifies that all variables in the parallel construct share the same default scope attribute of either PRIVATE, SHARED, or no default scope attribute.

Syntax

Read syntax diagramSkip visual syntax diagram>>-DEFAULT--(--default_scope_attr--)---------------------------><
 
default_scope_attr
is one of PRIVATE, SHARED, or NONE

Rules

If you specify DEFAULT(NONE) on a directive you must specify all named variables and all the leftmost names of referenced array sections, array elements, structure components, or substrings in the lexical extent of the directive construct in a FIRSTPRIVATE, LASTPRIVATE, PRIVATE, REDUCTION, or SHARED clause.

If you specify DEFAULT(PRIVATE) on a directive, all named variables and all leftmost names of referenced array sections, array elements, structure components, or substrings in the lexical extent of the directive construct, including common block and use associated variables, but excluding POINTEEs and THREADLOCAL common blocks, have a PRIVATE attribute to a thread as if they were listed explicitly in a PRIVATE clause.

If you specify DEFAULT(SHARED) on a directive, all named variables and all leftmost names of referenced array sections, array elements, structure components, or substrings in the lexical extent of the directive construct, excluding POINTEEs have a SHARED attribute to a thread as if they were listed explicitly in a SHARED clause.

The default behavior will be DEFAULT(SHARED) if you do not explicitly indicate a DEFAULT clause on a directive.

The DEFAULT clause applies to:

Examples

The following example demonstrates the use of DEFAULT(NONE), and some of the rules for specifying the data scope attributes of variables in the parallel region.

      PROGRAM MAIN
        COMMON /COMBLK/ ABC(10), DEF

          ! THE LOOP ITERATION VARIABLE, I, IS NOT
          ! REQUIRED TO BE IN DATA SCOPE ATTRIBUTE CLAUSE

!$OMP   PARALLEL DEFAULT(NONE) SHARED(ABC)

          ! DEF IS SPECIFIED ON THE WORK-SHARING DO AND IS NOT
          ! REQUIRED TO BE SPECIFIED IN A DATA SCOPE ATTRIBUTE
          ! CLAUSE ON THE PARALLEL REGION.

!$OMP   DO FIRSTPRIVATE(DEF)
        DO I=1,10
          ABC(I) = DEF
        END DO
!$OMP   END PARALLEL
      END

IF

Purpose

If you specify the IF clause, the run-time environment performs a test to determine whether to run the block in serial or parallel. If scalar_logical_expression is true, then the block is run in parallel; if not, then the block is run in serial.

Syntax

Read syntax diagramSkip visual syntax diagram>>-IF--(--scalar_logical_expression--)-------------------------><
 

Rules

Within a PARALLEL SECTIONS construct, variables that are not appearing in the PRIVATE clause are assumed to be SHARED by default.

The IF clause may appear at most once in the a any directive.

By default, a nested parallel loop is serialized, regardless of the setting of the IF clause. You can change this default by using the -qsmp=nested_par compiler option.

An IF expression is evaluated outside of the context of the parallel construct. Any function reference in the IF expression must not have side effects.

The IF clause applies to the following directives:

FIRSTPRIVATE

Purpose

If you use the FIRSTPRIVATE clause, each thread has its own initialized local copy of the variables and common blocks in data_scope_entity_list.

The FIRSTPRIVATE clause can be specified for the same variables as the PRIVATE clause, and functions in a manner similar to the PRIVATE clause. The exception is the status of the variable upon entry into the directive construct; the FIRSTPRIVATE variable exists and is initialized for each thread entering the directive construct.

Syntax

Read syntax diagramSkip visual syntax diagram>>-FIRSTPRIVATE--(--data_scope_entity_list--)------------------><
 

Rules

A variable in a FIRSTPRIVATE clause must not be any of the following elements:

You cannot specify a variable in a FIRSTPRIVATE clause of a parallel construct if:

If one of the entities involved in an asynchronous I/O operation is a FIRSTPRIVATE variable, a subobject of a FIRSTPRIVATE variable, or a pointer that is associated with a FIRSTPRIVATE variable, the matching implied wait or WAIT statement must be executed before the end of the thread.

When individual members of a common block are privatized, the storage of the specified variable is no longer associated with the storage of the common block.

Any variable that is storage associated with a FIRSTPRIVATE variable is undefined on entrance into the parallel construct.

If a directive construct contains a FIRSTPRIVATE argument to a Message Passing Interface (MPI) routine performing non-blocking communication, the MPI communication must complete before the end of the construct.

The FIRSTPRIVATE clause applies to the following directives:

LASTPRIVATE

Purpose

If you use the LASTPRIVATE clause, each variable and common block in data_scope_entity_list is PRIVATE, and the last value of each variable in data_scope_entity_list can be referred to outside of the construct of the directive. If you use the LASTPRIVATE clause with DO or PARALLEL DO, the last value is the value of the variable after the last sequential iteration of the loop. If you use the LASTPRIVATE clause with SECTIONS or PARALLEL SECTIONS, the last value is the value of the variable after the last SECTION of the construct. If the last iteration of the loop or last section of the construct does not define a LASTPRIVATE variable, the variable is undefined after the loop or construct.

The LASTPRIVATE clause functions in a manner similar to the PRIVATE clause and you should specify it for variables that match the same criteria. The exception is in the status of the variable on exit from the directive construct. The compiler determines the last value of the variable, and takes a copy of that value which it saves in the named variable for use after the construct. A LASTPRIVATE variable is undefined on entry to the construct if it is not a FIRSTPRIVATE variable.

Syntax

Read syntax diagramSkip visual syntax diagram>>-LASTPRIVATE--(--data_scope_entity_list--)-------------------><
 

Rules

A variable in a LASTPRIVATE clause must not be any of the following elements:

You cannot specify a variable in a LASTPRIVATE clause of a parallel construct if:

If one of the entities involved in an asynchronous I/O operation is a LASTPRIVATE, a subobject of a LASTPRIVATE variable, or a pointer that is associated with a LASTPRIVATE variable, the matching implied wait or WAIT statement must be executed before the end of the thread.

When individual members of a common block are privatized, the storage of the specified variable is no longer associated with the storage of the common block.

Any variable that is storage associated with a LASTPRIVATE variable is undefined on entrance into the parallel construct.

If a directive construct contains a LASTPRIVATE argument to a Message Passing Interface (MPI) routine performing non-blocking communication, the MPI communication must complete before the end of that construct.

If you specify a variable as LASTPRIVATE on a work-sharing directive, and you have specified a NOWAIT clause on that directive, you cannot use that variable between the end of the work-sharing construct and a BARRIER.

Variables that you specify as LASTPRIVATE to a parallel construct become defined at the end of the construct. If you have concurrent definitions or uses of LASTPRIVATE variables on multiple threads, you must ensure that the threads are synchronized at the end of the construct when the variables become defined. For example, if multiple threads encounter a PARALLEL construct with a LASTPRIVATE variable, you must synchronize the threads when they reach the END PARALLEL directive, because the LASTPRIVATE variable becomes defined at END PARALLEL. Therefore the whole PARALLEL construct must be enclosed within a synchronization construct.

The LASTPRIVATE clause applies to the following directives:

Examples

The following example shows the proper use of a LASTPRIVATE variable after a NOWAIT clause.

!$OMP PARALLEL
!$OMP   DO LASTPRIVATE(K)

        DO I=1,10
            K=I+1
        END DO

!$OMP   END DO NOWAIT

! PRINT *, K **ERROR** ! The reference to K must occur after a
                       ! barrier.
!$OMP BARRIER
      PRINT *, K       ! This reference to K is legal.
!$OMP END PARALLEL
      END

NUM_THREADS

Purpose

The NUM_THREADS clause allows you to specify the number of threads used in a parallel region. Subsequent parallel regions are not affected. The NUM_THREADS clause takes precedence over the number of threads specified using the omp_set_num_threads library routine or the environment variable OMP_NUM_THREADS.

Syntax

Read syntax diagramSkip visual syntax diagram>>-NUM_THREADS--(--scalar_integer_expression--)----------------><
 

Rules

The value of scalar_integer_expression must be a positive. Evaluation of the expression occurs outside the context of the parallel region. Any function calls that appear in the expression and change the value of a variable referenced in the expression will have unspecified results.

If you are using the environment variable OMP_DYNAMIC to enable dynamic threads, scalar_integer_expression defines the maximum number of threads available in the parallel region.

You must specify the omp_set_nested library routine or set the OMP_NESTED environment variable when including the NUM_THREADS clause as part of a nested parallel regions otherwise, the execution of that parallel region is serialized.

The NUM_THREADS clause applies to the following work-sharing constructs:

ORDERED

Purpose

Specifying the ORDERED clause on a work-sharing construct allows you to specify the ORDERED directive within the dynamic extent of a parallel loop.

Syntax

Read syntax diagramSkip visual syntax diagram>>-ORDERED-----------------------------------------------------><
 

Rules

The ORDERED clause applies to the following directives:

PRIVATE

Purpose

If you specify the PRIVATE clause on one of the directives listed below, each thread in a team has its own uninitialized local copy of the variables and common blocks in data_scope_entity_list.

You should specify a variable with the PRIVATE attribute if its value is calculated by a single thread and that value is not dependent on any other thread, if it is defined before it is used in the construct, and if its value is not used after the construct ends. Copies of the PRIVATE variable exist, locally, on each thread. Each thread receives its own uninitialized copy of the PRIVATE variable. A PRIVATE variable has an undefined value or association status on entry to, and exit from, the directive construct. All thread variables within the lexical extent of the directive construct have the PRIVATE attribute by default.

Syntax

Read syntax diagramSkip visual syntax diagram>>-PRIVATE--(--data_scope_entity_list--)-----------------------><
 

Rules

A variable in the PRIVATE clause must not be any of the following elements:

You cannot specify a variable in a PRIVATE clause of a parallel construct if:

If one of the entities involved in an asynchronous I/O operation is a PRIVATE variable, a subobject of a PRIVATE variable, or a pointer that is associated with a PRIVATE variable, the matching implied wait or WAIT statement must be executed before the end of the thread.

When individual members of a common block are privatized, the storage of the specified variable is no longer associated with the storage of the common block.

Any variable that is storage associated with a PRIVATE variable is undefined on entrance into the parallel construct.

If a directive construct contains a PRIVATE argument to a Message Passing Interface (MPI) routine performing non-blocking communication, the MPI communication must complete before the end of that construct.

A variable name in the data_scope_entity_list of the PRIVATE clause can be an allocatable object. It must not be allocated on initial entry to the directive construct, and you must allocate and deallocate the object for every thread that executes the construct.

Local variables without the SAVE or STATIC attributes in referenced subprograms in the dynamic extent of a directive construct have an implicit PRIVATE attribute.

The PRIVATE clause applies to the following directives:

Examples

The following example demonstrates the proper use of a PRIVATE variable that is used to define a statement function. A commented line shows the invalid use. Since J appears in a statement function, the statement function cannot be referenced within the parallel construct for which J is PRIVATE.

      INTEGER :: ARR(10), J = 17
      ISTFNC() = J

!$OMP PARALLEL DO PRIVATE(J)
      DO I = 1, 10
         J=I
         ARR(I) = J
      !  ARR(I) = ISTFNC() **ERROR**   A reference to ISTFNC would
                                       ! make the PRIVATE(J) clause
                                       ! invalid.
      END DO
      PRINT *, ARR
      END

REDUCTION

Purpose

The REDUCTION clause updates named variables declared on the clause within the directive construct. Intermediate values of REDUCTION variables are not used within the parallel construct, other than in the updates themselves.

Syntax

Read syntax diagramSkip visual syntax diagram>>-REDUCTION--(--+-----------+--variable_name_list--)----------><
                 '-op_fnc--:-'
 
op_fnc
is a reduction_op or a reduction_function that appears in all REDUCTION statements involving this variable. You must not specify more than one REDUCTION operator or function for a variable in the directive construct. To maintain OpenMP API Version 2.5 compliance, you must specify op_fnc for the REDUCTION clause.

A REDUCTION statement can have one of the following forms:

Read syntax diagramSkip visual syntax diagram>>-reduction_var_ref--=--expr--reduction_op--reduction_var_ref-><
 
Read syntax diagramSkip visual syntax diagram>>-reduction_var_ref--=--reduction_var_ref--reduction_op--expr-><
 
Read syntax diagramSkip visual syntax diagram>>-reduction_var_ref =--reduction_function--(expr,--reduction_var_ref)-><
 
Read syntax diagramSkip visual syntax diagram>>-reduction_var_ref =--reduction_function--(reduction_var_ref,--expr)-><
 

where:

reduction_var_ref
is a variable or subobject of a variable that appears in a REDUCTION clause
reduction_op
is one of the intrinsic operators: +, -, *, .AND., .OR., .EQV., .NEQV., or .XOR.
reduction_function
is one of the intrinsic procedures: MAX, MIN, IAND, IOR, or IEOR.

The canonical initialization value of each of the operators and intrinsics are shown in the following table. The actual initialization value will be consistent with the data type of your corresponding REDUCTION variable.

Intrinsic Operator Initialization
+ 0
* 1
- 0
.AND. .TRUE.
.OR. .FALSE.
.EQV. .TRUE.
.NEQV. .FALSE.
.XOR. .FALSE.
Intrinsic Procedure Initialization
MAX Smallest representable number
MIN Largest representable number
IAND All bits on
IOR 0
IEOR 0

Rules

The following rules apply to REDUCTION statements:

When you specify individual members of a common block in a REDUCTION clause, the storage of the specified variable is no longer associated with the storage of the common block.

Any variable you specify in a REDUCTION clause of a work-sharing construct must be shared in the enclosing PARALLEL construct.

If you use a REDUCTION clause on a construct that has a NOWAIT clause, the REDUCTION variable remains undefined until a barrier synchronization has been performed to ensure that all threads have completed the REDUCTION clause.

A REDUCTION variable must not appear in a FIRSTPRIVATE, PRIVATE or LASTPRIVATE clause of another construct within the dynamic extent of the construct in which it appeared as a REDUCTION variable.

If you specify op_fnc for the REDUCTION clause, each variable in the variable_name_list must be of intrinsic type. The variablecan only appear in a REDUCTION statement within the lexical extent of the directive construct. You must specify op_fnc if the directive uses the trigger_constant $OMP.

The REDUCTION clause specifies named variables that appear in reduction operations. The compiler will maintain local copies of such variables, but will combine them upon exit from the construct. The intermediate values of the REDUCTION variables are combined in random order, dependent on which threads finish their calculations first. Therefore, there is no guarantee that bit-identical results will be obtained from one parallel run to another. This is true even if the parallel runs use the same number of threads, scheduling type, and chunk size.

Variables that you specify as REDUCTION or LASTPRIVATE to a parallel construct become defined at the end of the construct. If you have concurrent definitions or uses of REDUCTION or LASTPRIVATE variables on multiple threads, you must ensure that the threads are synchronized at the end of the construct when the variables become defined. For example, if multiple threads encounter a PARALLEL construct with a REDUCTION variable, you must synchronize the threads when they reach the END PARALLEL directive, because the REDUCTION variable becomes defined at END PARALLEL. Therefore the whole PARALLEL construct must be enclosed within a synchronization construct.

A variable in the REDUCTION clause must be of intrinsic type. A variable in the REDUCTION clause, or any element thereof, must not be any of the following:

These rules describe the use of REDUCTION on OpenMP directives. If you are using the REDUCTION clause on the INDEPENDENT directive, see the INDEPENDENT directive directive.

The OpenMP implementation of the REDUCTION clause applies to:

SCHEDULE

Purpose

The SCHEDULE clause allows you to specify the chunking method for parallelization. Work is assigned to threads in different manners depending on the scheduling type or chunk size used.

Syntax

Read syntax diagramSkip visual syntax diagram>>-SCHEDULE--(--sched_type--+----+--)--------------------------><
                            '-,n-'
 
sched_type
is one of AFFINITY, DYNAMIC, GUIDED, RUNTIME, or STATIC
n
must be a positive scalar integer expression; it must not be specified for the RUNTIME sched_type. If you are using the trigger_constant $OMP, do not specify the scheduling type AFFINITY.
AFFINITY
The iterations of a loop are initially divided into number_of_threads partitions, containing
CEILING(number_of_iterations / number_of_threads)
iterations. Each partition is initially assigned to a thread, and is then further subdivided into chunks containing n iterations, if n has been specified. If n has not been specified, then the chunks consist of
CEILING(number_of_iterations_remaining_in_partition / 2)
loop iterations.

When a thread becomes free, it takes the next chunk from its initially assigned partition. If there are no more chunks in that partition, then the thread takes the next available chunk from a partition that is initially assigned to another thread.

Threads that are active will complete the work in a partition that is initially assigned to a sleeping thread.

DYNAMIC
If n has been specified, the iterations of a loop are divided into chunks containing n iterations each. If n has not been specified, then the default chunk size is 1 iteration.

Threads are assigned these chunks on a "first-come, first-do" basis. Chunks of the remaining work are assigned to available threads, until all work has been assigned.

If a thread is asleep, its assigned work will be taken over by an active thread, once that other thread becomes available.

GUIDED
If you specify a value for n, the iterations of a loop are divided into chunks such that the size of each successive chunk is exponentially decreasing. n specifies the size of the smallest chunk, except possibly the last. If you do not specify a value for n, the default value is 1.

The size of the initial chunk is proportional to:

CEILING(number_of_iterations / number_of_threads)

iterations. Subsequent chunks are proportional to:

CEILING(number_of_iterations_remaining / number_of_threads)

iterations. If n is greater than 1, each chunk should contain fewer than n iterations (except for the last chunk to be assigned, which can have fewer than n iterations. As each thread finishes a chunk, it dynamically obtains the next available chunk.

You can use guided scheduling in a situation in which multiple threads in a team might arrive at a DO work-sharing construct at varying times, and each iteration requires roughly the same amount of work. For example, if you have a DO loop preceded by one or more work-sharing SECTIONS or DO constructs with NOWAIT clauses, you can guarantee that no thread waits at the barrier longer than it takes another thread to execute its final iteration, or final k iterations if a chunk size of k is specified. The GUIDED schedule requires the fewest synchronizations of all the scheduling methods.

An n expression is evaluated outside of the context of the DO construct. Any function reference in the n expression must not have side effects.

The value of the n parameter on the SCHEDULE clause must be the same for all of the threads in the team.

RUNTIME
Determine the scheduling type at run time.

At run time, the scheduling type can be specified using the environment variable XLSMPOPTS. If no scheduling type is specified using that variable, then the default scheduling type used is STATIC.

STATIC
If n has been specified, the iterations of a loop are divided into chunks that contain n iterations. Each thread is assigned chunks in a "round robin" fashion. This is known as block cyclic scheduling. If the value of n is 1, then the scheduling type is specifically referred to as cyclic scheduling.

If n has not been specified, the chunks will contain

CEILING(number_of_iterations / number_of_threads)

iterations. Each thread is assigned one of these chunks. This is known as block cyclic scheduling.

If a thread is asleep and it has been assigned work, it will be awakened so that it may complete its work.

STATIC is the default scheduling type if the user has not specified any scheduling type at compile-time or run time.

Rules

You must not specify the SCHEDULE clause more than once for a particlaur DO directive.

The SCHEDULE clause applies to the following directives:

SHARED

Purpose

All sections use the same copy of the variables and common blocks you specify in data_scope_entity_list.

The SHARED clause specifies variables that must be available to all threads. If you specify a variable as SHARED, you are stating that all threads can safely share a single copy of the variable.

Syntax

Read syntax diagramSkip visual syntax diagram>>-SHARED--(--data_scope_entity_list--)------------------------><
 
data_scope_entity
Read syntax diagramSkip visual syntax diagram>>-+-named_variable----------+---------------------------------><
   '-/--common_block_name--/-'
 
named_variable
is a named variable that is accessible in the directive construct
common_block_name
is a common block name that is accessible in the directive construct

Rules

A variable in the SHARED clause must not be either:

If a SHARED variable, a subobject of a SHARED variable, or an object associated with a SHARED variable or subobject of a SHARED variable appears as an actual argument in a reference to a non-intrinsic procedure and:

then any references to or definitions of the shared storage that is associated with the dummy argument by any other thread must be synchronized with the procedure reference. In other words, you must structure your code in such a way that if a thread encounters a procedure reference, then the procedure call by that thread and any reference to or definition of the shared storage by any other thread will always occur in the same sequence. You can do this, for example, by placing the procedure reference after a BARRIER.

The SHARED clause applies to:

Examples

In the following example, the procedure reference with an array section actual argument is required to be synchronized with references to the dummy argument by placing the procedure reference in a critical section, because the associated dummy argument is an explicit-shape array.

      INTEGER:: ABC(10)
      I=2; J=5
!$OMP PARALLEL DEFAULT(NONE), SHARED(ABC,I,J)
!$OMP   CRITICAL
          CALL SUB1(ABC(I:J))    ! ACTUAL ARGUMENT IS AN ARRAY
                                 ! SECTION; THE PROCEDURE
                 ! REFERENCE MUST BE IN A CRITICAL SECTION.

!$OMP   END CRITICAL
!$OMP END PARALLEL
      CONTAINS
        SUBROUTINE SUB1(ARR)
          INTEGER:: ARR(1:4)
          DO I=1, 4
            ARR(I) = I
          END DO
        END SUBROUTINE
      END