XL Fortran for AIX 8.1

Language Reference


Clauses for SMP and Thead-Safing Directives

The following clauses allow you to specify the scope attributes of variables that you are using in parallel constructs:

The following clauses allow control of the parallel environment of a parallel region:

Format



>>-+-private_clause------+-------------------------------------><
   +-firstprivate_clause-+
   +-lastprivate_clause--+
   +-copyin_clause-------+
   +-copyprivate_clause--+
   +-shared_clause-------+
   +-default_clause------+
   +-reduction_clause----+
   '-num_threads_clause--'
 
 

private_clause



>>-PRIVATE--(--data_scope_entity_list--)-----------------------><
 
 

firstprivate_clause



>>-FIRSTPRIVATE--(--data_scope_entity_list--)------------------><
 
 

lastprivate_clause



>>-LASTPRIVATE--(--data_scope_entity_list--)-------------------><
 
 

shared_clause



>>-SHARED--(--data_scope_entity_list--)------------------------><
 
 

data_scope_entity



>>-+-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

copyin_clause



>>-COPYIN--(--copyin_entity_list--)----------------------------><
 
 

copyin_entity



>>-+-variable_name-----------+---------------------------------><
   '-/--common_block_name--/-'
 
 

variable
is a THREADPRIVATE variable name

common_block_name
is a THREADPRIVATE common block name

copyprivate_clause



>>-COPYPRIVATE--(--copyprivate_entity_list--)------------------><
 
 

copyprivate_entity



>>-+-variable----------------+---------------------------------><
   '-/--common_block_name--/-'
 
 

variable
is a private variable within the enclosing parallel region

common_block_name
is a THREADPRIVATE common block name

default_clause



>>-DEFAULT--(--default_scope_attr--)---------------------------><
 
 

default_scope_attr
is one of PRIVATE, SHARED, or NONE

reduction_clause



>>-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. Whether op_fnc is specified or not, only one REDUCTION operator or function must be used for that variable in the directive construct.

num_threads_clause



>>-NUM_THREADS--(--scalar_integer_expression--)----------------><
 
 

Rules

You cannot specify a variable or common block name more than once in the scope of a clause. A variable or common block name must not appear in the scope of more than one attribute clause on the same directive, with one exception. You can define a named variable or named common block as both FIRSTPRIVATE and LASTPRIVATE for the same directive construct.

If you specify a common block name on a data attribute clause, the common block name is expanded to its list of common block members by the compiler. Therefore, you cannot specify a common block name and a variable that is a member of that common block in the same data_scope_entity_list, copyin_entity_list or copyprivate_entity_list. Similarly, you cannot specify a common block name in the data_scope_entity_list of an attribute clause and a variable that is a member of that common block on another attribute clause of the same directive, except if the attribute clauses are the FIRSTPRIVATE and LASTPRIVATE clauses.

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 member of a named common block that has the FIRSTPRIVATE, PRIVATE, or LASTPRIVATE attribute is undefined in the parallel construct.

You cannot specify a variable in a PRIVATE, FIRSTPRIVATE or LASTPRIVATE clause of a parallel construct if:

If you do not specify a data scope clause, the default scope for variables affected by the directive construct is SHARED.

Local variables without the SAVE or STATIC attributes in referenced subprograms in the dynamic extent of a parallel region have an implicit PRIVATE attribute. If you declare a local variable with the SAVE or STATIC attribute in a procedure that is called from a parallel region, the variable has an implicit SHARED attribute. Members of common blocks and the variables of modules referenced in subprograms within the dynamic extent of a parallel region have an implict SHARED attribute, unless they are THREADLOCAL or THREADPRIVATE common blocks and variables.

If there is a call to an MPI routine that does non-blocking communication in the directive construct, and any argument to the MPI routine is FIRSTPRIVATE, LASTPRIVATE, or PRIVATE, the MPI communication must complete before the end of the construct.

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

A variable or a subobject of a variable in the data_scope_entity_list of a PRIVATE, FIRSTPRIVATE or LASTPRIVATE clause of a PARALLEL, PARALLEL DO, DO, PARALLEL SECTIONS, PARALLEL WORKSHARE, SECTIONS or SINGLE directive may have the POINTER attribute. Such a pointer has an undefined association status when a thread is created. The pointer also has an undefined association status when a thread is destroyed, unless the variable appears in the LASTPRIVATE clause. If the variable appears in the LASTPRIVATE clause, the pointer retains its association status at the end of the last iteration or SECTION.

Note:
XL Fortran allows Fortran 90 and integer pointers in FIRSTPRIVATE and LASTPRIVATE clauses; however, the OpenMP specification does not. Therefore, if you want your programs to be fully compliant with the OpenMP specification, you should not use Fortran 90 or integer pointers in a FIRSTPRIVATE or LASTPRIVATE clause.

While a parallel or work-sharing directive construct is running, a variable or subobject of a variable that appears 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:

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.

