lastprivate Clause
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