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