OpenMP Directives: THREADPRIVATE Directive

Purpose:

The THREADPRIVATE directive is used to make global file scope variables (C/C++) or common blocks (Fortran) local and persistent to a thread through the execution of multiple parallel regions.

Format:

Fortran

!$OMP THREADPRIVATE (/cb/, ...)  cb is the name of a common block 

C/C++

#pragma omp threadprivate  (list) 

Notes:

The directive must appear after the declaration of listed variables/common blocks. Each thread then gets its own copy of the variable/common block, so data written by one thread is not visible to other threads. For example:

Example:

Fortran - THREADPRIVATE Directive Example

      PROGRAM THREADPRIV
 
      INTEGER A, B, I, TID, OMP_GET_THREAD_NUM
      REAL*4 X
      COMMON /C1/ A
 
!$OMP THREADPRIVATE(/C1/, X) 
 
C     Explicitly turn off dynamic threads
      CALL OMP_SET_DYNAMIC(.FALSE.)
 
      PRINT *, '1st Parallel Region:'
!$OMP PARALLEL PRIVATE(B, TID) 
      TID = OMP_GET_THREAD_NUM()
      A = TID
      B = TID
      X = 1.1 * TID + 1.0
      PRINT *, 'Thread',TID,':   A,B,X=',A,B,X
!$OMP END PARALLEL 
 
      PRINT *, '************************************'
      PRINT *, 'Master thread doing serial work here'
      PRINT *, '************************************'
 
      PRINT *, '2nd Parallel Region: '
!$OMP PARALLEL PRIVATE(TID) 
      TID = OMP_GET_THREAD_NUM()
      PRINT *, 'Thread',TID,':   A,B,X=',A,B,X
!$OMP END PARALLEL 
 
      END

Output:

 1st Parallel Region:
 Thread 0 :   A,B,X= 0 0 1.000000000
 Thread 1 :   A,B,X= 1 1 2.099999905
 Thread 3 :   A,B,X= 3 3 4.300000191
 Thread 2 :   A,B,X= 2 2 3.200000048
 ************************************
 Master thread doing serial work here
 ************************************
 2nd Parallel Region: 
 Thread 0 :   A,B,X= 0 0 1.000000000
 Thread 2 :   A,B,X= 2 0 3.200000048
 Thread 3 :   A,B,X= 3 0 4.300000191
 Thread 1 :   A,B,X= 1 0 2.099999905

C/C++ - threadprivate Directive Example

#include <omp.h>
 
int  a, b, i, tid;
float x;

#pragma omp threadprivate(a, x)
 
main ()  {
 
/* Explicitly turn off dynamic threads */
  omp_set_dynamic(0); 

  printf("1st Parallel Region:\n");
#pragma omp parallel private(b,tid)
  {
  tid = omp_get_thread_num();
  a = tid;
  b = tid;
  x = 1.1 * tid +1.0;
  printf("Thread %d:   a,b,x= %d %d %f\n",tid,a,b,x);
  }  /* end of parallel section */
 
  printf("************************************\n");
  printf("Master thread doing serial work here\n");
  printf("************************************\n");
 
  printf("2nd Parallel Region:\n");
#pragma omp parallel private(tid)
  {
  tid = omp_get_thread_num();
  printf("Thread %d:   a,b,x= %d %d %f\n",tid,a,b,x);
  }  /* end of parallel section */

}

Output:

1st Parallel Region:
Thread 0:   a,b,x= 0 0 1.000000
Thread 2:   a,b,x= 2 2 3.200000
Thread 3:   a,b,x= 3 3 4.300000
Thread 1:   a,b,x= 1 1 2.100000
************************************
Master thread doing serial work here
************************************
2nd Parallel Region:
Thread 0:   a,b,x= 0 0 1.000000
Thread 3:   a,b,x= 3 0 4.300000
Thread 1:   a,b,x= 1 0 2.100000
Thread 2:   a,b,x= 2 0 3.200000

Restrictions: