! !$Header$ ! MODULE mod_phys_lmdz_omp_transfert PRIVATE REAL,PARAMETER :: grow_factor=1.5 INTEGER,PARAMETER :: size_min=1024 CHARACTER(LEN=size_min),SAVE :: buffer_c ! INTEGER,SAVE :: size_c=0 INTEGER,SAVE,ALLOCATABLE,DIMENSION(:) :: buffer_i INTEGER,SAVE :: size_i=0 REAL,SAVE,ALLOCATABLE,DIMENSION(:) :: buffer_r INTEGER,SAVE :: size_r=0 LOGICAL,SAVE,ALLOCATABLE,DIMENSION(:) :: buffer_l INTEGER,SAVE :: size_l=0 INTERFACE bcast_omp MODULE PROCEDURE bcast_omp_c, & bcast_omp_i,bcast_omp_i1,bcast_omp_i2,bcast_omp_i3,bcast_omp_i4, & bcast_omp_r,bcast_omp_r1,bcast_omp_r2,bcast_omp_r3,bcast_omp_r4, & bcast_omp_l,bcast_omp_l1,bcast_omp_l2,bcast_omp_l3,bcast_omp_l4 END INTERFACE INTERFACE scatter_omp MODULE PROCEDURE scatter_omp_i,scatter_omp_i1,scatter_omp_i2,scatter_omp_i3, & scatter_omp_r,scatter_omp_r1,scatter_omp_r2,scatter_omp_r3, & scatter_omp_l,scatter_omp_l1,scatter_omp_l2,scatter_omp_l3 END INTERFACE INTERFACE gather_omp MODULE PROCEDURE gather_omp_i,gather_omp_i1,gather_omp_i2,gather_omp_i3, & gather_omp_r,gather_omp_r1,gather_omp_r2,gather_omp_r3, & gather_omp_l,gather_omp_l1,gather_omp_l2,gather_omp_l3 END INTERFACE INTERFACE reduce_sum_omp MODULE PROCEDURE reduce_sum_omp_i,reduce_sum_omp_i1,reduce_sum_omp_i2,reduce_sum_omp_i3,reduce_sum_omp_i4, & reduce_sum_omp_r,reduce_sum_omp_r1,reduce_sum_omp_r2,reduce_sum_omp_r3,reduce_sum_omp_r4 END INTERFACE INTERFACE reduce_min_omp MODULE PROCEDURE reduce_min_omp_i,reduce_min_omp_i1,reduce_min_omp_i2,reduce_min_omp_i3,reduce_min_omp_i4, & reduce_min_omp_r,reduce_min_omp_r1,reduce_min_omp_r2,reduce_min_omp_r3,reduce_min_omp_r4 END INTERFACE PUBLIC bcast_omp,scatter_omp,gather_omp,reduce_sum_omp, reduce_min_omp, omp_barrier CONTAINS SUBROUTINE omp_barrier IMPLICIT NONE !$OMP BARRIER END SUBROUTINE omp_barrier SUBROUTINE check_buffer_i(buff_size) IMPLICIT NONE INTEGER :: buff_size !$OMP BARRIER !$OMP MASTER IF (buff_size>size_i) THEN IF (ALLOCATED(buffer_i)) DEALLOCATE(buffer_i) size_i=MAX(size_min,INT(grow_factor*buff_size)) ALLOCATE(buffer_i(size_i)) ENDIF !$OMP END MASTER !$OMP BARRIER END SUBROUTINE check_buffer_i SUBROUTINE check_buffer_r(buff_size) IMPLICIT NONE INTEGER :: buff_size !$OMP BARRIER !$OMP MASTER IF (buff_size>size_r) THEN IF (ALLOCATED(buffer_r)) DEALLOCATE(buffer_r) size_r=MAX(size_min,INT(grow_factor*buff_size)) ALLOCATE(buffer_r(size_r)) ENDIF !$OMP END MASTER !$OMP BARRIER END SUBROUTINE check_buffer_r SUBROUTINE check_buffer_l(buff_size) IMPLICIT NONE INTEGER :: buff_size !$OMP BARRIER !$OMP MASTER IF (buff_size>size_l) THEN IF (ALLOCATED(buffer_l)) DEALLOCATE(buffer_l) size_l=MAX(size_min,INT(grow_factor*buff_size)) ALLOCATE(buffer_l(size_l)) ENDIF !$OMP END MASTER !$OMP BARRIER END SUBROUTINE check_buffer_l !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! Definition des Broadcast --> 4D !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! -- Les chaine de charactère -- !! SUBROUTINE bcast_omp_c(var) IMPLICIT NONE CHARACTER(LEN=*),INTENT(INOUT) :: Var CALL bcast_omp_cgen(Var,len(Var),buffer_c) END SUBROUTINE bcast_omp_c !! -- Les entiers -- !! SUBROUTINE bcast_omp_i(var) IMPLICIT NONE INTEGER,INTENT(INOUT) :: Var INTEGER :: Var_tmp(1) Var_tmp(1)=Var CALL check_buffer_i(1) CALL bcast_omp_igen(Var_tmp,1,buffer_i) Var=Var_tmp(1) END SUBROUTINE bcast_omp_i SUBROUTINE bcast_omp_i1(var) IMPLICIT NONE INTEGER,INTENT(INOUT) :: Var(:) CALL check_buffer_i(size(Var)) CALL bcast_omp_igen(Var,size(Var),buffer_i) END SUBROUTINE bcast_omp_i1 SUBROUTINE bcast_omp_i2(var) IMPLICIT NONE INTEGER,INTENT(INOUT) :: Var(:,:) CALL check_buffer_i(size(Var)) CALL bcast_omp_igen(Var,size(Var),buffer_i) END SUBROUTINE bcast_omp_i2 SUBROUTINE bcast_omp_i3(var) IMPLICIT NONE INTEGER,INTENT(INOUT) :: Var(:,:,:) CALL check_buffer_i(size(Var)) CALL bcast_omp_igen(Var,size(Var),buffer_i) END SUBROUTINE bcast_omp_i3 SUBROUTINE bcast_omp_i4(var) IMPLICIT NONE INTEGER,INTENT(INOUT) :: Var(:,:,:,:) CALL check_buffer_i(size(Var)) CALL bcast_omp_igen(Var,size(Var),buffer_i) END SUBROUTINE bcast_omp_i4 !! -- Les reels -- !! SUBROUTINE bcast_omp_r(var) IMPLICIT NONE REAL,INTENT(INOUT) :: Var REAL :: Var_tmp(1) Var_tmp(1)=Var CALL check_buffer_r(1) CALL bcast_omp_rgen(Var_tmp,1,buffer_r) Var=Var_tmp(1) END SUBROUTINE bcast_omp_r SUBROUTINE bcast_omp_r1(var) IMPLICIT NONE REAL,INTENT(INOUT) :: Var(:) CALL check_buffer_r(size(Var)) CALL bcast_omp_rgen(Var,size(Var),buffer_r) END SUBROUTINE bcast_omp_r1 SUBROUTINE bcast_omp_r2(var) IMPLICIT NONE REAL,INTENT(INOUT) :: Var(:,:) CALL check_buffer_r(size(Var)) CALL bcast_omp_rgen(Var,size(Var),buffer_r) END SUBROUTINE bcast_omp_r2 SUBROUTINE bcast_omp_r3(var) IMPLICIT NONE REAL,INTENT(INOUT) :: Var(:,:,:) CALL check_buffer_r(size(Var)) CALL bcast_omp_rgen(Var,size(Var),buffer_r) END SUBROUTINE bcast_omp_r3 SUBROUTINE bcast_omp_r4(var) IMPLICIT NONE REAL,INTENT(INOUT) :: Var(:,:,:,:) CALL check_buffer_r(size(Var)) CALL bcast_omp_rgen(Var,size(Var),buffer_r) END SUBROUTINE bcast_omp_r4 !! -- Les booleans -- !! SUBROUTINE bcast_omp_l(var) IMPLICIT NONE LOGICAL,INTENT(INOUT) :: Var LOGICAL :: Var_tmp(1) Var_tmp(1)=Var CALL check_buffer_l(1) CALL bcast_omp_lgen(Var_tmp,1,buffer_l) Var=Var_tmp(1) END SUBROUTINE bcast_omp_l SUBROUTINE bcast_omp_l1(var) IMPLICIT NONE LOGICAL,INTENT(INOUT) :: Var(:) CALL check_buffer_l(size(Var)) CALL bcast_omp_lgen(Var,size(Var),buffer_l) END SUBROUTINE bcast_omp_l1 SUBROUTINE bcast_omp_l2(var) IMPLICIT NONE LOGICAL,INTENT(INOUT) :: Var(:,:) CALL check_buffer_l(size(Var)) CALL bcast_omp_lgen(Var,size(Var),buffer_l) END SUBROUTINE bcast_omp_l2 SUBROUTINE bcast_omp_l3(var) IMPLICIT NONE LOGICAL,INTENT(INOUT) :: Var(:,:,:) CALL check_buffer_l(size(Var)) CALL bcast_omp_lgen(Var,size(Var),buffer_l) END SUBROUTINE bcast_omp_l3 SUBROUTINE bcast_omp_l4(var) IMPLICIT NONE LOGICAL,INTENT(INOUT) :: Var(:,:,:,:) CALL check_buffer_l(size(Var)) CALL bcast_omp_lgen(Var,size(Var),buffer_l) END SUBROUTINE bcast_omp_l4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! Definition des Scatter --> 4D !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE scatter_omp_i(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL scatter_omp_igen(VarIn,Varout,1,buffer_i) END SUBROUTINE scatter_omp_i SUBROUTINE scatter_omp_i1(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL scatter_omp_igen(VarIn,Varout,Size(VarOut,2),buffer_i) END SUBROUTINE scatter_omp_i1 SUBROUTINE scatter_omp_i2(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL scatter_omp_igen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3),buffer_i) END SUBROUTINE scatter_omp_i2 SUBROUTINE scatter_omp_i3(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL scatter_omp_igen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3)*Size(VarOut,4),buffer_i) END SUBROUTINE scatter_omp_i3 SUBROUTINE scatter_omp_r(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:) :: VarIn REAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL scatter_omp_rgen(VarIn,Varout,1,buffer_r) END SUBROUTINE scatter_omp_r SUBROUTINE scatter_omp_r1(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL scatter_omp_rgen(VarIn,Varout,Size(VarOut,2),buffer_r) END SUBROUTINE scatter_omp_r1 SUBROUTINE scatter_omp_r2(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL scatter_omp_rgen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3),buffer_r) END SUBROUTINE scatter_omp_r2 SUBROUTINE scatter_omp_r3(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL scatter_omp_rgen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3)*Size(VarOut,4),buffer_r) END SUBROUTINE scatter_omp_r3 SUBROUTINE scatter_omp_l(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_l(size(VarIn)) CALL scatter_omp_lgen(VarIn,Varout,1,buffer_l) END SUBROUTINE scatter_omp_l SUBROUTINE scatter_omp_l1(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_l(size(VarIn)) CALL scatter_omp_lgen(VarIn,Varout,Size(VarOut,2),buffer_l) END SUBROUTINE scatter_omp_l1 SUBROUTINE scatter_omp_l2(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_l(size(VarIn)) CALL scatter_omp_lgen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3),buffer_l) END SUBROUTINE scatter_omp_l2 SUBROUTINE scatter_omp_l3(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_l(size(VarIn)) CALL scatter_omp_lgen(VarIn,Varout,Size(VarOut,2)*Size(VarOut,3)*Size(VarOut,4),buffer_l) END SUBROUTINE scatter_omp_l3 SUBROUTINE gather_omp_i(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_i(size(VarOut)) CALL gather_omp_igen(VarIn,Varout,1,buffer_i) END SUBROUTINE gather_omp_i SUBROUTINE gather_omp_i1(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_i(size(VarOut)) CALL gather_omp_igen(VarIn,Varout,Size(VarIn,2),buffer_i) END SUBROUTINE gather_omp_i1 SUBROUTINE gather_omp_i2(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_i(size(VarOut)) CALL gather_omp_igen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3),buffer_i) END SUBROUTINE gather_omp_i2 SUBROUTINE gather_omp_i3(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_i(size(VarOut)) CALL gather_omp_igen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3)*Size(VarIn,4),buffer_i) END SUBROUTINE gather_omp_i3 SUBROUTINE gather_omp_r(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:) :: VarIn REAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL gather_omp_rgen(VarIn,Varout,1) END SUBROUTINE gather_omp_r SUBROUTINE gather_omp_r1(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL gather_omp_rgen(VarIn,Varout,Size(VarIn,2)) END SUBROUTINE gather_omp_r1 SUBROUTINE gather_omp_r2(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL gather_omp_rgen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3)) END SUBROUTINE gather_omp_r2 SUBROUTINE gather_omp_r3(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL gather_omp_rgen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3)*Size(VarIn,4)) END SUBROUTINE gather_omp_r3 SUBROUTINE gather_omp_l(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_l(size(VarOut)) CALL gather_omp_lgen(VarIn,Varout,1,buffer_l) END SUBROUTINE gather_omp_l SUBROUTINE gather_omp_l1(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_l(size(VarOut)) CALL gather_omp_lgen(VarIn,Varout,Size(VarIn,2),buffer_l) END SUBROUTINE gather_omp_l1 SUBROUTINE gather_omp_l2(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_l(size(VarOut)) CALL gather_omp_lgen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3),buffer_l) END SUBROUTINE gather_omp_l2 SUBROUTINE gather_omp_l3(VarIn, VarOut) IMPLICIT NONE LOGICAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_l(size(VarOut)) CALL gather_omp_lgen(VarIn,Varout,Size(VarIn,2)*Size(VarIn,3)*Size(VarIn,4),buffer_l) END SUBROUTINE gather_omp_l3 SUBROUTINE reduce_sum_omp_i(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN) :: VarIn INTEGER,INTENT(OUT) :: VarOut INTEGER :: VarIn_tmp(1) INTEGER :: VarOut_tmp(1) VarIn_tmp(1)=VarIn CALL Check_buffer_i(1) CALL reduce_sum_omp_igen(VarIn_tmp,Varout_tmp,1,buffer_i) VarOut=VarOut_tmp(1) END SUBROUTINE reduce_sum_omp_i SUBROUTINE reduce_sum_omp_i1(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_sum_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_sum_omp_i1 SUBROUTINE reduce_sum_omp_i2(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_sum_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_sum_omp_i2 SUBROUTINE reduce_sum_omp_i3(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_sum_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_sum_omp_i3 SUBROUTINE reduce_sum_omp_i4(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_sum_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_sum_omp_i4 SUBROUTINE reduce_sum_omp_r(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN) :: VarIn REAL,INTENT(OUT) :: VarOut REAL :: VarIn_tmp(1) REAL :: VarOut_tmp(1) VarIn_tmp(1)=VarIn CALL Check_buffer_r(1) CALL reduce_sum_omp_rgen(VarIn_tmp,Varout_tmp,1,buffer_r) VarOut=VarOut_tmp(1) END SUBROUTINE reduce_sum_omp_r SUBROUTINE reduce_sum_omp_r1(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:) :: VarIn REAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_sum_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_sum_omp_r1 SUBROUTINE reduce_sum_omp_r2(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_sum_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_sum_omp_r2 SUBROUTINE reduce_sum_omp_r3(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_sum_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_sum_omp_r3 SUBROUTINE reduce_sum_omp_r4(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_sum_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_sum_omp_r4 SUBROUTINE reduce_min_omp_i(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN) :: VarIn INTEGER,INTENT(OUT) :: VarOut INTEGER :: VarIn_tmp(1) INTEGER :: VarOut_tmp(1) VarIn_tmp(1)=VarIn CALL Check_buffer_i(1) CALL reduce_min_omp_igen(VarIn_tmp,Varout_tmp,1,buffer_i) VarOut=VarOut_tmp(1) END SUBROUTINE reduce_min_omp_i SUBROUTINE reduce_min_omp_i1(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_min_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_min_omp_i1 SUBROUTINE reduce_min_omp_i2(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_min_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_min_omp_i2 SUBROUTINE reduce_min_omp_i3(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_min_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_min_omp_i3 SUBROUTINE reduce_min_omp_i4(VarIn, VarOut) IMPLICIT NONE INTEGER,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn INTEGER,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_i(size(VarIn)) CALL reduce_min_omp_igen(VarIn,Varout,Size(VarIn),buffer_i) END SUBROUTINE reduce_min_omp_i4 SUBROUTINE reduce_min_omp_r(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN) :: VarIn REAL,INTENT(OUT) :: VarOut REAL :: VarIn_tmp(1) REAL :: VarOut_tmp(1) VarIn_tmp(1)=VarIn CALL Check_buffer_r(1) CALL reduce_min_omp_rgen(VarIn_tmp,Varout_tmp,1,buffer_r) VarOut=VarOut_tmp(1) END SUBROUTINE reduce_min_omp_r SUBROUTINE reduce_min_omp_r1(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:) :: VarIn REAL,INTENT(OUT),DIMENSION(:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_min_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_min_omp_r1 SUBROUTINE reduce_min_omp_r2(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_min_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_min_omp_r2 SUBROUTINE reduce_min_omp_r3(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_min_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_min_omp_r3 SUBROUTINE reduce_min_omp_r4(VarIn, VarOut) IMPLICIT NONE REAL,INTENT(IN),DIMENSION(:,:,:,:) :: VarIn REAL,INTENT(OUT),DIMENSION(:,:,:,:) :: VarOut CALL Check_buffer_r(size(VarIn)) CALL reduce_min_omp_rgen(VarIn,Varout,Size(VarIn),buffer_r) END SUBROUTINE reduce_min_omp_r4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! LES ROUTINES GENERIQUES ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE bcast_omp_cgen(Var,Nb,Buff) IMPLICIT NONE CHARACTER(LEN=*),INTENT(INOUT) :: Var CHARACTER(LEN=*),INTENT(INOUT) :: Buff INTEGER,INTENT(IN) :: Nb INTEGER :: i !$OMP MASTER Buff=Var !$OMP END MASTER !$OMP BARRIER DO i=1,Nb Var=Buff ENDDO !$OMP BARRIER END SUBROUTINE bcast_omp_cgen SUBROUTINE bcast_omp_igen(Var,Nb,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: Nb INTEGER,DIMENSION(Nb),INTENT(INOUT) :: Var INTEGER,DIMENSION(Nb),INTENT(INOUT) :: Buff INTEGER :: i !$OMP MASTER DO i=1,Nb Buff(i)=Var(i) ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,Nb Var(i)=Buff(i) ENDDO !$OMP BARRIER END SUBROUTINE bcast_omp_igen SUBROUTINE bcast_omp_rgen(Var,Nb,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: Nb REAL,DIMENSION(Nb),INTENT(INOUT) :: Var REAL,DIMENSION(Nb),INTENT(INOUT) :: Buff INTEGER :: i !$OMP MASTER DO i=1,Nb Buff(i)=Var(i) ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,Nb Var(i)=Buff(i) ENDDO !$OMP BARRIER END SUBROUTINE bcast_omp_rgen SUBROUTINE bcast_omp_lgen(Var,Nb,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: Nb LOGICAL,DIMENSION(Nb),INTENT(INOUT) :: Var LOGICAL,DIMENSION(Nb),INTENT(INOUT) :: Buff INTEGER :: i !$OMP MASTER DO i=1,Nb Buff(i)=Var(i) ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,Nb Var(i)=Buff(i) ENDDO !$OMP BARRIER END SUBROUTINE bcast_omp_lgen SUBROUTINE scatter_omp_igen(VarIn,VarOut,dimsize,Buff) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize INTEGER,INTENT(IN),DIMENSION(klon_mpi,dimsize) :: VarIn INTEGER,INTENT(OUT),DIMENSION(klon_omp,dimsize) :: VarOut INTEGER,INTENT(INOUT),DIMENSION(klon_mpi,dimsize) :: Buff INTEGER :: i,ij !$OMP MASTER DO i=1,dimsize DO ij=1,klon_mpi Buff(ij,i)=VarIn(ij,i) ENDDO ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,dimsize DO ij=1,klon_omp VarOut(ij,i)=Buff(klon_omp_begin-1+ij,i) ENDDO ENDDO !$OMP BARRIER END SUBROUTINE scatter_omp_igen SUBROUTINE scatter_omp_rgen(VarIn,VarOut,dimsize,Buff) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize REAL,INTENT(IN),DIMENSION(klon_mpi,dimsize) :: VarIn REAL,INTENT(OUT),DIMENSION(klon_omp,dimsize) :: VarOut REAL,INTENT(INOUT),DIMENSION(klon_mpi,dimsize) :: Buff INTEGER :: i,ij !$OMP MASTER DO i=1,dimsize DO ij=1,klon_mpi Buff(ij,i)=VarIn(ij,i) ENDDO ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,dimsize DO ij=1,klon_omp VarOut(ij,i)=Buff(klon_omp_begin-1+ij,i) ENDDO ENDDO !$OMP BARRIER END SUBROUTINE scatter_omp_rgen SUBROUTINE scatter_omp_lgen(VarIn,VarOut,dimsize,Buff) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize LOGICAL,INTENT(IN),DIMENSION(klon_mpi,dimsize) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(klon_omp,dimsize) :: VarOut LOGICAL,INTENT(INOUT),DIMENSION(klon_mpi,dimsize) :: Buff INTEGER :: i,ij !$OMP MASTER DO i=1,dimsize DO ij=1,klon_mpi Buff(ij,i)=VarIn(ij,i) ENDDO ENDDO !$OMP END MASTER !$OMP BARRIER DO i=1,dimsize DO ij=1,klon_omp VarOut(ij,i)=Buff(klon_omp_begin-1+ij,i) ENDDO ENDDO !$OMP BARRIER END SUBROUTINE scatter_omp_lgen SUBROUTINE gather_omp_igen(VarIn,VarOut,dimsize,Buff) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize INTEGER,INTENT(IN),DIMENSION(klon_omp,dimsize) :: VarIn INTEGER,INTENT(OUT),DIMENSION(klon_mpi,dimsize) :: VarOut INTEGER,INTENT(INOUT),DIMENSION(klon_mpi,dimsize) :: Buff INTEGER :: i,ij DO i=1,dimsize DO ij=1,klon_omp Buff(klon_omp_begin-1+ij,i)=VarIn(ij,i) ENDDO ENDDO !$OMP BARRIER !$OMP MASTER DO i=1,dimsize DO ij=1,klon_mpi VarOut(ij,i)=Buff(ij,i) ENDDO ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE gather_omp_igen SUBROUTINE gather_omp_rgen(VarIn,VarOut,dimsize) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize REAL,INTENT(IN),DIMENSION(klon_omp,dimsize) :: VarIn REAL,INTENT(OUT),DIMENSION(klon_mpi,dimsize),TARGET :: VarOut REAL, POINTER, SAVE :: Varout_ptr(:,:) ! Shared between threads NOT THREADPRIVATE INTEGER :: i,ij !$omp master Varout_ptr => VarOut !$omp end master !$omp barrier DO i=1,dimsize DO ij=1,klon_omp Varout_ptr(klon_omp_begin-1+ij,i)=VarIn(ij,i) ENDDO ENDDO !$omp barrier END SUBROUTINE gather_omp_rgen SUBROUTINE gather_omp_lgen(VarIn,VarOut,dimsize,Buff) USE mod_phys_lmdz_omp_data USE mod_phys_lmdz_mpi_data, ONLY : klon_mpi IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize LOGICAL,INTENT(IN),DIMENSION(klon_omp,dimsize) :: VarIn LOGICAL,INTENT(OUT),DIMENSION(klon_mpi,dimsize) :: VarOut LOGICAL,INTENT(INOUT),DIMENSION(klon_mpi,dimsize) :: Buff INTEGER :: i,ij DO i=1,dimsize DO ij=1,klon_omp Buff(klon_omp_begin-1+ij,i)=VarIn(ij,i) ENDDO ENDDO !$OMP BARRIER !$OMP MASTER DO i=1,dimsize DO ij=1,klon_mpi VarOut(ij,i)=Buff(ij,i) ENDDO ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE gather_omp_lgen SUBROUTINE reduce_sum_omp_igen(VarIn,VarOut,dimsize,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize INTEGER,INTENT(IN),DIMENSION(dimsize) :: VarIn INTEGER,INTENT(OUT),DIMENSION(dimsize) :: VarOut INTEGER,INTENT(INOUT),DIMENSION(dimsize) :: Buff INTEGER :: i !$OMP MASTER Buff(:)=0 !$OMP END MASTER !$OMP BARRIER !$OMP CRITICAL DO i=1,dimsize Buff(i)=Buff(i)+VarIn(i) ENDDO !$OMP END CRITICAL !$OMP BARRIER !$OMP MASTER DO i=1,dimsize VarOut(i)=Buff(i) ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE reduce_sum_omp_igen SUBROUTINE reduce_sum_omp_rgen(VarIn,VarOut,dimsize,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize REAL,INTENT(IN),DIMENSION(dimsize) :: VarIn REAL,INTENT(OUT),DIMENSION(dimsize) :: VarOut REAL,INTENT(INOUT),DIMENSION(dimsize) :: Buff INTEGER :: i !$OMP MASTER Buff(:)=0 !$OMP END MASTER !$OMP BARRIER !$OMP CRITICAL DO i=1,dimsize Buff(i)=Buff(i)+VarIn(i) ENDDO !$OMP END CRITICAL !$OMP BARRIER !$OMP MASTER DO i=1,dimsize VarOut(i)=Buff(i) ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE reduce_sum_omp_rgen SUBROUTINE reduce_min_omp_igen(VarIn,VarOut,dimsize,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize INTEGER,INTENT(IN),DIMENSION(dimsize) :: VarIn INTEGER,INTENT(OUT),DIMENSION(dimsize) :: VarOut INTEGER,INTENT(INOUT),DIMENSION(dimsize) :: Buff INTEGER :: i INTEGER :: var !$OMP MASTER Buff(:)=HUGE(var) !$OMP END MASTER !$OMP BARRIER !$OMP CRITICAL DO i=1,dimsize Buff(i)=MIN(Buff(i),VarIn(i)) ENDDO !$OMP END CRITICAL !$OMP BARRIER !$OMP MASTER DO i=1,dimsize VarOut(i)=Buff(i) ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE reduce_min_omp_igen SUBROUTINE reduce_min_omp_rgen(VarIn,VarOut,dimsize,Buff) IMPLICIT NONE INTEGER,INTENT(IN) :: dimsize REAL,INTENT(IN),DIMENSION(dimsize) :: VarIn REAL,INTENT(OUT),DIMENSION(dimsize) :: VarOut REAL,INTENT(INOUT),DIMENSION(dimsize) :: Buff INTEGER :: i REAL :: var !$OMP MASTER Buff(:)=HUGE(var) !$OMP END MASTER !$OMP BARRIER !$OMP CRITICAL DO i=1,dimsize Buff(i)=MIN(Buff(i),VarIn(i)) ENDDO !$OMP END CRITICAL !$OMP BARRIER !$OMP MASTER DO i=1,dimsize VarOut(i)=Buff(i) ENDDO !$OMP END MASTER !$OMP BARRIER END SUBROUTINE reduce_min_omp_rgen END MODULE mod_phys_lmdz_omp_transfert