Visible to Intel only — GUID: GUID-1E0E9A70-D184-4C69-9167-DC5B688E1169
Visible to Intel only — GUID: GUID-1E0E9A70-D184-4C69-9167-DC5B688E1169
LASTPRIVATE
Parallel Directive Clause: Provides a superset of the functionality provided by the PRIVATE clause. It declares one or more variables to be private to an implicit task, and causes the corresponding original variable to be updated after the end of the region.
Syntax
LASTPRIVATE ([CONDITIONAL:] list)
CONDITIONAL |
Is an optional modifier specifying that the last value assigned to a list item can be from the sequentially last iteration of the associated loops or the lexically last section construct. |
list |
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /). If CONDITIONAL is present, list items must be scalar of intrinsic type (INTEGER, REAL, COMPLEX, LOGICAL, and CHARACTER) and they must have neither the POINTER nor the ALLOCATABLE attribute. |
Variables that appear in a LASTPRIVATE list are subject to PRIVATE clause semantics. In addition, once the parallel region is exited, each variable has the value provided by the sequentially last section or loop iteration.
Multiple LASTPRIVATE clauses are allowed on all of the directives that accept them. A list item may not appear in more than one LASTPRIVATE clause. LASTPRIVATE (CONDITIONAL:A,B) is equivalent to LASTPRIVATE(CONDITIONAL:A) LASTPRIVATE(CONDITIONAL:B).
LASTPRIVATE (CONDITIONAL:list) can appear in the following directives:
OMP DISTRIBUTE
OMP DO
OMP SECTIONS
OMP SIMD
OMP TASKLOOP
Any and all of the combination directives of the above directives
The OMP PARALLEL directive does not allow the LASTPRIVATE clause.
If the original variable has the POINTER attribute, its update occurs as if by pointer assignment.
If the original variable does not have the POINTER attribute, its update occurs as if by intrinsic assignment.
When a LASTPRIVATE clause without the CONDITIONAL modifier appears in a worksharing or a SIMD directive, the value of each new list item from the sequentially last iteration of the associated loops, or the lexically last section, is assigned to the original list item.
When the CONDITIONAL modifier is specified, the final value written by the sequentially last iteration or lexically last section that writes to a list item, if any, is assigned to the original list item.
When the CONDITIONAL modifier is not specified, list items that are not assigned a value by the sequentially last iteration of the loops, or by the lexically last section, have unspecified values after the construct.
Therefore, variables specified in the list of a LASTPRIVATE clause that contains a CONDITIONAL modifier should be variables that are conditionally assigned to in the loop/region/sections. The variables in the list of a LASTPRIVATE clause that does not contain a CONDITIONAL modifier should be variables that are unconditionally assigned to in the loop or sections.
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.
The original variable becomes defined at the end of the construct if there is an implicit barrier at that point. To avoid race conditions, concurrent reads or updates of the original variable must be synchronized with the update of the original variable that occurs as a result of the LASTPRIVATE clause.
If the LASTPRIVATE clause is used in a construct for which NOWAIT is specified, accesses to the original variable may create a data race. To avoid this, synchronization must be inserted to ensure that the sequentially last iteration or lexically last section construct has stored and flushed that variable.
The following are restrictions for the LASTPRIVATE clause:
A variable that is part of another variable (as an array or structure element) must not appear in a PRIVATE clause.
A variable that is private within a parallel region, or that appears in the REDUCTION clause of a PARALLEL construct, must not appear in a LASTPRIVATE clause on a worksharing construct if any of the corresponding worksharing regions ever binds to any of the corresponding parallel regions.
A variable that appears in a LASTPRIVATE clause must be definable.
An original variable with the ALLOCATABLE attribute must be in the allocated state at entry to the construct containing the LASTPRIVATE clause. The variable in the sequentially last iteration or lexically last section must be in the allocated state upon exit from that iteration or section with the same bounds as the corresponding original variable.
Assumed-size arrays must not appear in a PRIVATE clause.
Variables that appear in NAMELIST statements, in variable format expressions, and in expressions for statement function definitions, must not appear in a PRIVATE clause.
If a list item appears in both the FIRSTPRIVATE and LASTPRIVATE clauses, the update required for LASTPRIVATE occurs after all of the initializations for FIRSTPRIVATE.
If a variable appears in both FIRSTPRIVATE and LASTPRIVATE clauses, the update required for LASTPRIVATE occurs after all initializations for FIRSTPRIVATE.
If a variable appears in a LASTPRIVATE clause on a combined construct for which the first construct is TARGET, it is treated as if it had appeared in a MAP clause with a map-type of FROM.
Example
Consider the following:
!$OMP DO PRIVATE(I) LASTPRIVATE(B)
DO I = 1, 1000
B = I
ENDDO
!$OMP END DO
In this case, after the construct is exited, variable B has the value 1000.
Consider the following:
!$OMP SECTIONS LASTPRIVATE(B)
!$OMP SECTION
B = 2
!$OMP SECTION
B = 4
!$OMP SECTION
D = 6
!$OMP END SECTIONS
In this case the thread that executes the lexically last SECTION updates the original variable B to have a value of 4. However, variable D was not specified in the LASTPRIVATE clause, so it has an undefined value after the construct is exited.
Consider the following example:
P = 0
!$OMP DO PRIVATE(I), FIRSTPRIVATE(P), LASTPRIVATE(CONDITIONAL:P)
DO I = 1, 1000
IF (A(I) .EQ. B) THEN
P = I
EXIT
END IF
ENDDO
!$OMP END DO
After the loop, P will be the index of the first element of A to match B; if no match is found, P will be zero.