You cannot specify a THREADPRIVATE common block, the variables that comprise that block or a THREADPRIVATE variable in a PRIVATE, LASTPRIVATE, FIRSTPRIVATE, SHARED, or REDUCTION clause.

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:

You cannot access the name of a common block by use association or host association. Thus, a named common block can only appear in a data attribute clause if the common block is declared in the scoping unit that contains the directive. However, you can access the variables in the common block by use association or host association. For more information, see Host Association and Use Association.

Examples

Example 1: 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
        ARR(I) = J
      ! ARR(I) = ISTFNC() **ERROR**   A reference to ISTFNC would
                                    ! make the PRIVATE(J) clause
                                    ! invalid.
      END DO
      PRINT *, ARR
      END

Example 2: In the following example, ABC and DEF are storage-associated, and ABC is a LASTPRIVATE variable. The example shows an instance of how ABC and DEF may become undefined.

INTEGER:: ABC(10), DEF(10), INDX1
      EQUIVALENCE(ABC(9),DEF(1))
 
!$OMP PARALLEL DO PRIVATE(INDX1) LASTPRIVATE(ABC)
      DO INDX1= 1, 10
        ABC(INDX1) = INDX1 + 1      ! ABC IS REFERENCED, SO DEF
                                    ! BECOMES UNDEFINED.
        DEF(INDX1) = DEF(INDX1)-1   ! DEF'N OF DEF IS UNDEFINED.
      END DO
 
      PRINT *, ABC       ! LASTPRIVATE ABC IS UNDEFINED,
                         ! BECAUSE DEF WAS REFERENCED.
      PRINT *, DEF       ! DEF IS ALSO UNDEFINED SINCE
                         ! LASTPRIVATE ABC IS UNDEFINED.

Example 3: In the following example, the common block /ABC/ cannot be accessed by host or use association, so it cannot be specified on the COPYIN clause. However, the variable I, which is in the common block /ABC/, can be specified in the COPYIN clause.

      MODULE MOD
        COMMON /ABC/ I
!$OMP   THREADPRIVATE (/ABC/)
      END MODULE MOD
 
      PROGRAM T
        USE MOD
!$OMP   PARALLEL COPYIN(I)    ! COPYIN(/ABC/) WOULD BE INVALID HERE
! ...
        I=0
!$OMP   END PARALLEL
      END PROGRAM

List of Data Scope Attribute Clauses

The data scope attribute clauses are:

PRIVATE(data_scope_entity_list)

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.

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

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:

FIRSTPRIVATE(data_scope_entity_list)

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.

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

The FIRSTPRIVATE clause applies to the following directives:

LASTPRIVATE(data_scope_entity_list)

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.

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

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 prior to a barrier.

The LASTPRIVATE clause applies to the following directives:

Example:

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

REDUCTION([op_fnc] : variable_name_list)

The REDUCTION clause asserts that updates to named variables will occur within REDUCTION statements in the directive construct. Furthermore, the intermediate values of the REDUCTION variables are not used within the parallel construct, other than in the updates themselves. Thus, the value of the REDUCTION variable after the construct is the result of a reduction tree.

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 variable can 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 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

A REDUCTION statement can have one of the following forms:



>>-reduction_var_ref--=--expr--reduction_op--reduction_var_ref-><
 
 
>>-reduction_var_ref--=--reduction_var_ref--reduction_op--expr-><
 
 
>>-reduction_var_ref =--reduction_function--(expr,--reduction_var_ref)-><
 
 
>>-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 following rules apply to REDUCTION statements:

  1. A variable in the REDUCTION clause must only occur in a REDUCTION statement within the directive construct on which the REDUCTION clause appears.
  2. The two reduction_var_refs that appear in a REDUCTION statement must be lexically identical.
  3. You cannot use the following form of the REDUCTION statement:



    >>-reduction_var_ref-- = --expr-- - --reduction_var_ref--------><
     
     
    

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.

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 INDEPENDENT.

The OpenMP implementation of the REDUCTION clause applies to:

COPYIN(copyin_entity_list)

If you specify the COPYIN clause, the master thread's copy of each variable, or common block variable 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.

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.

The COPYIN clause applies to:

COPYPRIVATE(copyprivate_entity_list)

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 value of the pointer, not the value of the object it points to. Integer pointers and assumed-size arrays must not appear in copyprivate_entity_list.

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_listmust 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(default_scope_attr)

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.

If you specify DEFAULT(NONE) on a directive there will be no implicit DEFAULT scope attribute as to whether variables are PRIVATE or SHARED. In this situation 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 PRIVATE, FIRSTPRIVATE, SHARED, or REDUCTION 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:

Example:

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

SHARED(data_scope_entity_list)

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.

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. You can do this, for example, by placing the procedure reference after a BARRIER.

The SHARED clause applies to:

Example:

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

NUM_THREADS(scalar_integer_expression)

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.

The value of scalar_integer_expression must be a positive scalar integer expression. You must not specify more than one value. 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 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:


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]