MODULE omp_para INTEGER,SAVE :: omp_size INTEGER,SAVE :: omp_rank !$OMP THREADPRIVATE(omp_rank) LOGICAL,SAVE :: omp_first LOGICAL,SAVE :: omp_last LOGICAL,SAVE :: omp_master !$OMP THREADPRIVATE(omp_first, omp_last,omp_master) INTEGER,SAVE :: ll_begin INTEGER,SAVE :: ll_beginp1 INTEGER,SAVE :: ll_end INTEGER,SAVE :: ll_endm1 INTEGER,SAVE :: ll_endp1 !$OMP THREADPRIVATE(ll_begin,ll_beginp1,ll_end,ll_endm1,ll_endp1) LOGICAL,SAVE :: using_openmp LOGICAL,PARAMETER :: omp_by_domain=.TRUE. CONTAINS SUBROUTINE init_omp_para USE grid_param #ifdef CPP_USING_OMP USE omp_lib #endif IMPLICIT NONE INTEGER :: ll_nb,i #ifdef CPP_USING_OMP using_openmp=.TRUE. #else using_openmp=.FALSE. #endif IF (using_openmp) THEN !$OMP PARALLEL PRIVATE(ll_nb,i) !$OMP MASTER #ifdef CPP_USING_OMP omp_size=OMP_GET_NUM_THREADS() #endif !$OMP END MASTER !$OMP BARRIER #ifdef CPP_USING_OMP omp_rank=OMP_GET_THREAD_NUM() #endif IF (omp_by_domain) THEN omp_first=.TRUE. omp_last=.TRUE. IF (omp_rank==0) THEN omp_master=.TRUE. ELSE omp_master=.FALSE. ENDIF ll_begin=1 ll_beginp1=2 ll_end=llm ll_endm1=llm-1 ll_endp1=llm+1 ELSE omp_first=.FALSE. omp_last=.FALSE. omp_master=.FALSE. IF (omp_rank==0) THEN omp_first=.TRUE. omp_master=.TRUE. ENDIF IF (omp_rank==omp_size-1) omp_last=.TRUE. ll_end=0 DO i=0,omp_rank ll_begin=ll_end+1 ll_nb=llm/omp_size IF (MOD(llm,omp_size)>i) ll_nb=ll_nb+1 ll_end=ll_begin+ll_nb-1 ENDDO ll_beginp1=ll_begin ll_endp1=ll_end ll_endm1=ll_end IF (omp_first) ll_beginp1=ll_begin+1 IF (omp_last) ll_endp1=ll_endp1+1 IF (omp_last) ll_endm1=ll_endm1-1 ENDIF !$OMP END PARALLEL ELSE omp_size=1 omp_rank=0 omp_first=.TRUE. omp_last=.TRUE. omp_master=.TRUE. ll_begin=1 ll_beginp1=2 ll_end=llm ll_endm1=llm-1 ll_endp1=llm+1 ENDIF END SUBROUTINE init_omp_para FUNCTION omp_in_parallel() #ifdef CPP_USING_OMP USE omp_lib, ONLY : omp_in_parallel_=>omp_in_parallel #endif IMPLICIT NONE LOGICAL :: omp_in_parallel #ifdef CPP_USING_OMP omp_in_parallel=omp_in_parallel_() #else omp_in_parallel=.FALSE. #endif END FUNCTION omp_in_parallel END MODULE omp_para