10.8. lastprivate Clause#

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 in a lastprivate clause so that the values of the variables are the same as when the loop is executed sequentially.

//%compiler: clang
//%cflags: -fopenmp

/*
* name: lastprivate.1
* type: C
*/
void lastpriv (int n, float *a, float *b)
{
  int i;

  #pragma omp parallel
  {
    #pragma omp for lastprivate(i)
    for (i=0; i<n-1; i++)
      a[i] = b[i] + b[i+1];
  }

  a[i]=b[i];      /* i == n-1 here */
}
!!%compiler: gfortran
!!%cflags: -fopenmp

! name: lastprivate.1
! type: F-fixed
      SUBROUTINE LASTPRIV(N, A, B)

        INTEGER N
        REAL A(*), B(*)
        INTEGER I
!$OMP PARALLEL
!$OMP DO LASTPRIVATE(I)

        DO I=1,N-1
          A(I) = B(I) + B(I+1)
        ENDDO

!$OMP END PARALLEL
        A(I) = B(I)      ! I has the value of N here

      END SUBROUTINE LASTPRIV

The next example illustrates the use of the conditional modifier in a lastprivate clause to return the last value when it may not come from the last iteration of a loop. That is, users can preserve the serial equivalence semantics of the loop. The conditional lastprivate ensures the final value of the variable after the loop is as if the loop iterations were executed in a sequential order.

//%compiler: clang
//%cflags: -fopenmp

/*
* name: lastprivate.2
* type: C
* version: omp_5.0
*/
#include <math.h>

float condlastprivate(float *a, int n)
{
   float x = 0.0f;

   #pragma omp parallel for simd lastprivate(conditional: x)
   for (int k = 0; k < n; k++) {
      if (a[k] < 108.5 || a[k] > 208.5) {
         x = sinf(a[k]);
      }
   }

   return x;
}
!!%compiler: gfortran
!!%cflags: -fopenmp

! name: lastprivate.2
! type: F-free
! version: omp_5.0
function condlastprivate(a, n) result(x)
   implicit none
   real a(*), x
   integer n, k

   x = 0.0

   !$omp parallel do simd lastprivate(conditional: x)
   do k = 1, n
      if (a(k) < 108.5 .or. a(k) > 208.5) then
         x = sin(a(k))
      endif
   end do

end function condlastprivate