!$Header$ MODULE lmdz_phys_omp_transfert PRIVATE REAL, PARAMETER :: grow_factor = 1.5 INTEGER, PARAMETER :: size_min = 1024 CHARACTER(LEN = size_min), SAVE :: buffer_c 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 CONTAINS 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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_data USE lmdz_phys_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 lmdz_phys_omp_transfert