masked Construct
3.14. masked Construct#
The following example demonstrates the masked construct. In the example, the primary thread (thread number 0) keeps track of how many iterations have been executed and prints out a progress report in the iteration loop. The other threads skip the masked region without waiting. The filter clause can be used to specify a thread number other than the primary thread to execute a structured block, as illustrated by the second masked construct after the iteration loop. If the thread specified in a filter clause does not exist in the team then the structured block is not executed by any thread.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: masked.1
* type: C
* version: omp_5.1
*/
#include <stdio.h>
extern float average(float,float,float);
void masked_example( float* x, float* xold, int n, float tol )
{
int c, i, toobig;
float error, y;
c = 0;
#pragma omp parallel
{
do {
#pragma omp for private(i)
for( i = 1; i < n-1; ++i ){
xold[i] = x[i];
}
#pragma omp single
{
toobig = 0;
}
#pragma omp for private(i,y,error) reduction(+:toobig)
for( i = 1; i < n-1; ++i ){
y = x[i];
x[i] = average( xold[i-1], x[i], xold[i+1] );
error = y - x[i];
if( error > tol || error < -tol ) ++toobig;
}
#pragma omp masked // primary thread (thread 0)
{
++c;
printf( "iteration %d, toobig=%d\n", c, toobig );
}
} while( toobig > 0 );
#pragma omp barrier
#pragma omp masked filter(1) // thread 1
{
// The printf statement will not be executed
// if the number of threads is less than 2.
printf( "total number of iterations = %d\n", c );
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: masked.1
! type: F-fixed
! version: omp_5.1
SUBROUTINE MASKED_EXAMPLE( X, XOLD, N, TOL )
REAL X(*), XOLD(*), TOL
INTEGER N
INTEGER C, I, TOOBIG
REAL ERROR, Y, AVERAGE
EXTERNAL AVERAGE
C = 0
TOOBIG = 1
!$OMP PARALLEL
DO WHILE( TOOBIG > 0 )
!$OMP DO PRIVATE(I)
DO I = 2, N-1
XOLD(I) = X(I)
ENDDO
!$OMP SINGLE
TOOBIG = 0
!$OMP END SINGLE
!$OMP DO PRIVATE(I,Y,ERROR), REDUCTION(+:TOOBIG)
DO I = 2, N-1
Y = X(I)
X(I) = AVERAGE( XOLD(I-1), X(I), XOLD(I+1) )
ERROR = Y-X(I)
IF( ERROR > TOL .OR. ERROR < -TOL ) TOOBIG = TOOBIG+1
ENDDO
!$OMP MASKED ! primary thread (thread 0)
C = C + 1
PRINT *, 'Iteration ', C, 'TOOBIG=', TOOBIG
!$OMP END MASKED
ENDDO
!$OMP BARRIER
!$OMP MASKED FILTER(1) ! thread 1
! The print statement will not be executed
! if the number of threads is less than 2.
PRINT *, 'Total number of iterations =', C
!$OMP END MASKED
!$OMP END PARALLEL
END SUBROUTINE MASKED_EXAMPLE