Using threadprivate and private of openMP

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.

The PRIVATE clause declares variables in its list to be private to each thread.

When developing with openMP, please make sure to keep the declaration of threadprivate/private variables be consistent during the execution. You should not using inconsistent declaration in different subroutines inside a same parallel block.

An example different combinations are attached for demonstration.

In the attached example, the declaration is correct for:

common block /MSP/;

variable SP0 in common block /SP/;

variable SP2 in common block /SP2/.

While the declaration is incorrect for:

common block /MP/;

variable SP1 in common block /SP/.

As we can see in the out.txt, we can always get consistent results for MSP1, SP0 and SP2 in main routine and subroutine for every threads.

But for SP1 and SP2, it is different in main routine and subroutine.

Useful links:

https://hpc-tutorials.llnl.gov/openmp/threadprivate_directive/

https://hpc-tutorials.llnl.gov/openmp/private_clause/

ifort -c main_threadprivate.f90 /Qauto /Qopenmp

ifort -c sub_thread.f90 /Qauto /Qopenmp

ifort -o threadprivate_test.exe main_threadprivate.obj sub_thread.obj

threadprivate_test.exe >out.txt


==================main_threadprivate.f90 ==========================

PROGRAM MAIN

! A DEMONSTRATION PROGRAM TO SHOW CORRECT AND INCORRECT WAY TO DECLARE

! THREADPRIVATE AND PRIVATE VARIABLES BY openMP.

!

    IMPLICIT NONE

    INTEGER MSP1,MP1,SP0,SP1,SP2,TTID,OMP_GET_THREAD_NUM,OMP_SET_NUM_THREADS

    !      MSP: MAIN+SUBROUTINE PRIVATE

    COMMON /MSP/MSP1

    COMMON /MP/MP1

    COMMON /SP/SP0,SP1

    COMMON /SP2/SP2

!$OMP THREADPRIVATE(/MSP/,/MP/)   

!

!INITIALIZATION

    MSP1 = 10

    MP1  = 20

    SP0  = 30

    SP1  = 31

    SP2  = 32

!

    TTID = OMP_GET_THREAD_NUM()

!$OMP CRITICAL

    WRITE(*,*) 'INITIAL VALUE IN MAIN MSP1=',MSP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN  MP1=', MP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP0=', SP0, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP1=', SP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP2=', SP2, 'TTID=',TTID

!$OMP END CRITICAL

!

    WRITE(*,*) 'PARALLEL BEGINS'

!$OMP PARALLEL COPYIN(/MSP/) PRIVATE(SP1) FIRSTPRIVATE(SP2)

!

!$OMP CRITICAL

    TTID = OMP_GET_THREAD_NUM()

    MSP1=MSP1+TTID

    MP1=MP1+TTID

    SP0=SP0+TTID

    SP1=SP1+TTID

    SP2=SP2+TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL, MSP1=',MSP1,'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  MP1=',MP1, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP0=',SP0, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP1=',SP1, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP2=',SP2, 'TTID=',TTID

      CALL SUB_THREAD(SP2)

!$OMP END CRITICAL

!

!$OMP END PARALLEL

STOP

END

==============sub_thread.f90================================

SUBROUTINE SUB_THREAD(SP2)

!

    IMPLICIT NONE   

    INTEGER MSP1,MP1,SP0,SP1,SP2,TTID,OMP_GET_THREAD_NUM

    !MSP MAIN+SUBROUTINE PRIVATE

    COMMON /MSP/MSP1

    COMMON /MP/MP1

    COMMON /SP/SP0,SP1

!$OMP THREADPRIVATE(/MSP/)

!

    TTID = OMP_GET_THREAD_NUM()

    WRITE(*,*) 'SUB_THREAD, MSP1=',MSP1,'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  MP1=',MP1, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP0=',SP0, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP1=',SP1, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP2=',SP2, 'TTID=',TTID

    WRITE(*,*) '                          '

RETURN

END

=====================out.txt===================================

INITIAL VALUE IN MAIN MSP1= 10 TTID= 0

INITIAL VALUE IN MAIN  MP1=          20 TTID=          0

INITIAL VALUE IN MAIN, SP0=          30 TTID=          0

INITIAL VALUE IN MAIN, SP1=          31 TTID=          0

INITIAL VALUE IN MAIN, SP2=          32 TTID=          0

PARALLEL BEGINS

MAIN AFTER PARALLEL, MSP1=          10 TTID=          0

MAIN AFTER PARALLEL,  MP1=          20 TTID=          0

MAIN AFTER PARALLEL,  SP0=          30 TTID=          0

MAIN AFTER PARALLEL,  SP1=          0 TTID=          0

MAIN AFTER PARALLEL,  SP2=          32 TTID=          0

SUB_THREAD, MSP1=          10 TTID=          0

SUB_THREAD,  MP1=          20 TTID=          0

SUB_THREAD,  SP0=          30 TTID=          0

