| CF90TM Commands and Directives Reference Manual | ||
|---|---|---|
| Prev Section | Chapter 4. OpenMP Fortran API Directives (UNICOS Systems Only) | Next Section |
The following subsections present constructs for controlling the data environment during the execution of parallel constructs. Section 4.7.1, describes the THREADPRIVATE directive, which makes common blocks local to a thread. Section 4.7.2, describes directive clauses that affect the data environment.
The THREADPRIVATE directive makes named common blocks private to a thread but global within the thread. In other words, each thread executing a THREADPRIVATE directive receives its own private copy of the named common blocks, which are then available to it in any routine within the scope of an application.
This directive must appear in the declaration section of the routine after the declaration of the listed common blocks. Each thread gets its own copy of the common block, so data written to the common block by one thread is not directly visible to other threads. During serial portions and MASTER sections of the program, accesses are to the master thread's copy of the common block.
On entry to the first parallel region, data in the THREADPRIVATE common blocks should be assumed to be undefined unless a COPYIN clause is specified on the PARALLEL directive. When a common block that is initialized using DATA statements appears in a THREADPRIVATE directive, each thread's copy is initialized once prior to its first use. For subsequent parallel regions, the data in the THREADPRIVATE common blocks are guaranteed to persist only if the dynamic threads mechanism has been disabled and if the number of threads are the same for all the parallel regions.
For more information on dynamic threads, see the OMP_SET_DYNAMIC library routine.
The format of this directive is as follows:
!$OMP THREADPRIVATE(/cb/[,/cb/]...) |
| cb | The name of the common block to be made private to a thread. Only named common blocks can be made thread private. |
The following restrictions apply to the THREADPRIVATE directive:
The THREADPRIVATE directive must appear after every declaration of a thread private common block.
You cannot use a THREADPRIVATE common block or its constituent variables in any clause other than a COPYIN clause. As a result, they are not permitted in a PRIVATE, FIRSTPRIVATE, LASTPRIVATE, SHARED, or REDUCTION clause. They are not affected by the DEFAULT clause.
Several directives accept clauses that allow a user to control the scope attributes of variables for the duration of the construct. Not all of the clauses in this section are allowed on all directives, but the clauses that are valid on a particular directive are included with the description of the directive. Usually, if no data scope clauses are specified for a directive, the default scope for variables affected by the directive is SHARED. Exceptions to this are described in Section 4.7.3.
The following sections describe the data scope attribute clauses:
Section 4.7.2.1, describes the PRIVATE clause.
Section 4.7.2.2, describes the SHARED clause.
Section 4.7.2.3, describes the DEFAULT clause.
Section 4.7.2.4, describes the FIRSTPRIVATE clause.
Section 4.7.2.5, describes the LASTPRIVATE clause.
Section 4.7.2.6, describes the REDUCTION clause.
Section 4.7.2.7, describes the COPYIN clause.
The PRIVATE clause declares variables to be private to each thread in a team.
This clause has the following format:
PRIVATE(var[, var] ...) |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. If a named common block is specified, its name must appear between slashes. |
The behavior of a variable declared in a PRIVATE clause is as follows:
A new object of the same type is declared once for each thread in the team. The new object is no longer storage associated with the storage location of the original object.
All references to the original object in the lexical extent of the directive construct are replaced with references to the private object.
Variables defined as PRIVATE are undefined for each thread on entering the construct and the corresponding shared variable is undefined on exit from a parallel construct.
Contents, allocation state, and association status of variables defined as PRIVATE are undefined when they are referenced outside the lexical extent (but inside the dynamic extent) of the construct, unless they are passed as actual arguments to called routines.
Example. The following example shows how to scope variables with the PRIVATE clause:
INTEGER I,J
I = 1
J = 2
!$OMP PARALLEL PRIVATE(I) FIRSTPRIVATE(J)
I = 3
J = J+ 2
!$OMP END PARALLEL
PRINT *, I, J |
In the preceding code, the values of I and J are undefined on exit from the parallel region.
The SHARED clause makes variables shared among all the threads in a team. All threads within a team access the same storage area for SHARED data.
This clause has the following format:
SHARED(var[, var] ...) |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. If a named common block is specified, its name must appear between slashes. |
The DEFAULT clause allows the user to specify a PRIVATE, SHARED, or NONE default scope attribute for all variables in the lexical extent of any parallel region. Variables in THREADPRIVATE common blocks are not affected by this clause.
This clause has the following format:
DEFAULT(PRIVATE | SHARED| NONE) |
The PRIVATE, SHARED, and NONE specifications have the following effects:
Specifying DEFAULT(PRIVATE) makes all named objects in the lexical extent of the parallel region, including common block variables but excluding THREADPRIVATE variables, private to a thread as if each variable were listed explicitly in a PRIVATE clause.
Specifying DEFAULT(SHARED) makes all named objects in the lexical extent of the parallel region shared among the threads in a team, as if each variable were listed explicitly in a SHARED clause. In the absence of an explicit DEFAULT clause, the default behavior is the same as if DEFAULT(SHARED) were specified.
Specifying DEFAULT(NONE) declares that there is no implicit default as to whether variables are PRIVATE or SHARED. In this case, the PRIVATE, SHARED, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION attribute of each variable used in the lexical extent of the parallel region must be specified.
Only one DEFAULT clause can be specified on a PARALLEL directive.
Variables can be exempted from a defined default using the PRIVATE, SHARED, FIRSTPRIVATE, LASTPRIVATE, and REDUCTION clauses. As a result, the following example is valid:
!$OMP PARALLEL DO DEFAULT(PRIVATE), FIRSTPRIVATE(I),SHARED(X), !$OMP& SHARED(R) LASTPRIVATE(I) |
The FIRSTPRIVATE clause provides a superset of the functionality provided by the PRIVATE clause.
This clause has the following format:
FIRSTPRIVATE(var[, var] ...) |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. If a named common block is specified, its name must appear between slashes. Variables specified are subject to PRIVATE clause semantics described in Section 4.7.2.1. In addition, private copies of the variables are initialized from the original object existing before the construct. |
The LASTPRIVATE clause provides a superset of the functionality provided by the PRIVATE clause.
When the LASTPRIVATE clause appears on a DO directive, the thread that executes the sequentially last iteration updates the version of the object it had before the construct. When the LASTPRIVATE clause appears in a SECTIONS directive, the thread that executes the lexically last SECTION updates the version of the object it had before the construct. Subobjects that are not assigned a value by the last iteration of the DO or the lexically last SECTION of the SECTIONS directive are undefined after the construct.
This clause has the following format:
LASTPRIVATE(var[, var] ...) |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. If a named common block is specified, its name must appear between slashes. Each var is subject to the PRIVATE clause semantics described in Section 4.7.2.1. |
Example. Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables as arguments to a LASTPRIVATE clause so that the values of the variables are the same as when the loop is executed sequentially.
!$OMP PARALLEL
!$OMP DO LASTPRIVATE(I)
DO I=1,N
A(I) = B(I) + C(I)
ENDDO
!$OMP END PARALLEL
CALL REVERSE(I) |
In the preceding code fragment, the value of I at the end of the parallel region will equal N+1, as in the sequential case.
This clause performs a reduction on the variables specified, with the operator or the intrinsic specified.
This clause has the following format:
REDUCTION({operator|intrinsic}:var[, var] ...) |
| operator | Specify one of the following: +, *, -, .AND., .OR., .EQV., or .NEQV. | |
| intrinsic | Specify one of the following: MAX, MIN, IAND, IOR, or IEOR. | |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. Each var must be a named scalar variable of intrinsic type. Variables that appear in a REDUCTION clause must be SHARED in the enclosing context. A private copy of each var is created for each thread as if the PRIVATE clause had been used. The private copy is initialized according to the operator. For more information, see Table 4-1. If a named common block is specified, its name must appear between slashes. |
At the end of the REDUCTION, the shared variable is updated to reflect the result of combining the original value of the (shared) reduction variable with the final value of each of the private copies using the operator specified. The reduction operators are all associative (except for subtraction), and the compiler can freely reassociate the computation of the final value (the partial results of a subtraction reduction are added to form the final value).
The value of the shared variable becomes undefined when the first thread reaches the containing clause, and it remains so until the reduction computation is complete. Normally, the computation is complete at the end of the REDUCTION construct; however, if the REDUCTION clause is used on a construct to which NOWAIT is also applied, the shared variable remains undefined until a barrier synchronization has been performed to ensure that all the threads have completed the REDUCTION clause.
The REDUCTION clause is intended to be used on a region or work-sharing construct in which the reduction variable is used only in reduction statements with one of the following forms:
|
Some reductions can be expressed in other forms. For instance, a MAX reduction might be expressed as follows:
IF (x .LT. expr) x = expr |
Alternatively, the reduction might be hidden inside a subroutine call. You must ensure that the operator specified in the REDUCTION clause matches the reduction operation.
The following table lists the operators and intrinsics that are valid and their canonical initialization values. The actual initialization value will be consistent with the data type of the reduction variable.
Table 4-1. Initialization values
Operator/Intrinsic | Initialization |
|---|---|
+ | 0 |
* | 1 |
- | 0 |
.AND. | .TRUE. |
.OR. | .FALSE. |
.EQV. | .TRUE. |
.NEQV. | .FALSE. |
MAX | Smallest representable number |
MIN | Largest representable number |
IAND | All bits on |
IOR | 0 |
IEOR | 0 |
Any number of reduction clauses can be specified on the directive, but a variable can appear only once in a REDUCTION clause for that directive.
Example 1. The following directive line shows use of the REDUCTION clause:
!$OMP DO REDUCTION(+: A, Y) REDUCTION(.OR.: AM) |
Example 2. The following code fragment shows how to use the REDUCTION clause:
!$OMP PARALLEL DO DEFAULT(PRIVATE) REDUCTION(+: A,B)
DO I=1,N
CALL WORK(ALOCAL,BLOCAL)
A = A + ALOCAL
B = B + BLOCAL
ENDDO
!$OMP END PARALLEL DO |
The COPYIN clause applies only to common blocks that are declared THREADPRIVATE. A COPYIN clause on a parallel region specifies that the data in the master thread of the team be copied to the thread private copies of the common block at the beginning of the parallel region.
This clause has the following format:
COPYIN(var[, var] ...) |
| var | A named variable or named common block that is accessible in the scoping unit. Subobjects cannot be specified. If a named common block is specified, its name must appear between slashes. |
It is not necessary to specify a whole common block to be copied in.
Example. In the following example, the common blocks BLK1 and FIELDS are specified as thread private, but only one of the variables in common block FIELDS is specified to be copied in:
COMMON /BLK1/ SCRATCH
COMMON /FIELDS/ XFIELD, YFIELD, ZFIELD
!$OMP THREADPRIVATE(/BLK1/, /FIELDS/)
!$OMP PARALLEL DEFAULT(PRIVATE) COPYIN(/BLK1/,ZFIELD) |
The following rules and restrictions apply with respect to data scope:
Sequential DO loop control variables in the lexical extent of a PARALLEL region that would otherwise be SHARED based on default rules are automatically made private on the PARALLEL directive. Sequential DO loop control variables with no enclosing PARALLEL region are not classified automatically. You must guarantee that these indexes are private if the containing procedures are called from a PARALLEL region.
All implied DO loop control variables are automatically made private at the enclosing implied DO construct.
Variables that are made private in a parallel region cannot be made private again on an enclosed work-sharing directive. As a result, variables that appear in the PRIVATE, FIRSTPRIVATE, LASTPRIVATE, and REDUCTION clauses on a work-sharing directive have shared scope in the enclosing parallel region.
A variable that appears in a PRIVATE, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION clause must be definable.
Assumed-size and assumed-shape arrays cannot be specified as PRIVATE, FIRSTPRIVATE, or LASTPRIVATE. Array dummy arguments that are explicitly shaped (including variably dimensioned) can be declared in any scoping clause.
Fortran pointers and allocatable arrays can be declared as PRIVATE or SHARED but not as FIRSTPRIVATE or LASTPRIVATE.
Within a parallel region, the initial status of a private pointer is undefined. Private pointers that become allocated during the execution of a parallel region should be explicitly deallocated by the program prior to the end of the parallel region to avoid memory leaks.
The association status of a SHARED pointer becomes undefined upon entry to and on exit from the parallel construct if it is associated with a target or a subobject of a target that is PRIVATE, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION inside the parallel construct. An allocatable array declared PRIVATE has an allocation status of not currently allocated on entry to and on exit from the construct.
PRIVATE or SHARED attributes can be declared for a Cray pointer but not for the pointee. The scope attribute for the pointee is determined at the point of pointer definition. You cannot declare a scope attribute for a pointee. Cray pointers cannot be specified in FIRSTPRIVATE or LASTPRIVATE clauses.
Scope clauses apply only to variables in the static extent of the directive on which the clause appears, with the exception of variables passed as actual arguments. Local variables in called routines that do not have the SAVE attribute are PRIVATE. Common blocks and modules in called routines in the dynamic extent of a parallel region always have an implicit SHARED attribute, unless they are THREADPRIVATE common blocks.
When a named common block is declared as PRIVATE, FIRSTPRIVATE, or LASTPRIVATE, none of its constituent elements may be declared in another scope attribute. When individual members of a common block are privatized, the storage of the specified variables is no longer associated with the storage of the common block itself.
Variables that are not allowed in the PRIVATE and SHARED clauses are not affected by DEFAULT(PRIVATE) or DEFAULT(SHARED) clauses, respectively.
Clauses can be repeated as needed, but each variable can appear explicitly in only one clause per directive, with the following exceptions:
A variable can be specified as both FIRSTPRIVATE and LASTPRIVATE.
Variables affected by the DEFAULT clause can be listed explicitly in a clause to override the default specification.
| Prev Section | Table of Contents | Title Page | Next Section |
| Synchronization Constructs | Up one level | Directive Binding |