Intel® Fortran Compiler 18.0 Developer Guide and Reference

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.

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:

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:

NOTE

If a variable appears in both FIRSTPRIVATE and LASTPRIVATE clauses, the update required for LASTPRIVATE occurs after all initializations for FIRSTPRIVATE.

NOTE

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.

See Also