SUB_THREAD,  SP1=          31 TTID=          0

SUB_THREAD,  SP2=          32 TTID=          0


MAIN AFTER PARALLEL, MSP1=          16 TTID=          6

MAIN AFTER PARALLEL,  MP1=          6 TTID=          6

MAIN AFTER PARALLEL,  SP0=          36 TTID=          6

MAIN AFTER PARALLEL,  SP1=          6 TTID=          6

MAIN AFTER PARALLEL,  SP2=          38 TTID=          6

SUB_THREAD, MSP1=          16 TTID=          6

SUB_THREAD,  MP1=          20 TTID=          6

SUB_THREAD,  SP0=          36 TTID=          6

SUB_THREAD,  SP1=          31 TTID=          6

SUB_THREAD,  SP2=          38 TTID=          6


MAIN AFTER PARALLEL, MSP1=          12 TTID=          2

MAIN AFTER PARALLEL,  MP1=          2 TTID=          2

MAIN AFTER PARALLEL,  SP0=          38 TTID=          2

MAIN AFTER PARALLEL,  SP1=          2 TTID=          2

MAIN AFTER PARALLEL,  SP2=          34 TTID=          2

SUB_THREAD, MSP1=          12 TTID=          2

SUB_THREAD,  MP1=          20 TTID=          2

SUB_THREAD,  SP0=          38 TTID=          2

SUB_THREAD,  SP1=          31 TTID=          2

SUB_THREAD,  SP2=          34 TTID=          2


MAIN AFTER PARALLEL, MSP1=          17 TTID=          7

MAIN AFTER PARALLEL,  MP1=          7 TTID=          7

MAIN AFTER PARALLEL,  SP0=          45 TTID=          7

MAIN AFTER PARALLEL,  SP1=          7 TTID=          7

MAIN AFTER PARALLEL,  SP2=          39 TTID=          7

SUB_THREAD, MSP1=          17 TTID=          7

SUB_THREAD,  MP1=          20 TTID=          7

SUB_THREAD,  SP0=          45 TTID=          7

SUB_THREAD,  SP1=          31 TTID=          7

SUB_THREAD,  SP2=          39 TTID=          7


MAIN AFTER PARALLEL, MSP1=          14 TTID=          4

MAIN AFTER PARALLEL,  MP1=          4 TTID=          4

MAIN AFTER PARALLEL,  SP0=          49 TTID=          4

MAIN AFTER PARALLEL,  SP1=          4 TTID=          4

MAIN AFTER PARALLEL,  SP2=          36 TTID=          4

SUB_THREAD, MSP1=          14 TTID=          4

SUB_THREAD,  MP1=          20 TTID=          4

SUB_THREAD,  SP0=          49 TTID=          4

SUB_THREAD,  SP1=          31 TTID=          4

SUB_THREAD,  SP2=          36 TTID=          4


MAIN AFTER PARALLEL, MSP1=          13 TTID=          3

MAIN AFTER PARALLEL,  MP1=          3 TTID=          3

MAIN AFTER PARALLEL,  SP0=          52 TTID=          3

MAIN AFTER PARALLEL,  SP1=          3 TTID=          3

MAIN AFTER PARALLEL,  SP2=          35 TTID=          3

SUB_THREAD, MSP1=          13 TTID=          3

SUB_THREAD,  MP1=          20 TTID=          3

SUB_THREAD,  SP0=          52 TTID=          3

SUB_THREAD,  SP1=          31 TTID=          3

SUB_THREAD,  SP2=          35 TTID=          3


MAIN AFTER PARALLEL, MSP1=          11 TTID=          1

MAIN AFTER PARALLEL,  MP1=          1 TTID=          1

MAIN AFTER PARALLEL,  SP0=          53 TTID=          1

MAIN AFTER PARALLEL,  SP1=          1 TTID=          1

MAIN AFTER PARALLEL,  SP2=          33 TTID=          1

SUB_THREAD, MSP1=          11 TTID=          1

SUB_THREAD,  MP1=          20 TTID=          1

SUB_THREAD,  SP0=          53 TTID=          1

SUB_THREAD,  SP1=          31 TTID=          1

SUB_THREAD,  SP2=          33 TTID=          1


MAIN AFTER PARALLEL, MSP1=          15 TTID=          5

MAIN AFTER PARALLEL,  MP1=          5 TTID=          5

MAIN AFTER PARALLEL,  SP0=          58 TTID=          5

MAIN AFTER PARALLEL,  SP1=          5 TTID=          5

MAIN AFTER PARALLEL,  SP2=          37 TTID=          5

SUB_THREAD, MSP1=          15 TTID=          5

SUB_THREAD,  MP1=          20 TTID=          5

SUB_THREAD,  SP0=          58 TTID=          5

SUB_THREAD,  SP1=          31 TTID=          5

SUB_THREAD,  SP2=          37 TTID=          5

======================END=============================

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容