LCOV - code coverage report
Current view: top level - src/mpiwrap - message_passing.fypp (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:d1f8d1b) Lines: 609 1100 55.4 %
Date: 2024-11-29 06:42:44 Functions: 119 660 18.0 %

          Line data    Source code
       1             : #!-------------------------------------------------------------------------------------------------!
       2             : #!   CP2K: A general program to perform molecular dynamics simulations                             !
       3             : #!   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                  !
       4             : #!                                                                                                 !
       5             : #!   SPDX-License-Identifier: GPL-2.0-or-later                                                     !
       6             : #!-------------------------------------------------------------------------------------------------!
       7             : #:mute
       8             :    #:set nametype1 = ['i', 'l', 'd', 'r', 'z', 'c']
       9             :    #:set type1 = ['INTEGER(KIND=int_4)', 'INTEGER(KIND=int_8)', 'REAL(kind=real_8)', 'REAL(kind=real_4)', 'COMPLEX(kind=real_8)', 'COMPLEX(kind=real_4)']
      10             :    #:set mpi_type1 = ['MPI_INTEGER', 'MPI_INTEGER8', 'MPI_DOUBLE_PRECISION', 'MPI_REAL', 'MPI_DOUBLE_COMPLEX', 'MPI_COMPLEX']
      11             :    #:set mpi_2type1 = ['MPI_2INTEGER', 'MPI_INTEGER8', 'MPI_2DOUBLE_PRECISION', 'MPI_2REAL', 'MPI_2DOUBLE_COMPLEX', 'MPI_2COMPLEX']
      12             :    #:set kind1 = ['int_4', 'int_8', 'real_8', 'real_4', 'real_8', 'real_4']
      13             :    #:set bytes1 = ['int_4_size','int_8_size','real_8_size','real_4_size','(2*real_8_size)','(2*real_4_size)']
      14             :    #:set handle1 = ['17', '19', '3', '1', '7', '5']
      15             :    #:set zero1 = ['0_int_4', '0_int_8', '0.0_real_8', '0.0_real_4', 'CMPLX(0.0, 0.0, real_8)', 'CMPLX(0.0, 0.0, real_4)']
      16             :    #:set one1 = ['1_int_4', '1_int_8', '1.0_real_8', '1.0_real_4', 'CMPLX(1.0, 0.0, real_8)', 'CMPLX(1.0, 0.0, real_4)']
      17             :    #:set inst_params = list(zip(nametype1, type1, mpi_type1, mpi_2type1, kind1, bytes1, handle1, zero1, one1))
      18             : #:endmute
      19             : #:for nametype1, type1, mpi_type1, mpi_2type1, kind1, bytes1, handle1, zero1, one1 in inst_params
      20             : ! **************************************************************************************************
      21             : !> \brief Shift around the data in msg
      22             : !> \param[in,out] msg         Rank-2 data to shift
      23             : !> \param[in] comm           message passing environment identifier
      24             : !> \param[in] displ_in        displacements (?)
      25             : !> \par Example
      26             : !>      msg will be moved from rank to rank+displ_in (in a circular way)
      27             : !> \par Limitations
      28             : !>      * displ_in will be 1 by default (others not tested)
      29             : !>      * the message array needs to be the same size on all processes
      30             : ! **************************************************************************************************
      31         950 :    SUBROUTINE mp_shift_${nametype1}$m(msg, comm, displ_in)
      32             : 
      33             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :)
      34             :       CLASS(mp_comm_type), INTENT(IN)                      :: comm
      35             :       INTEGER, INTENT(IN), OPTIONAL            :: displ_in
      36             : 
      37             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_shift_${nametype1}$m'
      38             : 
      39             :       INTEGER                                  :: handle, ierror
      40             : #if defined(__parallel)
      41             :       INTEGER                                  :: displ, left, &
      42             :                                                   msglen, myrank, nprocs, &
      43             :                                                   right, tag
      44             : #endif
      45             : 
      46         950 :       ierror = 0
      47         950 :       CALL mp_timeset(routineN, handle)
      48             : 
      49             : #if defined(__parallel)
      50         950 :       CALL mpi_comm_rank(comm%handle, myrank, ierror)
      51         950 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_comm_rank @ "//routineN)
      52         950 :       CALL mpi_comm_size(comm%handle, nprocs, ierror)
      53         950 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_comm_size @ "//routineN)
      54         950 :       IF (PRESENT(displ_in)) THEN
      55           0 :          displ = displ_in
      56             :       ELSE
      57             :          displ = 1
      58             :       END IF
      59         950 :       right = MODULO(myrank + displ, nprocs)
      60         950 :       left = MODULO(myrank - displ, nprocs)
      61         950 :       tag = 17
      62        2850 :       msglen = SIZE(msg)
      63             :       CALL mpi_sendrecv_replace(msg, msglen, ${mpi_type1}$, right, tag, left, tag, &
      64         950 :                                 comm%handle, MPI_STATUS_IGNORE, ierror)
      65         950 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_sendrecv_replace @ "//routineN)
      66         950 :       CALL add_perf(perf_id=7, count=1, msg_size=msglen*${bytes1}$)
      67             : #else
      68             :       MARK_USED(msg)
      69             :       MARK_USED(comm)
      70             :       MARK_USED(displ_in)
      71             : #endif
      72         950 :       CALL mp_timestop(handle)
      73             : 
      74         950 :    END SUBROUTINE mp_shift_${nametype1}$m
      75             : 
      76             : ! **************************************************************************************************
      77             : !> \brief Shift around the data in msg
      78             : !> \param[in,out] msg         Data to shift
      79             : !> \param[in] comm           message passing environment identifier
      80             : !> \param[in] displ_in        displacements (?)
      81             : !> \par Example
      82             : !>      msg will be moved from rank to rank+displ_in (in a circular way)
      83             : !> \par Limitations
      84             : !>      * displ_in will be 1 by default (others not tested)
      85             : !>      * the message array needs to be the same size on all processes
      86             : ! **************************************************************************************************
      87        2852 :    SUBROUTINE mp_shift_${nametype1}$ (msg, comm, displ_in)
      88             : 
      89             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:)
      90             :       CLASS(mp_comm_type), INTENT(IN)                      :: comm
      91             :       INTEGER, INTENT(IN), OPTIONAL            :: displ_in
      92             : 
      93             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_shift_${nametype1}$'
      94             : 
      95             :       INTEGER                                  :: handle, ierror
      96             : #if defined(__parallel)
      97             :       INTEGER                                  :: displ, left, &
      98             :                                                   msglen, myrank, nprocs, &
      99             :                                                   right, tag
     100             : #endif
     101             : 
     102        2852 :       ierror = 0
     103        2852 :       CALL mp_timeset(routineN, handle)
     104             : 
     105             : #if defined(__parallel)
     106        2852 :       CALL mpi_comm_rank(comm%handle, myrank, ierror)
     107        2852 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_comm_rank @ "//routineN)
     108        2852 :       CALL mpi_comm_size(comm%handle, nprocs, ierror)
     109        2852 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_comm_size @ "//routineN)
     110        2852 :       IF (PRESENT(displ_in)) THEN
     111           6 :          displ = displ_in
     112             :       ELSE
     113             :          displ = 1
     114             :       END IF
     115        2852 :       right = MODULO(myrank + displ, nprocs)
     116        2852 :       left = MODULO(myrank - displ, nprocs)
     117        2852 :       tag = 19
     118        2852 :       msglen = SIZE(msg)
     119             :       CALL mpi_sendrecv_replace(msg, msglen, ${mpi_type1}$, right, tag, left, &
     120        2852 :                                 tag, comm%handle, MPI_STATUS_IGNORE, ierror)
     121        2852 :       IF (ierror /= 0) CALL mp_stop(ierror, "mpi_sendrecv_replace @ "//routineN)
     122        2852 :       CALL add_perf(perf_id=7, count=1, msg_size=msglen*${bytes1}$)
     123             : #else
     124             :       MARK_USED(msg)
     125             :       MARK_USED(comm)
     126             :       MARK_USED(displ_in)
     127             : #endif
     128        2852 :       CALL mp_timestop(handle)
     129             : 
     130        2852 :    END SUBROUTINE mp_shift_${nametype1}$
     131             : 
     132             : ! **************************************************************************************************
     133             : !> \brief All-to-all data exchange, rank-1 data of different sizes
     134             : !> \param[in] sb              Data to send
     135             : !> \param[in] scount          Data counts for data sent to other processes
     136             : !> \param[in] sdispl          Respective data offsets for data sent to process
     137             : !> \param[in,out] rb          Buffer into which to receive data
     138             : !> \param[in] rcount          Data counts for data received from other
     139             : !>                            processes
     140             : !> \param[in] rdispl          Respective data offsets for data received from
     141             : !>                            other processes
     142             : !> \param[in] comm            Message passing environment identifier
     143             : !> \par MPI mapping
     144             : !>      mpi_alltoallv
     145             : !> \par Array sizes
     146             : !>      The scount, rcount, and the sdispl and rdispl arrays have a
     147             : !>      size equal to the number of processes.
     148             : !> \par Offsets
     149             : !>      Values in sdispl and rdispl start with 0.
     150             : ! **************************************************************************************************
     151       77446 :    SUBROUTINE mp_alltoall_${nametype1}$11v(sb, scount, sdispl, rb, rcount, rdispl, comm)
     152             : 
     153             :       ${type1}$, DIMENSION(:), INTENT(IN), CONTIGUOUS        :: sb
     154             :       INTEGER, DIMENSION(:), INTENT(IN), CONTIGUOUS        :: scount, sdispl
     155             :       ${type1}$, DIMENSION(:), INTENT(INOUT), CONTIGUOUS     :: rb
     156             :       INTEGER, DIMENSION(:), INTENT(IN), CONTIGUOUS        :: rcount, rdispl
     157             :       CLASS(mp_comm_type), INTENT(IN)                      :: comm
     158             : 
     159             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$11v'
     160             : 
     161             :       INTEGER                                  :: handle
     162             : #if defined(__parallel)
     163             :       INTEGER                                  :: ierr, msglen
     164             : #else
     165             :       INTEGER                                  :: i
     166             : #endif
     167             : 
     168       77446 :       CALL mp_timeset(routineN, handle)
     169             : 
     170             : #if defined(__parallel)
     171             :       CALL mpi_alltoallv(sb, scount, sdispl, ${mpi_type1}$, &
     172       77446 :                          rb, rcount, rdispl, ${mpi_type1}$, comm%handle, ierr)
     173       77446 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoallv @ "//routineN)
     174      387216 :       msglen = SUM(scount) + SUM(rcount)
     175       77446 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     176             : #else
     177             :       MARK_USED(comm)
     178             :       MARK_USED(scount)
     179             :       MARK_USED(sdispl)
     180             :       !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(i) SHARED(rcount,rdispl,sdispl,rb,sb)
     181             :       DO i = 1, rcount(1)
     182             :          rb(rdispl(1) + i) = sb(sdispl(1) + i)
     183             :       END DO
     184             : #endif
     185       77446 :       CALL mp_timestop(handle)
     186             : 
     187       77446 :    END SUBROUTINE mp_alltoall_${nametype1}$11v
     188             : 
     189             : ! **************************************************************************************************
     190             : !> \brief All-to-all data exchange, rank-2 data of different sizes
     191             : !> \param sb ...
     192             : !> \param scount ...
     193             : !> \param sdispl ...
     194             : !> \param rb ...
     195             : !> \param rcount ...
     196             : !> \param rdispl ...
     197             : !> \param comm ...
     198             : !> \par MPI mapping
     199             : !>      mpi_alltoallv
     200             : !> \note see mp_alltoall_${nametype1}$11v
     201             : ! **************************************************************************************************
     202     2663418 :    SUBROUTINE mp_alltoall_${nametype1}$22v(sb, scount, sdispl, rb, rcount, rdispl, comm)
     203             : 
     204             :       ${type1}$, DIMENSION(:, :), &
     205             :          INTENT(IN), CONTIGUOUS                             :: sb
     206             :       INTEGER, DIMENSION(:), INTENT(IN), CONTIGUOUS        :: scount, sdispl
     207             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, &
     208             :          INTENT(INOUT)                          :: rb
     209             :       INTEGER, DIMENSION(:), INTENT(IN), CONTIGUOUS        :: rcount, rdispl
     210             :       CLASS(mp_comm_type), INTENT(IN)                      :: comm
     211             : 
     212             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$22v'
     213             : 
     214             :       INTEGER                                  :: handle
     215             : #if defined(__parallel)
     216             :       INTEGER                                  :: ierr, msglen
     217             : #endif
     218             : 
     219     2663418 :       CALL mp_timeset(routineN, handle)
     220             : 
     221             : #if defined(__parallel)
     222             :       CALL mpi_alltoallv(sb, scount, sdispl, ${mpi_type1}$, &
     223     2663418 :                          rb, rcount, rdispl, ${mpi_type1}$, comm%handle, ierr)
     224     2663418 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoallv @ "//routineN)
     225    15980508 :       msglen = SUM(scount) + SUM(rcount)
     226     2663418 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*2*${bytes1}$)
     227             : #else
     228             :       MARK_USED(comm)
     229             :       MARK_USED(scount)
     230             :       MARK_USED(sdispl)
     231             :       MARK_USED(rcount)
     232             :       MARK_USED(rdispl)
     233             :       rb = sb
     234             : #endif
     235     2663418 :       CALL mp_timestop(handle)
     236             : 
     237     2663418 :    END SUBROUTINE mp_alltoall_${nametype1}$22v
     238             : 
     239             : ! **************************************************************************************************
     240             : !> \brief All-to-all data exchange, rank 1 arrays, equal sizes
     241             : !> \param[in] sb    array with data to send
     242             : !> \param[out] rb   array into which data is received
     243             : !> \param[in] count  number of elements to send/receive (product of the
     244             : !>                   extents of the first two dimensions)
     245             : !> \param[in] comm           Message passing environment identifier
     246             : !> \par Index meaning
     247             : !> \par The first two indices specify the data while the last index counts
     248             : !>      the processes
     249             : !> \par Sizes of ranks
     250             : !>      All processes have the same data size.
     251             : !> \par MPI mapping
     252             : !>      mpi_alltoall
     253             : ! **************************************************************************************************
     254      764328 :    SUBROUTINE mp_alltoall_${nametype1}$ (sb, rb, count, comm)
     255             : 
     256             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: sb
     257             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(OUT)       :: rb
     258             :       INTEGER, INTENT(IN)                      :: count
     259             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     260             : 
     261             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$'
     262             : 
     263             :       INTEGER                                  :: handle
     264             : #if defined(__parallel)
     265             :       INTEGER                                  :: ierr, msglen, np
     266             : #endif
     267             : 
     268      764328 :       CALL mp_timeset(routineN, handle)
     269             : 
     270             : #if defined(__parallel)
     271             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     272      764328 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     273      764328 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     274      764328 :       CALL mpi_comm_size(comm%handle, np, ierr)
     275      764328 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     276      764328 :       msglen = 2*count*np
     277      764328 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     278             : #else
     279             :       MARK_USED(count)
     280             :       MARK_USED(comm)
     281             :       rb = sb
     282             : #endif
     283      764328 :       CALL mp_timestop(handle)
     284             : 
     285      764328 :    END SUBROUTINE mp_alltoall_${nametype1}$
     286             : 
     287             : ! **************************************************************************************************
     288             : !> \brief All-to-all data exchange, rank-2 arrays, equal sizes
     289             : !> \param sb ...
     290             : !> \param rb ...
     291             : !> \param count ...
     292             : !> \param commp ...
     293             : !> \note see mp_alltoall_${nametype1}$
     294             : ! **************************************************************************************************
     295        5476 :    SUBROUTINE mp_alltoall_${nametype1}$22(sb, rb, count, comm)
     296             : 
     297             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(IN)     :: sb
     298             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(OUT)    :: rb
     299             :       INTEGER, INTENT(IN)                      :: count
     300             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     301             : 
     302             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$22'
     303             : 
     304             :       INTEGER                                  :: handle
     305             : #if defined(__parallel)
     306             :       INTEGER                                  :: ierr, msglen, np
     307             : #endif
     308             : 
     309        5476 :       CALL mp_timeset(routineN, handle)
     310             : 
     311             : #if defined(__parallel)
     312             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     313        5476 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     314        5476 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     315        5476 :       CALL mpi_comm_size(comm%handle, np, ierr)
     316        5476 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     317       16428 :       msglen = 2*SIZE(sb)*np
     318        5476 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     319             : #else
     320             :       MARK_USED(count)
     321             :       MARK_USED(comm)
     322             :       rb = sb
     323             : #endif
     324        5476 :       CALL mp_timestop(handle)
     325             : 
     326        5476 :    END SUBROUTINE mp_alltoall_${nametype1}$22
     327             : 
     328             : ! **************************************************************************************************
     329             : !> \brief All-to-all data exchange, rank-3 data with equal sizes
     330             : !> \param sb ...
     331             : !> \param rb ...
     332             : !> \param count ...
     333             : !> \param comm ...
     334             : !> \note see mp_alltoall_${nametype1}$
     335             : ! **************************************************************************************************
     336           0 :    SUBROUTINE mp_alltoall_${nametype1}$33(sb, rb, count, comm)
     337             : 
     338             :       ${type1}$, DIMENSION(:, :, :), CONTIGUOUS, INTENT(IN)  :: sb
     339             :       ${type1}$, DIMENSION(:, :, :), CONTIGUOUS, INTENT(OUT) :: rb
     340             :       INTEGER, INTENT(IN)                      :: count
     341             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     342             : 
     343             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$33'
     344             : 
     345             :       INTEGER                                  :: handle
     346             : #if defined(__parallel)
     347             :       INTEGER                                  :: ierr, msglen, np
     348             : #endif
     349             : 
     350           0 :       CALL mp_timeset(routineN, handle)
     351             : 
     352             : #if defined(__parallel)
     353             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     354           0 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     355           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     356           0 :       CALL mpi_comm_size(comm%handle, np, ierr)
     357           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     358           0 :       msglen = 2*count*np
     359           0 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     360             : #else
     361             :       MARK_USED(count)
     362             :       MARK_USED(comm)
     363             :       rb = sb
     364             : #endif
     365           0 :       CALL mp_timestop(handle)
     366             : 
     367           0 :    END SUBROUTINE mp_alltoall_${nametype1}$33
     368             : 
     369             : ! **************************************************************************************************
     370             : !> \brief All-to-all data exchange, rank 4 data, equal sizes
     371             : !> \param sb ...
     372             : !> \param rb ...
     373             : !> \param count ...
     374             : !> \param comm ...
     375             : !> \note see mp_alltoall_${nametype1}$
     376             : ! **************************************************************************************************
     377           0 :    SUBROUTINE mp_alltoall_${nametype1}$44(sb, rb, count, comm)
     378             : 
     379             :       ${type1}$, DIMENSION(:, :, :, :), CONTIGUOUS, &
     380             :          INTENT(IN)                             :: sb
     381             :       ${type1}$, DIMENSION(:, :, :, :), CONTIGUOUS, &
     382             :          INTENT(OUT)                            :: rb
     383             :       INTEGER, INTENT(IN)                      :: count
     384             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     385             : 
     386             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$44'
     387             : 
     388             :       INTEGER                                  :: handle
     389             : #if defined(__parallel)
     390             :       INTEGER                                  :: ierr, msglen, np
     391             : #endif
     392             : 
     393           0 :       CALL mp_timeset(routineN, handle)
     394             : 
     395             : #if defined(__parallel)
     396             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     397           0 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     398           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     399           0 :       CALL mpi_comm_size(comm%handle, np, ierr)
     400           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     401           0 :       msglen = 2*count*np
     402           0 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     403             : #else
     404             :       MARK_USED(count)
     405             :       MARK_USED(comm)
     406             :       rb = sb
     407             : #endif
     408           0 :       CALL mp_timestop(handle)
     409             : 
     410           0 :    END SUBROUTINE mp_alltoall_${nametype1}$44
     411             : 
     412             : ! **************************************************************************************************
     413             : !> \brief All-to-all data exchange, rank 5 data, equal sizes
     414             : !> \param sb ...
     415             : !> \param rb ...
     416             : !> \param count ...
     417             : !> \param comm ...
     418             : !> \note see mp_alltoall_${nametype1}$
     419             : ! **************************************************************************************************
     420           0 :    SUBROUTINE mp_alltoall_${nametype1}$55(sb, rb, count, comm)
     421             : 
     422             :       ${type1}$, DIMENSION(:, :, :, :, :), CONTIGUOUS, &
     423             :          INTENT(IN)                             :: sb
     424             :       ${type1}$, DIMENSION(:, :, :, :, :), CONTIGUOUS, &
     425             :          INTENT(OUT)                            :: rb
     426             :       INTEGER, INTENT(IN)                      :: count
     427             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     428             : 
     429             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$55'
     430             : 
     431             :       INTEGER                                  :: handle
     432             : #if defined(__parallel)
     433             :       INTEGER                                  :: ierr, msglen, np
     434             : #endif
     435             : 
     436           0 :       CALL mp_timeset(routineN, handle)
     437             : 
     438             : #if defined(__parallel)
     439             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     440           0 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     441           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     442           0 :       CALL mpi_comm_size(comm%handle, np, ierr)
     443           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     444           0 :       msglen = 2*count*np
     445           0 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     446             : #else
     447             :       MARK_USED(count)
     448             :       MARK_USED(comm)
     449             :       rb = sb
     450             : #endif
     451           0 :       CALL mp_timestop(handle)
     452             : 
     453           0 :    END SUBROUTINE mp_alltoall_${nametype1}$55
     454             : 
     455             : ! **************************************************************************************************
     456             : !> \brief All-to-all data exchange, rank-4 data to rank-5 data
     457             : !> \param sb ...
     458             : !> \param rb ...
     459             : !> \param count ...
     460             : !> \param comm ...
     461             : !> \note see mp_alltoall_${nametype1}$
     462             : !> \note User must ensure size consistency.
     463             : ! **************************************************************************************************
     464       12820 :    SUBROUTINE mp_alltoall_${nametype1}$45(sb, rb, count, comm)
     465             : 
     466             :       ${type1}$, DIMENSION(:, :, :, :), CONTIGUOUS, &
     467             :          INTENT(IN)                             :: sb
     468             :       ${type1}$, &
     469             :          DIMENSION(:, :, :, :, :), INTENT(OUT), CONTIGUOUS  :: rb
     470             :       INTEGER, INTENT(IN)                      :: count
     471             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     472             : 
     473             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$45'
     474             : 
     475             :       INTEGER                                  :: handle
     476             : #if defined(__parallel)
     477             :       INTEGER                                  :: ierr, msglen, np
     478             : #endif
     479             : 
     480       12820 :       CALL mp_timeset(routineN, handle)
     481             : 
     482             : #if defined(__parallel)
     483             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     484       12820 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     485       12820 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     486       12820 :       CALL mpi_comm_size(comm%handle, np, ierr)
     487       12820 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     488       12820 :       msglen = 2*count*np
     489       12820 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     490             : #else
     491             :       MARK_USED(count)
     492             :       MARK_USED(comm)
     493             :       rb = RESHAPE(sb, SHAPE(rb))
     494             : #endif
     495       12820 :       CALL mp_timestop(handle)
     496             : 
     497       12820 :    END SUBROUTINE mp_alltoall_${nametype1}$45
     498             : 
     499             : ! **************************************************************************************************
     500             : !> \brief All-to-all data exchange, rank-3 data to rank-4 data
     501             : !> \param sb ...
     502             : !> \param rb ...
     503             : !> \param count ...
     504             : !> \param comm ...
     505             : !> \note see mp_alltoall_${nametype1}$
     506             : !> \note User must ensure size consistency.
     507             : ! **************************************************************************************************
     508           2 :    SUBROUTINE mp_alltoall_${nametype1}$34(sb, rb, count, comm)
     509             : 
     510             :       ${type1}$, DIMENSION(:, :, :), CONTIGUOUS, &
     511             :          INTENT(IN)                             :: sb
     512             :       ${type1}$, DIMENSION(:, :, :, :), CONTIGUOUS, &
     513             :          INTENT(OUT)                            :: rb
     514             :       INTEGER, INTENT(IN)                      :: count
     515             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     516             : 
     517             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$34'
     518             : 
     519             :       INTEGER                                  :: handle
     520             : #if defined(__parallel)
     521             :       INTEGER                                  :: ierr, msglen, np
     522             : #endif
     523             : 
     524           2 :       CALL mp_timeset(routineN, handle)
     525             : 
     526             : #if defined(__parallel)
     527             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     528           2 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     529           2 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     530           2 :       CALL mpi_comm_size(comm%handle, np, ierr)
     531           2 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     532           2 :       msglen = 2*count*np
     533           2 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     534             : #else
     535             :       MARK_USED(count)
     536             :       MARK_USED(comm)
     537             :       rb = RESHAPE(sb, SHAPE(rb))
     538             : #endif
     539           2 :       CALL mp_timestop(handle)
     540             : 
     541           2 :    END SUBROUTINE mp_alltoall_${nametype1}$34
     542             : 
     543             : ! **************************************************************************************************
     544             : !> \brief All-to-all data exchange, rank-5 data to rank-4 data
     545             : !> \param sb ...
     546             : !> \param rb ...
     547             : !> \param count ...
     548             : !> \param comm ...
     549             : !> \note see mp_alltoall_${nametype1}$
     550             : !> \note User must ensure size consistency.
     551             : ! **************************************************************************************************
     552       12464 :    SUBROUTINE mp_alltoall_${nametype1}$54(sb, rb, count, comm)
     553             : 
     554             :       ${type1}$, &
     555             :          DIMENSION(:, :, :, :, :), CONTIGUOUS, INTENT(IN)   :: sb
     556             :       ${type1}$, DIMENSION(:, :, :, :), CONTIGUOUS, &
     557             :          INTENT(OUT)                            :: rb
     558             :       INTEGER, INTENT(IN)                      :: count
     559             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     560             : 
     561             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_alltoall_${nametype1}$54'
     562             : 
     563             :       INTEGER                                  :: handle
     564             : #if defined(__parallel)
     565             :       INTEGER                                  :: ierr, msglen, np
     566             : #endif
     567             : 
     568       12464 :       CALL mp_timeset(routineN, handle)
     569             : 
     570             : #if defined(__parallel)
     571             :       CALL mpi_alltoall(sb, count, ${mpi_type1}$, &
     572       12464 :                         rb, count, ${mpi_type1}$, comm%handle, ierr)
     573       12464 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_alltoall @ "//routineN)
     574       12464 :       CALL mpi_comm_size(comm%handle, np, ierr)
     575       12464 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_size @ "//routineN)
     576       12464 :       msglen = 2*count*np
     577       12464 :       CALL add_perf(perf_id=6, count=1, msg_size=msglen*${bytes1}$)
     578             : #else
     579             :       MARK_USED(count)
     580             :       MARK_USED(comm)
     581             :       rb = RESHAPE(sb, SHAPE(rb))
     582             : #endif
     583       12464 :       CALL mp_timestop(handle)
     584             : 
     585       12464 :    END SUBROUTINE mp_alltoall_${nametype1}$54
     586             : 
     587             : ! **************************************************************************************************
     588             : !> \brief Send one datum to another process
     589             : !> \param[in] msg             Scalar to send
     590             : !> \param[in] dest            Destination process
     591             : !> \param[in] tag             Transfer identifier
     592             : !> \param[in] comm             Message passing environment identifier
     593             : !> \par MPI mapping
     594             : !>      mpi_send
     595             : ! **************************************************************************************************
     596        1214 :    SUBROUTINE mp_send_${nametype1}$ (msg, dest, tag, comm)
     597             :       ${type1}$, INTENT(IN)                   :: msg
     598             :       INTEGER, INTENT(IN)                      :: dest, tag
     599             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     600             : 
     601             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_send_${nametype1}$'
     602             : 
     603             :       INTEGER                                  :: handle
     604             : #if defined(__parallel)
     605             :       INTEGER :: ierr, msglen
     606             : #endif
     607             : 
     608        1214 :       CALL mp_timeset(routineN, handle)
     609             : 
     610             : #if defined(__parallel)
     611        1214 :       msglen = 1
     612        1214 :       CALL mpi_send(msg, msglen, ${mpi_type1}$, dest, tag, comm%handle, ierr)
     613        1214 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_send @ "//routineN)
     614        1214 :       CALL add_perf(perf_id=13, count=1, msg_size=msglen*${bytes1}$)
     615             : #else
     616             :       MARK_USED(msg)
     617             :       MARK_USED(dest)
     618             :       MARK_USED(tag)
     619             :       MARK_USED(comm)
     620             :       ! only defined in parallel
     621             :       CPABORT("not in parallel mode")
     622             : #endif
     623        1214 :       CALL mp_timestop(handle)
     624        1214 :    END SUBROUTINE mp_send_${nametype1}$
     625             : 
     626             : ! **************************************************************************************************
     627             : !> \brief Send rank-1 data to another process
     628             : !> \param[in] msg             Rank-1 data to send
     629             : !> \param dest ...
     630             : !> \param tag ...
     631             : !> \param comm ...
     632             : !> \note see mp_send_${nametype1}$
     633             : ! **************************************************************************************************
     634      113458 :    SUBROUTINE mp_send_${nametype1}$v(msg, dest, tag, comm)
     635             :       ${type1}$, CONTIGUOUS, INTENT(IN)                                  :: msg(:)
     636             :       INTEGER, INTENT(IN)                                  :: dest, tag
     637             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     638             : 
     639             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_send_${nametype1}$v'
     640             : 
     641             :       INTEGER                                  :: handle
     642             : #if defined(__parallel)
     643             :       INTEGER :: ierr, msglen
     644             : #endif
     645             : 
     646      113458 :       CALL mp_timeset(routineN, handle)
     647             : 
     648             : #if defined(__parallel)
     649      113458 :       msglen = SIZE(msg)
     650      113458 :       CALL mpi_send(msg, msglen, ${mpi_type1}$, dest, tag, comm%handle, ierr)
     651      113458 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_send @ "//routineN)
     652      113458 :       CALL add_perf(perf_id=13, count=1, msg_size=msglen*${bytes1}$)
     653             : #else
     654             :       MARK_USED(msg)
     655             :       MARK_USED(dest)
     656             :       MARK_USED(tag)
     657             :       MARK_USED(comm)
     658             :       ! only defined in parallel
     659             :       CPABORT("not in parallel mode")
     660             : #endif
     661      113458 :       CALL mp_timestop(handle)
     662      113458 :    END SUBROUTINE mp_send_${nametype1}$v
     663             : 
     664             : ! **************************************************************************************************
     665             : !> \brief Send rank-2 data to another process
     666             : !> \param[in] msg             Rank-2 data to send
     667             : !> \param dest ...
     668             : !> \param tag ...
     669             : !> \param comm ...
     670             : !> \note see mp_send_${nametype1}$
     671             : ! **************************************************************************************************
     672           4 :    SUBROUTINE mp_send_${nametype1}$m2(msg, dest, tag, comm)
     673             :       ${type1}$, CONTIGUOUS, INTENT(IN)                                  :: msg(:, :)
     674             :       INTEGER, INTENT(IN)                                  :: dest, tag
     675             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     676             : 
     677             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_send_${nametype1}$m2'
     678             : 
     679             :       INTEGER                                  :: handle
     680             : #if defined(__parallel)
     681             :       INTEGER :: ierr, msglen
     682             : #endif
     683             : 
     684           4 :       CALL mp_timeset(routineN, handle)
     685             : 
     686             : #if defined(__parallel)
     687          12 :       msglen = SIZE(msg)
     688           4 :       CALL mpi_send(msg, msglen, ${mpi_type1}$, dest, tag, comm%handle, ierr)
     689           4 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_send @ "//routineN)
     690           4 :       CALL add_perf(perf_id=13, count=1, msg_size=msglen*${bytes1}$)
     691             : #else
     692             :       MARK_USED(msg)
     693             :       MARK_USED(dest)
     694             :       MARK_USED(tag)
     695             :       MARK_USED(comm)
     696             :       ! only defined in parallel
     697             :       CPABORT("not in parallel mode")
     698             : #endif
     699           4 :       CALL mp_timestop(handle)
     700           4 :    END SUBROUTINE mp_send_${nametype1}$m2
     701             : 
     702             : ! **************************************************************************************************
     703             : !> \brief Send rank-3 data to another process
     704             : !> \param[in] msg             Rank-3 data to send
     705             : !> \param dest ...
     706             : !> \param tag ...
     707             : !> \param comm ...
     708             : !> \note see mp_send_${nametype1}$
     709             : ! **************************************************************************************************
     710         258 :    SUBROUTINE mp_send_${nametype1}$m3(msg, dest, tag, comm)
     711             :       ${type1}$, CONTIGUOUS, INTENT(IN)                                  :: msg(:, :, :)
     712             :       INTEGER, INTENT(IN)                                  :: dest, tag
     713             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     714             : 
     715             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_send_${nametype1}m3'
     716             : 
     717             :       INTEGER                                  :: handle
     718             : #if defined(__parallel)
     719             :       INTEGER :: ierr, msglen
     720             : #endif
     721             : 
     722         258 :       CALL mp_timeset(routineN, handle)
     723             : 
     724             : #if defined(__parallel)
     725        1032 :       msglen = SIZE(msg)
     726         258 :       CALL mpi_send(msg, msglen, ${mpi_type1}$, dest, tag, comm%handle, ierr)
     727         258 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_send @ "//routineN)
     728         258 :       CALL add_perf(perf_id=13, count=1, msg_size=msglen*${bytes1}$)
     729             : #else
     730             :       MARK_USED(msg)
     731             :       MARK_USED(dest)
     732             :       MARK_USED(tag)
     733             :       MARK_USED(comm)
     734             :       ! only defined in parallel
     735             :       CPABORT("not in parallel mode")
     736             : #endif
     737         258 :       CALL mp_timestop(handle)
     738         258 :    END SUBROUTINE mp_send_${nametype1}$m3
     739             : 
     740             : ! **************************************************************************************************
     741             : !> \brief Receive one datum from another process
     742             : !> \param[in,out] msg         Place received data into this variable
     743             : !> \param[in,out] source      Process to receive from
     744             : !> \param[in,out] tag         Transfer identifier
     745             : !> \param[in] comm             Message passing environment identifier
     746             : !> \par MPI mapping
     747             : !>      mpi_send
     748             : ! **************************************************************************************************
     749        1214 :    SUBROUTINE mp_recv_${nametype1}$ (msg, source, tag, comm)
     750             :       ${type1}$, INTENT(INOUT)                   :: msg
     751             :       INTEGER, INTENT(INOUT)                   :: source, tag
     752             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     753             : 
     754             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_recv_${nametype1}$'
     755             : 
     756             :       INTEGER                                  :: handle
     757             : #if defined(__parallel)
     758             :       INTEGER :: ierr, msglen
     759             :       MPI_STATUS_TYPE       :: status
     760             : #endif
     761             : 
     762        1214 :       CALL mp_timeset(routineN, handle)
     763             : 
     764             : #if defined(__parallel)
     765        1214 :       msglen = 1
     766        1214 :       IF (source /= mp_any_source .AND. tag /= mp_any_tag) THEN
     767        1143 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, MPI_STATUS_IGNORE, ierr)
     768        1143 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     769             :       ELSE
     770          71 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, status, ierr)
     771          71 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     772          71 :          CALL add_perf(perf_id=14, count=1, msg_size=msglen*${bytes1}$)
     773          71 :          source = status MPI_STATUS_EXTRACT(MPI_SOURCE)
     774          71 :          tag = status MPI_STATUS_EXTRACT(MPI_TAG)
     775             :       END IF
     776             : #else
     777             :       MARK_USED(msg)
     778             :       MARK_USED(source)
     779             :       MARK_USED(tag)
     780             :       MARK_USED(comm)
     781             :       ! only defined in parallel
     782             :       CPABORT("not in parallel mode")
     783             : #endif
     784        1214 :       CALL mp_timestop(handle)
     785        1214 :    END SUBROUTINE mp_recv_${nametype1}$
     786             : 
     787             : ! **************************************************************************************************
     788             : !> \brief Receive rank-1 data from another process
     789             : !> \param[in,out] msg         Place received data into this rank-1 array
     790             : !> \param source ...
     791             : !> \param tag ...
     792             : !> \param comm ...
     793             : !> \note see mp_recv_${nametype1}$
     794             : ! **************************************************************************************************
     795      113438 :    SUBROUTINE mp_recv_${nametype1}$v(msg, source, tag, comm)
     796             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:)
     797             :       INTEGER, INTENT(INOUT)                   :: source, tag
     798             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     799             : 
     800             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_recv_${nametype1}$v'
     801             : 
     802             :       INTEGER                                  :: handle
     803             : #if defined(__parallel)
     804             :       INTEGER :: ierr, msglen
     805             :       MPI_STATUS_TYPE       :: status
     806             : #endif
     807             : 
     808      113438 :       CALL mp_timeset(routineN, handle)
     809             : 
     810             : #if defined(__parallel)
     811      113438 :       msglen = SIZE(msg)
     812      113438 :       IF (source /= mp_any_source .AND. tag /= mp_any_tag) THEN
     813      104316 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, MPI_STATUS_IGNORE, ierr)
     814      104316 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     815             :       ELSE
     816        9122 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, status, ierr)
     817        9122 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     818        9122 :          CALL add_perf(perf_id=14, count=1, msg_size=msglen*${bytes1}$)
     819        9122 :          source = status MPI_STATUS_EXTRACT(MPI_SOURCE)
     820        9122 :          tag = status MPI_STATUS_EXTRACT(MPI_TAG)
     821             :       END IF
     822             : #else
     823             :       MARK_USED(msg)
     824             :       MARK_USED(source)
     825             :       MARK_USED(tag)
     826             :       MARK_USED(comm)
     827             :       ! only defined in parallel
     828             :       CPABORT("not in parallel mode")
     829             : #endif
     830      113438 :       CALL mp_timestop(handle)
     831      113438 :    END SUBROUTINE mp_recv_${nametype1}$v
     832             : 
     833             : ! **************************************************************************************************
     834             : !> \brief Receive rank-2 data from another process
     835             : !> \param[in,out] msg         Place received data into this rank-2 array
     836             : !> \param source ...
     837             : !> \param tag ...
     838             : !> \param comm ...
     839             : !> \note see mp_recv_${nametype1}$
     840             : ! **************************************************************************************************
     841           4 :    SUBROUTINE mp_recv_${nametype1}$m2(msg, source, tag, comm)
     842             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :)
     843             :       INTEGER, INTENT(INOUT)                   :: source, tag
     844             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     845             : 
     846             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_recv_${nametype1}$m2'
     847             : 
     848             :       INTEGER                                  :: handle
     849             : #if defined(__parallel)
     850             :       INTEGER :: ierr, msglen
     851             :       MPI_STATUS_TYPE       :: status
     852             : #endif
     853             : 
     854           4 :       CALL mp_timeset(routineN, handle)
     855             : 
     856             : #if defined(__parallel)
     857          12 :       msglen = SIZE(msg)
     858           4 :       IF (source /= mp_any_source .AND. tag /= mp_any_tag) THEN
     859           4 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, MPI_STATUS_IGNORE, ierr)
     860           4 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     861             :       ELSE
     862           0 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, status, ierr)
     863           0 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     864           0 :          CALL add_perf(perf_id=14, count=1, msg_size=msglen*${bytes1}$)
     865           0 :          source = status MPI_STATUS_EXTRACT(MPI_SOURCE)
     866           0 :          tag = status MPI_STATUS_EXTRACT(MPI_TAG)
     867             :       END IF
     868             : #else
     869             :       MARK_USED(msg)
     870             :       MARK_USED(source)
     871             :       MARK_USED(tag)
     872             :       MARK_USED(comm)
     873             :       ! only defined in parallel
     874             :       CPABORT("not in parallel mode")
     875             : #endif
     876           4 :       CALL mp_timestop(handle)
     877           4 :    END SUBROUTINE mp_recv_${nametype1}$m2
     878             : 
     879             : ! **************************************************************************************************
     880             : !> \brief Receive rank-3 data from another process
     881             : !> \param[in,out] msg         Place received data into this rank-3 array
     882             : !> \param source ...
     883             : !> \param tag ...
     884             : !> \param comm ...
     885             : !> \note see mp_recv_${nametype1}$
     886             : ! **************************************************************************************************
     887         258 :    SUBROUTINE mp_recv_${nametype1}$m3(msg, source, tag, comm)
     888             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :, :)
     889             :       INTEGER, INTENT(INOUT)                   :: source, tag
     890             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     891             : 
     892             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_recv_${nametype1}$m3'
     893             : 
     894             :       INTEGER                                  :: handle
     895             : #if defined(__parallel)
     896             :       INTEGER :: ierr, msglen
     897             :       MPI_STATUS_TYPE       :: status
     898             : #endif
     899             : 
     900         258 :       CALL mp_timeset(routineN, handle)
     901             : 
     902             : #if defined(__parallel)
     903        1032 :       msglen = SIZE(msg)
     904         258 :       IF (source /= mp_any_source .AND. tag /= mp_any_tag) THEN
     905         258 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, MPI_STATUS_IGNORE, ierr)
     906         258 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     907             :       ELSE
     908           0 :          CALL mpi_recv(msg, msglen, ${mpi_type1}$, source, tag, comm%handle, status, ierr)
     909           0 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_recv @ "//routineN)
     910           0 :          CALL add_perf(perf_id=14, count=1, msg_size=msglen*${bytes1}$)
     911           0 :          source = status MPI_STATUS_EXTRACT(MPI_SOURCE)
     912           0 :          tag = status MPI_STATUS_EXTRACT(MPI_TAG)
     913             :       END IF
     914             : #else
     915             :       MARK_USED(msg)
     916             :       MARK_USED(source)
     917             :       MARK_USED(tag)
     918             :       MARK_USED(comm)
     919             :       ! only defined in parallel
     920             :       CPABORT("not in parallel mode")
     921             : #endif
     922         258 :       CALL mp_timestop(handle)
     923         258 :    END SUBROUTINE mp_recv_${nametype1}$m3
     924             : 
     925             : ! **************************************************************************************************
     926             : !> \brief Broadcasts a datum to all processes.
     927             : !> \param[in] msg             Datum to broadcast
     928             : !> \param[in] source          Processes which broadcasts
     929             : !> \param[in] comm             Message passing environment identifier
     930             : !> \par MPI mapping
     931             : !>      mpi_bcast
     932             : ! **************************************************************************************************
     933     4405182 :    SUBROUTINE mp_bcast_${nametype1}$ (msg, source, comm)
     934             :       ${type1}$, INTENT(INOUT)                                  :: msg
     935             :       INTEGER, INTENT(IN)                                  :: source
     936             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     937             : 
     938             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$'
     939             : 
     940             :       INTEGER                                  :: handle
     941             : #if defined(__parallel)
     942             :       INTEGER :: ierr, msglen
     943             : #endif
     944             : 
     945     4405182 :       CALL mp_timeset(routineN, handle)
     946             : 
     947             : #if defined(__parallel)
     948     4405182 :       msglen = 1
     949     4405182 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, source, comm%handle, ierr)
     950     4405182 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
     951     4405182 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
     952             : #else
     953             :       MARK_USED(msg)
     954             :       MARK_USED(source)
     955             :       MARK_USED(comm)
     956             : #endif
     957     4405182 :       CALL mp_timestop(handle)
     958     4405182 :    END SUBROUTINE mp_bcast_${nametype1}$
     959             : 
     960             : ! **************************************************************************************************
     961             : !> \brief Broadcasts a datum to all processes. Convenience function using the source of the communicator
     962             : !> \param[in] msg             Datum to broadcast
     963             : !> \param[in] comm             Message passing environment identifier
     964             : !> \par MPI mapping
     965             : !>      mpi_bcast
     966             : ! **************************************************************************************************
     967      321015 :    SUBROUTINE mp_bcast_${nametype1}$_src(msg, comm)
     968             :       ${type1}$, INTENT(INOUT)                                  :: msg
     969             :       CLASS(mp_comm_type), INTENT(IN) :: comm
     970             : 
     971             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$_src'
     972             : 
     973             :       INTEGER                                  :: handle
     974             : #if defined(__parallel)
     975             :       INTEGER :: ierr, msglen
     976             : #endif
     977             : 
     978      321015 :       CALL mp_timeset(routineN, handle)
     979             : 
     980             : #if defined(__parallel)
     981      321015 :       msglen = 1
     982      321015 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
     983      321015 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
     984      321015 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
     985             : #else
     986             :       MARK_USED(msg)
     987             :       MARK_USED(comm)
     988             : #endif
     989      321015 :       CALL mp_timestop(handle)
     990      321015 :    END SUBROUTINE mp_bcast_${nametype1}$_src
     991             : 
     992             : ! **************************************************************************************************
     993             : !> \brief Broadcasts a datum to all processes.
     994             : !> \param[in] msg             Datum to broadcast
     995             : !> \param[in] source          Processes which broadcasts
     996             : !> \param[in] comm             Message passing environment identifier
     997             : !> \par MPI mapping
     998             : !>      mpi_bcast
     999             : ! **************************************************************************************************
    1000           0 :    SUBROUTINE mp_ibcast_${nametype1}$ (msg, source, comm, request)
    1001             :       ${type1}$, INTENT(INOUT)                   :: msg
    1002             :       INTEGER, INTENT(IN)                        :: source
    1003             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1004             :       TYPE(mp_request_type), INTENT(OUT)          :: request
    1005             : 
    1006             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_ibcast_${nametype1}$'
    1007             : 
    1008             :       INTEGER                                  :: handle
    1009             : #if defined(__parallel)
    1010             :       INTEGER :: ierr, msglen
    1011             : #endif
    1012             : 
    1013           0 :       CALL mp_timeset(routineN, handle)
    1014             : 
    1015             : #if defined(__parallel)
    1016           0 :       msglen = 1
    1017           0 :       CALL mpi_ibcast(msg, msglen, ${mpi_type1}$, source, comm%handle, request%handle, ierr)
    1018           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_ibcast @ "//routineN)
    1019           0 :       CALL add_perf(perf_id=22, count=1, msg_size=msglen*${bytes1}$)
    1020             : #else
    1021             :       MARK_USED(msg)
    1022             :       MARK_USED(source)
    1023             :       MARK_USED(comm)
    1024             :       request = mp_request_null
    1025             : #endif
    1026           0 :       CALL mp_timestop(handle)
    1027           0 :    END SUBROUTINE mp_ibcast_${nametype1}$
    1028             : 
    1029             : ! **************************************************************************************************
    1030             : !> \brief Broadcasts rank-1 data to all processes
    1031             : !> \param[in] msg             Data to broadcast
    1032             : !> \param source ...
    1033             : !> \param comm ...
    1034             : !> \note see mp_bcast_${nametype1}$1
    1035             : ! **************************************************************************************************
    1036     1738652 :    SUBROUTINE mp_bcast_${nametype1}$v(msg, source, comm)
    1037             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                                  :: msg(:)
    1038             :       INTEGER, INTENT(IN)                                  :: source
    1039             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1040             : 
    1041             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$v'
    1042             : 
    1043             :       INTEGER                                  :: handle
    1044             : #if defined(__parallel)
    1045             :       INTEGER :: ierr, msglen
    1046             : #endif
    1047             : 
    1048     1738652 :       CALL mp_timeset(routineN, handle)
    1049             : 
    1050             : #if defined(__parallel)
    1051     1738652 :       msglen = SIZE(msg)
    1052     1738652 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, source, comm%handle, ierr)
    1053     1738652 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1054     1738652 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1055             : #else
    1056             :       MARK_USED(msg)
    1057             :       MARK_USED(source)
    1058             :       MARK_USED(comm)
    1059             : #endif
    1060     1738652 :       CALL mp_timestop(handle)
    1061     1738652 :    END SUBROUTINE mp_bcast_${nametype1}$v
    1062             : 
    1063             : ! **************************************************************************************************
    1064             : !> \brief Broadcasts rank-1 data to all processes, uses the source of the communicator, convenience function
    1065             : !> \param[in] msg             Data to broadcast
    1066             : !> \param comm ...
    1067             : !> \note see mp_bcast_${nametype1}$1
    1068             : ! **************************************************************************************************
    1069       85232 :    SUBROUTINE mp_bcast_${nametype1}$v_src(msg, comm)
    1070             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                                  :: msg(:)
    1071             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1072             : 
    1073             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$v_src'
    1074             : 
    1075             :       INTEGER                                  :: handle
    1076             : #if defined(__parallel)
    1077             :       INTEGER :: ierr, msglen
    1078             : #endif
    1079             : 
    1080       85232 :       CALL mp_timeset(routineN, handle)
    1081             : 
    1082             : #if defined(__parallel)
    1083       85232 :       msglen = SIZE(msg)
    1084       85232 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    1085       85232 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1086       85232 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1087             : #else
    1088             :       MARK_USED(msg)
    1089             :       MARK_USED(comm)
    1090             : #endif
    1091       85232 :       CALL mp_timestop(handle)
    1092       85232 :    END SUBROUTINE mp_bcast_${nametype1}$v_src
    1093             : 
    1094             : ! **************************************************************************************************
    1095             : !> \brief Broadcasts rank-1 data to all processes
    1096             : !> \param[in] msg             Data to broadcast
    1097             : !> \param source ...
    1098             : !> \param comm ...
    1099             : !> \note see mp_bcast_${nametype1}$1
    1100             : ! **************************************************************************************************
    1101           0 :    SUBROUTINE mp_ibcast_${nametype1}$v(msg, source, comm, request)
    1102             :       ${type1}$, INTENT(INOUT)                 :: msg(:)
    1103             :       INTEGER, INTENT(IN)                      :: source
    1104             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1105             :       TYPE(mp_request_type)                   :: request
    1106             : 
    1107             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_ibcast_${nametype1}$v'
    1108             : 
    1109             :       INTEGER                                  :: handle
    1110             : #if defined(__parallel)
    1111             :       INTEGER :: ierr, msglen
    1112             : #endif
    1113             : 
    1114           0 :       CALL mp_timeset(routineN, handle)
    1115             : 
    1116             : #if defined(__parallel)
    1117             : #if !defined(__GNUC__) || __GNUC__ >= 9
    1118           0 :       CPASSERT(IS_CONTIGUOUS(msg))
    1119             : #endif
    1120           0 :       msglen = SIZE(msg)
    1121           0 :       CALL mpi_ibcast(msg, msglen, ${mpi_type1}$, source, comm%handle, request%handle, ierr)
    1122           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_ibcast @ "//routineN)
    1123           0 :       CALL add_perf(perf_id=22, count=1, msg_size=msglen*${bytes1}$)
    1124             : #else
    1125             :       MARK_USED(msg)
    1126             :       MARK_USED(source)
    1127             :       MARK_USED(comm)
    1128             :       request = mp_request_null
    1129             : #endif
    1130           0 :       CALL mp_timestop(handle)
    1131           0 :    END SUBROUTINE mp_ibcast_${nametype1}$v
    1132             : 
    1133             : ! **************************************************************************************************
    1134             : !> \brief Broadcasts rank-2 data to all processes
    1135             : !> \param[in] msg             Data to broadcast
    1136             : !> \param source ...
    1137             : !> \param comm ...
    1138             : !> \note see mp_bcast_${nametype1}$1
    1139             : ! **************************************************************************************************
    1140      631652 :    SUBROUTINE mp_bcast_${nametype1}$m(msg, source, comm)
    1141             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                                  :: msg(:, :)
    1142             :       INTEGER, INTENT(IN)                                  :: source
    1143             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1144             : 
    1145             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$m'
    1146             : 
    1147             :       INTEGER                                  :: handle
    1148             : #if defined(__parallel)
    1149             :       INTEGER :: ierr, msglen
    1150             : #endif
    1151             : 
    1152      631652 :       CALL mp_timeset(routineN, handle)
    1153             : 
    1154             : #if defined(__parallel)
    1155     1894956 :       msglen = SIZE(msg)
    1156      631652 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, source, comm%handle, ierr)
    1157      631652 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1158      631652 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1159             : #else
    1160             :       MARK_USED(msg)
    1161             :       MARK_USED(source)
    1162             :       MARK_USED(comm)
    1163             : #endif
    1164      631652 :       CALL mp_timestop(handle)
    1165      631652 :    END SUBROUTINE mp_bcast_${nametype1}$m
    1166             : 
    1167             : ! **************************************************************************************************
    1168             : !> \brief Broadcasts rank-2 data to all processes
    1169             : !> \param[in] msg             Data to broadcast
    1170             : !> \param source ...
    1171             : !> \param comm ...
    1172             : !> \note see mp_bcast_${nametype1}$1
    1173             : ! **************************************************************************************************
    1174        9401 :    SUBROUTINE mp_bcast_${nametype1}$m_src(msg, comm)
    1175             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                                  :: msg(:, :)
    1176             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1177             : 
    1178             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$m_src'
    1179             : 
    1180             :       INTEGER                                  :: handle
    1181             : #if defined(__parallel)
    1182             :       INTEGER :: ierr, msglen
    1183             : #endif
    1184             : 
    1185        9401 :       CALL mp_timeset(routineN, handle)
    1186             : 
    1187             : #if defined(__parallel)
    1188       28203 :       msglen = SIZE(msg)
    1189        9401 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    1190        9401 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1191        9401 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1192             : #else
    1193             :       MARK_USED(msg)
    1194             :       MARK_USED(comm)
    1195             : #endif
    1196        9401 :       CALL mp_timestop(handle)
    1197        9401 :    END SUBROUTINE mp_bcast_${nametype1}$m_src
    1198             : 
    1199             : ! **************************************************************************************************
    1200             : !> \brief Broadcasts rank-3 data to all processes
    1201             : !> \param[in] msg             Data to broadcast
    1202             : !> \param source ...
    1203             : !> \param comm ...
    1204             : !> \note see mp_bcast_${nametype1}$1
    1205             : ! **************************************************************************************************
    1206       23520 :    SUBROUTINE mp_bcast_${nametype1}$3(msg, source, comm)
    1207             :       ${type1}$, CONTIGUOUS                                  :: msg(:, :, :)
    1208             :       INTEGER, INTENT(IN)                                  :: source
    1209             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1210             : 
    1211             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$3'
    1212             : 
    1213             :       INTEGER                                  :: handle
    1214             : #if defined(__parallel)
    1215             :       INTEGER :: ierr, msglen
    1216             : #endif
    1217             : 
    1218       23520 :       CALL mp_timeset(routineN, handle)
    1219             : 
    1220             : #if defined(__parallel)
    1221       94080 :       msglen = SIZE(msg)
    1222       23520 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, source, comm%handle, ierr)
    1223       23520 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1224       23520 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1225             : #else
    1226             :       MARK_USED(msg)
    1227             :       MARK_USED(source)
    1228             :       MARK_USED(comm)
    1229             : #endif
    1230       23520 :       CALL mp_timestop(handle)
    1231       23520 :    END SUBROUTINE mp_bcast_${nametype1}$3
    1232             : 
    1233             : ! **************************************************************************************************
    1234             : !> \brief Broadcasts rank-3 data to all processes. Uses the source of the communicator for convenience
    1235             : !> \param[in] msg             Data to broadcast
    1236             : !> \param source ...
    1237             : !> \param comm ...
    1238             : !> \note see mp_bcast_${nametype1}$1
    1239             : ! **************************************************************************************************
    1240          92 :    SUBROUTINE mp_bcast_${nametype1}$3_src(msg, comm)
    1241             :       ${type1}$, CONTIGUOUS                                  :: msg(:, :, :)
    1242             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1243             : 
    1244             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_bcast_${nametype1}$3_src'
    1245             : 
    1246             :       INTEGER                                  :: handle
    1247             : #if defined(__parallel)
    1248             :       INTEGER :: ierr, msglen
    1249             : #endif
    1250             : 
    1251          92 :       CALL mp_timeset(routineN, handle)
    1252             : 
    1253             : #if defined(__parallel)
    1254         368 :       msglen = SIZE(msg)
    1255          92 :       CALL mpi_bcast(msg, msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    1256          92 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_bcast @ "//routineN)
    1257          92 :       CALL add_perf(perf_id=2, count=1, msg_size=msglen*${bytes1}$)
    1258             : #else
    1259             :       MARK_USED(msg)
    1260             :       MARK_USED(comm)
    1261             : #endif
    1262          92 :       CALL mp_timestop(handle)
    1263          92 :    END SUBROUTINE mp_bcast_${nametype1}$3_src
    1264             : 
    1265             : ! **************************************************************************************************
    1266             : !> \brief Sums a datum from all processes with result left on all processes.
    1267             : !> \param[in,out] msg         Datum to sum (input) and result (output)
    1268             : !> \param[in] comm             Message passing environment identifier
    1269             : !> \par MPI mapping
    1270             : !>      mpi_allreduce
    1271             : ! **************************************************************************************************
    1272    25949044 :    SUBROUTINE mp_sum_${nametype1}$ (msg, comm)
    1273             :       ${type1}$, INTENT(INOUT)                   :: msg
    1274             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1275             : 
    1276             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_${nametype1}$'
    1277             : 
    1278             :       INTEGER                                  :: handle
    1279             : #if defined(__parallel)
    1280             :       INTEGER :: ierr, msglen
    1281             : #endif
    1282             : 
    1283    25949044 :       CALL mp_timeset(routineN, handle)
    1284             : 
    1285             : #if defined(__parallel)
    1286    25949044 :       msglen = 1
    1287    25949044 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1288    25949044 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1289    25949044 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1290             : #else
    1291             :       MARK_USED(msg)
    1292             :       MARK_USED(comm)
    1293             : #endif
    1294    25949044 :       CALL mp_timestop(handle)
    1295    25949044 :    END SUBROUTINE mp_sum_${nametype1}$
    1296             : 
    1297             : ! **************************************************************************************************
    1298             : !> \brief Element-wise sum of a rank-1 array on all processes.
    1299             : !> \param[in,out] msg         Vector to sum and result
    1300             : !> \param comm ...
    1301             : !> \note see mp_sum_${nametype1}$
    1302             : ! **************************************************************************************************
    1303     4449502 :    SUBROUTINE mp_sum_${nametype1}$v(msg, comm)
    1304             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:)
    1305             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1306             : 
    1307             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_${nametype1}$v'
    1308             : 
    1309             :       INTEGER                                  :: handle
    1310             : #if defined(__parallel)
    1311             :       INTEGER                                  :: ierr, msglen
    1312             : #endif
    1313             : 
    1314     4449502 :       CALL mp_timeset(routineN, handle)
    1315             : 
    1316             : #if defined(__parallel)
    1317     4449502 :       msglen = SIZE(msg)
    1318     4449502 :       IF (msglen > 0) THEN
    1319     4319425 :          CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1320     4319425 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1321             :       END IF
    1322     4449502 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1323             : #else
    1324             :       MARK_USED(msg)
    1325             :       MARK_USED(comm)
    1326             : #endif
    1327     4449502 :       CALL mp_timestop(handle)
    1328     4449502 :    END SUBROUTINE mp_sum_${nametype1}$v
    1329             : 
    1330             : ! **************************************************************************************************
    1331             : !> \brief Element-wise sum of a rank-1 array on all processes.
    1332             : !> \param[in,out] msg         Vector to sum and result
    1333             : !> \param comm ...
    1334             : !> \note see mp_sum_${nametype1}$
    1335             : ! **************************************************************************************************
    1336           0 :    SUBROUTINE mp_isum_${nametype1}$v(msg, comm, request)
    1337             :       ${type1}$, INTENT(INOUT)                   :: msg(:)
    1338             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1339             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    1340             : 
    1341             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isum_${nametype1}$v'
    1342             : 
    1343             :       INTEGER                                  :: handle
    1344             : #if defined(__parallel)
    1345             :       INTEGER                                  :: ierr, msglen
    1346             : #endif
    1347             : 
    1348           0 :       CALL mp_timeset(routineN, handle)
    1349             : 
    1350             : #if defined(__parallel)
    1351             : #if !defined(__GNUC__) || __GNUC__ >= 9
    1352           0 :       CPASSERT(IS_CONTIGUOUS(msg))
    1353             : #endif
    1354           0 :       msglen = SIZE(msg)
    1355           0 :       IF (msglen > 0) THEN
    1356           0 :          CALL mpi_iallreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, request%handle, ierr)
    1357           0 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallreduce @ "//routineN)
    1358             :       ELSE
    1359           0 :          request = mp_request_null
    1360             :       END IF
    1361           0 :       CALL add_perf(perf_id=23, count=1, msg_size=msglen*${bytes1}$)
    1362             : #else
    1363             :       MARK_USED(msg)
    1364             :       MARK_USED(comm)
    1365             :       request = mp_request_null
    1366             : #endif
    1367           0 :       CALL mp_timestop(handle)
    1368           0 :    END SUBROUTINE mp_isum_${nametype1}$v
    1369             : 
    1370             : ! **************************************************************************************************
    1371             : !> \brief Element-wise sum of a rank-2 array on all processes.
    1372             : !> \param[in] msg             Matrix to sum and result
    1373             : !> \param comm ...
    1374             : !> \note see mp_sum_${nametype1}$
    1375             : ! **************************************************************************************************
    1376     1883575 :    SUBROUTINE mp_sum_${nametype1}$m(msg, comm)
    1377             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :)
    1378             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1379             : 
    1380             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_${nametype1}$m'
    1381             : 
    1382             :       INTEGER                                  :: handle
    1383             : #if defined(__parallel)
    1384             :       INTEGER, PARAMETER :: max_msg = 2**25
    1385             :       INTEGER                                  :: ierr, m1, msglen, step, msglensum
    1386             : #endif
    1387             : 
    1388     1883575 :       CALL mp_timeset(routineN, handle)
    1389             : 
    1390             : #if defined(__parallel)
    1391             :       ! chunk up the call so that message sizes are limited, to avoid overflows in mpich triggered in large rpa calcs
    1392     5650725 :       step = MAX(1, SIZE(msg, 2)/MAX(1, SIZE(msg)/max_msg))
    1393     1883575 :       msglensum = 0
    1394     5650625 :       DO m1 = LBOUND(msg, 2), UBOUND(msg, 2), step
    1395     1883525 :          msglen = SIZE(msg, 1)*(MIN(UBOUND(msg, 2), m1 + step - 1) - m1 + 1)
    1396     1883525 :          msglensum = msglensum + msglen
    1397     3767100 :          IF (msglen > 0) THEN
    1398     1882377 :             CALL mpi_allreduce(MPI_IN_PLACE, msg(LBOUND(msg, 1), m1), msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1399     1882377 :             IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1400             :          END IF
    1401             :       END DO
    1402     1883575 :       CALL add_perf(perf_id=3, count=1, msg_size=msglensum*${bytes1}$)
    1403             : #else
    1404             :       MARK_USED(msg)
    1405             :       MARK_USED(comm)
    1406             : #endif
    1407     1883575 :       CALL mp_timestop(handle)
    1408     1883575 :    END SUBROUTINE mp_sum_${nametype1}$m
    1409             : 
    1410             : ! **************************************************************************************************
    1411             : !> \brief Element-wise sum of a rank-3 array on all processes.
    1412             : !> \param[in] msg             Array to sum and result
    1413             : !> \param comm ...
    1414             : !> \note see mp_sum_${nametype1}$
    1415             : ! **************************************************************************************************
    1416       59821 :    SUBROUTINE mp_sum_${nametype1}$m3(msg, comm)
    1417             :       ${type1}$, INTENT(INOUT), CONTIGUOUS     :: msg(:, :, :)
    1418             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1419             : 
    1420             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_${nametype1}$m3'
    1421             : 
    1422             :       INTEGER                                  :: handle
    1423             : #if defined(__parallel)
    1424             :       INTEGER :: ierr, msglen
    1425             : #endif
    1426             : 
    1427       59821 :       CALL mp_timeset(routineN, handle)
    1428             : 
    1429             : #if defined(__parallel)
    1430      239284 :       msglen = SIZE(msg)
    1431       59821 :       IF (msglen > 0) THEN
    1432       59821 :          CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1433       59821 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1434             :       END IF
    1435       59821 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1436             : #else
    1437             :       MARK_USED(msg)
    1438             :       MARK_USED(comm)
    1439             : #endif
    1440       59821 :       CALL mp_timestop(handle)
    1441       59821 :    END SUBROUTINE mp_sum_${nametype1}$m3
    1442             : 
    1443             : ! **************************************************************************************************
    1444             : !> \brief Element-wise sum of a rank-4 array on all processes.
    1445             : !> \param[in] msg             Array to sum and result
    1446             : !> \param comm ...
    1447             : !> \note see mp_sum_${nametype1}$
    1448             : ! **************************************************************************************************
    1449         220 :    SUBROUTINE mp_sum_${nametype1}$m4(msg, comm)
    1450             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :, :, :)
    1451             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1452             : 
    1453             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_${nametype1}$m4'
    1454             : 
    1455             :       INTEGER                                  :: handle
    1456             : #if defined(__parallel)
    1457             :       INTEGER :: ierr, msglen
    1458             : #endif
    1459             : 
    1460         220 :       CALL mp_timeset(routineN, handle)
    1461             : 
    1462             : #if defined(__parallel)
    1463        1100 :       msglen = SIZE(msg)
    1464         220 :       IF (msglen > 0) THEN
    1465         220 :          CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1466         220 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1467             :       END IF
    1468         220 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1469             : #else
    1470             :       MARK_USED(msg)
    1471             :       MARK_USED(comm)
    1472             : #endif
    1473         220 :       CALL mp_timestop(handle)
    1474         220 :    END SUBROUTINE mp_sum_${nametype1}$m4
    1475             : 
    1476             : ! **************************************************************************************************
    1477             : !> \brief Element-wise sum of data from all processes with result left only on
    1478             : !>        one.
    1479             : !> \param[in,out] msg         Vector to sum (input) and (only on process root)
    1480             : !>                            result (output)
    1481             : !> \param root ...
    1482             : !> \param[in] comm             Message passing environment identifier
    1483             : !> \par MPI mapping
    1484             : !>      mpi_reduce
    1485             : ! **************************************************************************************************
    1486          54 :    SUBROUTINE mp_sum_root_${nametype1}$v(msg, root, comm)
    1487             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:)
    1488             :       INTEGER, INTENT(IN)                      :: root
    1489             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1490             : 
    1491             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_root_${nametype1}$v'
    1492             : 
    1493             :       INTEGER                                  :: handle
    1494             : #if defined(__parallel)
    1495             :       INTEGER                                  :: ierr, m1, msglen, taskid
    1496          54 :       ${type1}$, ALLOCATABLE                     :: res(:)
    1497             : #endif
    1498             : 
    1499          54 :       CALL mp_timeset(routineN, handle)
    1500             : 
    1501             : #if defined(__parallel)
    1502          54 :       msglen = SIZE(msg)
    1503          54 :       CALL mpi_comm_rank(comm%handle, taskid, ierr)
    1504          54 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_rank @ "//routineN)
    1505          54 :       IF (msglen > 0) THEN
    1506          54 :          m1 = SIZE(msg, 1)
    1507         162 :          ALLOCATE (res(m1))
    1508             :          CALL mpi_reduce(msg, res, msglen, ${mpi_type1}$, MPI_SUM, &
    1509          54 :                          root, comm%handle, ierr)
    1510          54 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_reduce @ "//routineN)
    1511          54 :          IF (taskid == root) THEN
    1512         135 :             msg = res
    1513             :          END IF
    1514          54 :          DEALLOCATE (res)
    1515             :       END IF
    1516          54 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1517             : #else
    1518             :       MARK_USED(msg)
    1519             :       MARK_USED(root)
    1520             :       MARK_USED(comm)
    1521             : #endif
    1522          54 :       CALL mp_timestop(handle)
    1523          54 :    END SUBROUTINE mp_sum_root_${nametype1}$v
    1524             : 
    1525             : ! **************************************************************************************************
    1526             : !> \brief Element-wise sum of data from all processes with result left only on
    1527             : !>        one.
    1528             : !> \param[in,out] msg         Matrix to sum (input) and (only on process root)
    1529             : !>                            result (output)
    1530             : !> \param root ...
    1531             : !> \param comm ...
    1532             : !> \note see mp_sum_root_${nametype1}$v
    1533             : ! **************************************************************************************************
    1534           0 :    SUBROUTINE mp_sum_root_${nametype1}$m(msg, root, comm)
    1535             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :)
    1536             :       INTEGER, INTENT(IN)                      :: root
    1537             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1538             : 
    1539             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_root_rm'
    1540             : 
    1541             :       INTEGER                                  :: handle
    1542             : #if defined(__parallel)
    1543             :       INTEGER                                  :: ierr, m1, m2, msglen, taskid
    1544           0 :       ${type1}$, ALLOCATABLE                     :: res(:, :)
    1545             : #endif
    1546             : 
    1547           0 :       CALL mp_timeset(routineN, handle)
    1548             : 
    1549             : #if defined(__parallel)
    1550           0 :       msglen = SIZE(msg)
    1551           0 :       CALL mpi_comm_rank(comm%handle, taskid, ierr)
    1552           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_rank @ "//routineN)
    1553           0 :       IF (msglen > 0) THEN
    1554           0 :          m1 = SIZE(msg, 1)
    1555           0 :          m2 = SIZE(msg, 2)
    1556           0 :          ALLOCATE (res(m1, m2))
    1557           0 :          CALL mpi_reduce(msg, res, msglen, ${mpi_type1}$, MPI_SUM, root, comm%handle, ierr)
    1558           0 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_reduce @ "//routineN)
    1559           0 :          IF (taskid == root) THEN
    1560           0 :             msg = res
    1561             :          END IF
    1562           0 :          DEALLOCATE (res)
    1563             :       END IF
    1564           0 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1565             : #else
    1566             :       MARK_USED(root)
    1567             :       MARK_USED(msg)
    1568             :       MARK_USED(comm)
    1569             : #endif
    1570           0 :       CALL mp_timestop(handle)
    1571           0 :    END SUBROUTINE mp_sum_root_${nametype1}$m
    1572             : 
    1573             : ! **************************************************************************************************
    1574             : !> \brief Partial sum of data from all processes with result on each process.
    1575             : !> \param[in] msg          Matrix to sum (input)
    1576             : !> \param[out] res         Matrix containing result (output)
    1577             : !> \param[in] comm          Message passing environment identifier
    1578             : ! **************************************************************************************************
    1579          54 :    SUBROUTINE mp_sum_partial_${nametype1}$m(msg, res, comm)
    1580             :       ${type1}$, CONTIGUOUS, INTENT(IN)   :: msg(:, :)
    1581             :       ${type1}$, CONTIGUOUS, INTENT(OUT)  :: res(:, :)
    1582             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1583             : 
    1584             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_partial_${nametype1}$m'
    1585             : 
    1586             :       INTEGER                     :: handle
    1587             : #if defined(__parallel)
    1588             :       INTEGER                     :: ierr, msglen, taskid
    1589             : #endif
    1590             : 
    1591          54 :       CALL mp_timeset(routineN, handle)
    1592             : 
    1593             : #if defined(__parallel)
    1594         162 :       msglen = SIZE(msg)
    1595          54 :       CALL mpi_comm_rank(comm%handle, taskid, ierr)
    1596          54 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_comm_rank @ "//routineN)
    1597          54 :       IF (msglen > 0) THEN
    1598          54 :          CALL mpi_scan(msg, res, msglen, ${mpi_type1}$, MPI_SUM, comm%handle, ierr)
    1599          54 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_scan @ "//routineN)
    1600             :       END IF
    1601          54 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1602             :       ! perf_id is same as for other summation routines
    1603             : #else
    1604             :       res = msg
    1605             :       MARK_USED(comm)
    1606             : #endif
    1607          54 :       CALL mp_timestop(handle)
    1608          54 :    END SUBROUTINE mp_sum_partial_${nametype1}$m
    1609             : 
    1610             : ! **************************************************************************************************
    1611             : !> \brief Finds the maximum of a datum with the result left on all processes.
    1612             : !> \param[in,out] msg         Find maximum among these data (input) and
    1613             : !>                            maximum (output)
    1614             : !> \param[in] comm             Message passing environment identifier
    1615             : !> \par MPI mapping
    1616             : !>      mpi_allreduce
    1617             : ! **************************************************************************************************
    1618    11284481 :    SUBROUTINE mp_max_${nametype1}$ (msg, comm)
    1619             :       ${type1}$, INTENT(INOUT)                   :: msg
    1620             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1621             : 
    1622             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_max_${nametype1}$'
    1623             : 
    1624             :       INTEGER                                  :: handle
    1625             : #if defined(__parallel)
    1626             :       INTEGER :: ierr, msglen
    1627             : #endif
    1628             : 
    1629    11284481 :       CALL mp_timeset(routineN, handle)
    1630             : 
    1631             : #if defined(__parallel)
    1632    11284481 :       msglen = 1
    1633    11284481 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_MAX, comm%handle, ierr)
    1634    11284481 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1635    11284481 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1636             : #else
    1637             :       MARK_USED(msg)
    1638             :       MARK_USED(comm)
    1639             : #endif
    1640    11284481 :       CALL mp_timestop(handle)
    1641    11284481 :    END SUBROUTINE mp_max_${nametype1}$
    1642             : 
    1643             : ! **************************************************************************************************
    1644             : !> \brief Finds the maximum of a datum with the result left on all processes.
    1645             : !> \param[in,out] msg         Find maximum among these data (input) and
    1646             : !>                            maximum (output)
    1647             : !> \param[in] comm             Message passing environment identifier
    1648             : !> \par MPI mapping
    1649             : !>      mpi_allreduce
    1650             : ! **************************************************************************************************
    1651          56 :    SUBROUTINE mp_max_root_${nametype1}$ (msg, root, comm)
    1652             :       ${type1}$, INTENT(INOUT)                   :: msg
    1653             :       INTEGER, INTENT(IN) :: root
    1654             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1655             : 
    1656             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_max_root_${nametype1}$'
    1657             : 
    1658             :       INTEGER                                  :: handle
    1659             : #if defined(__parallel)
    1660             :       INTEGER :: ierr, msglen
    1661             :       ${type1}$ :: res
    1662             : #endif
    1663             : 
    1664          56 :       CALL mp_timeset(routineN, handle)
    1665             : 
    1666             : #if defined(__parallel)
    1667          56 :       msglen = 1
    1668          56 :       CALL mpi_reduce(msg, res, msglen, ${mpi_type1}$, MPI_MAX, root, comm%handle, ierr)
    1669          56 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_reduce @ "//routineN)
    1670          56 :       IF (root == comm%mepos) msg = res
    1671          56 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1672             : #else
    1673             :       MARK_USED(msg)
    1674             :       MARK_USED(comm)
    1675             :       MARK_USED(root)
    1676             : #endif
    1677          56 :       CALL mp_timestop(handle)
    1678          56 :    END SUBROUTINE mp_max_root_${nametype1}$
    1679             : 
    1680             : ! **************************************************************************************************
    1681             : !> \brief Finds the element-wise maximum of a vector with the result left on
    1682             : !>        all processes.
    1683             : !> \param[in,out] msg         Find maximum among these data (input) and
    1684             : !>                            maximum (output)
    1685             : !> \param comm ...
    1686             : !> \note see mp_max_${nametype1}$
    1687             : ! **************************************************************************************************
    1688      448526 :    SUBROUTINE mp_max_${nametype1}$v(msg, comm)
    1689             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:)
    1690             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1691             : 
    1692             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_max_${nametype1}$v'
    1693             : 
    1694             :       INTEGER                                  :: handle
    1695             : #if defined(__parallel)
    1696             :       INTEGER :: ierr, msglen
    1697             : #endif
    1698             : 
    1699      448526 :       CALL mp_timeset(routineN, handle)
    1700             : 
    1701             : #if defined(__parallel)
    1702      448526 :       msglen = SIZE(msg)
    1703      448526 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_MAX, comm%handle, ierr)
    1704      448526 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1705      448526 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1706             : #else
    1707             :       MARK_USED(msg)
    1708             :       MARK_USED(comm)
    1709             : #endif
    1710      448526 :       CALL mp_timestop(handle)
    1711      448526 :    END SUBROUTINE mp_max_${nametype1}$v
    1712             : 
    1713             : ! **************************************************************************************************
    1714             : !> \brief Finds the element-wise maximum of a vector with the result left on
    1715             : !>        all processes.
    1716             : !> \param[in,out] msg         Find maximum among these data (input) and
    1717             : !>                            maximum (output)
    1718             : !> \param comm ...
    1719             : !> \note see mp_max_${nametype1}$
    1720             : ! **************************************************************************************************
    1721           2 :    SUBROUTINE mp_max_root_${nametype1}$m(msg, root, comm)
    1722             :       ${type1}$, CONTIGUOUS, INTENT(INOUT)                   :: msg(:, :)
    1723             :       INTEGER :: root
    1724             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1725             : 
    1726             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_max_root_${nametype1}$m'
    1727             : 
    1728             :       INTEGER                                  :: handle
    1729             : #if defined(__parallel)
    1730             :       INTEGER :: ierr, msglen
    1731           4 :       ${type1}$                   :: res(SIZE(msg, 1), SIZE(msg, 2))
    1732             : #endif
    1733             : 
    1734           2 :       CALL mp_timeset(routineN, handle)
    1735             : 
    1736             : #if defined(__parallel)
    1737           6 :       msglen = SIZE(msg)
    1738           2 :       CALL mpi_reduce(msg, res, msglen, ${mpi_type1}$, MPI_MAX, root, comm%handle, ierr)
    1739           2 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1740           9 :       IF (root == comm%mepos) msg = res
    1741           2 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1742             : #else
    1743             :       MARK_USED(msg)
    1744             :       MARK_USED(comm)
    1745             :       MARK_USED(root)
    1746             : #endif
    1747           2 :       CALL mp_timestop(handle)
    1748           2 :    END SUBROUTINE mp_max_root_${nametype1}$m
    1749             : 
    1750             : ! **************************************************************************************************
    1751             : !> \brief Finds the minimum of a datum with the result left on all processes.
    1752             : !> \param[in,out] msg         Find minimum among these data (input) and
    1753             : !>                            maximum (output)
    1754             : !> \param[in] comm             Message passing environment identifier
    1755             : !> \par MPI mapping
    1756             : !>      mpi_allreduce
    1757             : ! **************************************************************************************************
    1758        1746 :    SUBROUTINE mp_min_${nametype1}$ (msg, comm)
    1759             :       ${type1}$, INTENT(INOUT)                   :: msg
    1760             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1761             : 
    1762             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_min_${nametype1}$'
    1763             : 
    1764             :       INTEGER                                  :: handle
    1765             : #if defined(__parallel)
    1766             :       INTEGER :: ierr, msglen
    1767             : #endif
    1768             : 
    1769        1746 :       CALL mp_timeset(routineN, handle)
    1770             : 
    1771             : #if defined(__parallel)
    1772        1746 :       msglen = 1
    1773        1746 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_MIN, comm%handle, ierr)
    1774        1746 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1775        1746 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1776             : #else
    1777             :       MARK_USED(msg)
    1778             :       MARK_USED(comm)
    1779             : #endif
    1780        1746 :       CALL mp_timestop(handle)
    1781        1746 :    END SUBROUTINE mp_min_${nametype1}$
    1782             : 
    1783             : ! **************************************************************************************************
    1784             : !> \brief Finds the element-wise minimum of vector with the result left on
    1785             : !>        all processes.
    1786             : !> \param[in,out] msg         Find minimum among these data (input) and
    1787             : !>                            maximum (output)
    1788             : !> \param comm ...
    1789             : !> \par MPI mapping
    1790             : !>      mpi_allreduce
    1791             : !> \note see mp_min_${nametype1}$
    1792             : ! **************************************************************************************************
    1793       43810 :    SUBROUTINE mp_min_${nametype1}$v(msg, comm)
    1794             :       ${type1}$, INTENT(INOUT), CONTIGUOUS     :: msg(:)
    1795             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1796             : 
    1797             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_min_${nametype1}$v'
    1798             : 
    1799             :       INTEGER                                  :: handle
    1800             : #if defined(__parallel)
    1801             :       INTEGER :: ierr, msglen
    1802             : #endif
    1803             : 
    1804       43810 :       CALL mp_timeset(routineN, handle)
    1805             : 
    1806             : #if defined(__parallel)
    1807       43810 :       msglen = SIZE(msg)
    1808       43810 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_MIN, comm%handle, ierr)
    1809       43810 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1810       43810 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1811             : #else
    1812             :       MARK_USED(msg)
    1813             :       MARK_USED(comm)
    1814             : #endif
    1815       43810 :       CALL mp_timestop(handle)
    1816       43810 :    END SUBROUTINE mp_min_${nametype1}$v
    1817             : 
    1818             : ! **************************************************************************************************
    1819             : !> \brief Multiplies a set of numbers scattered across a number of processes,
    1820             : !>        then replicates the result.
    1821             : !> \param[in,out] msg         a number to multiply (input) and result (output)
    1822             : !> \param[in] comm             message passing environment identifier
    1823             : !> \par MPI mapping
    1824             : !>      mpi_allreduce
    1825             : ! **************************************************************************************************
    1826        5238 :    SUBROUTINE mp_prod_${nametype1}$ (msg, comm)
    1827             :       ${type1}$, INTENT(INOUT)                   :: msg
    1828             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1829             : 
    1830             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_prod_${nametype1}$'
    1831             : 
    1832             :       INTEGER                                  :: handle
    1833             : #if defined(__parallel)
    1834             :       INTEGER :: ierr, msglen
    1835             : #endif
    1836             : 
    1837        5238 :       CALL mp_timeset(routineN, handle)
    1838             : 
    1839             : #if defined(__parallel)
    1840        5238 :       msglen = 1
    1841        5238 :       CALL mpi_allreduce(MPI_IN_PLACE, msg, msglen, ${mpi_type1}$, MPI_PROD, comm%handle, ierr)
    1842        5238 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allreduce @ "//routineN)
    1843        5238 :       CALL add_perf(perf_id=3, count=1, msg_size=msglen*${bytes1}$)
    1844             : #else
    1845             :       MARK_USED(msg)
    1846             :       MARK_USED(comm)
    1847             : #endif
    1848        5238 :       CALL mp_timestop(handle)
    1849        5238 :    END SUBROUTINE mp_prod_${nametype1}$
    1850             : 
    1851             : ! **************************************************************************************************
    1852             : !> \brief Scatters data from one processes to all others
    1853             : !> \param[in] msg_scatter     Data to scatter (for root process)
    1854             : !> \param[out] msg            Received data
    1855             : !> \param[in] root            Process which scatters data
    1856             : !> \param[in] comm             Message passing environment identifier
    1857             : !> \par MPI mapping
    1858             : !>      mpi_scatter
    1859             : ! **************************************************************************************************
    1860           0 :    SUBROUTINE mp_scatter_${nametype1}$v(msg_scatter, msg, root, comm)
    1861             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg_scatter(:)
    1862             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg(:)
    1863             :       INTEGER, INTENT(IN)                      :: root
    1864             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1865             : 
    1866             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_scatter_${nametype1}$v'
    1867             : 
    1868             :       INTEGER                                  :: handle
    1869             : #if defined(__parallel)
    1870             :       INTEGER :: ierr, msglen
    1871             : #endif
    1872             : 
    1873           0 :       CALL mp_timeset(routineN, handle)
    1874             : 
    1875             : #if defined(__parallel)
    1876           0 :       msglen = SIZE(msg)
    1877             :       CALL mpi_scatter(msg_scatter, msglen, ${mpi_type1}$, msg, &
    1878           0 :                        msglen, ${mpi_type1}$, root, comm%handle, ierr)
    1879           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_scatter @ "//routineN)
    1880           0 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    1881             : #else
    1882             :       MARK_USED(root)
    1883             :       MARK_USED(comm)
    1884             :       msg = msg_scatter
    1885             : #endif
    1886           0 :       CALL mp_timestop(handle)
    1887           0 :    END SUBROUTINE mp_scatter_${nametype1}$v
    1888             : 
    1889             : ! **************************************************************************************************
    1890             : !> \brief Scatters data from one processes to all others
    1891             : !> \param[in] msg_scatter     Data to scatter (for root process)
    1892             : !> \param[in] root            Process which scatters data
    1893             : !> \param[in] comm             Message passing environment identifier
    1894             : !> \par MPI mapping
    1895             : !>      mpi_scatter
    1896             : ! **************************************************************************************************
    1897           0 :    SUBROUTINE mp_iscatter_${nametype1}$ (msg_scatter, msg, root, comm, request)
    1898             :       ${type1}$, INTENT(IN)                      :: msg_scatter(:)
    1899             :       ${type1}$, INTENT(INOUT)                   :: msg
    1900             :       INTEGER, INTENT(IN)                      :: root
    1901             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1902             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    1903             : 
    1904             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iscatter_${nametype1}$'
    1905             : 
    1906             :       INTEGER                                  :: handle
    1907             : #if defined(__parallel)
    1908             :       INTEGER :: ierr, msglen
    1909             : #endif
    1910             : 
    1911           0 :       CALL mp_timeset(routineN, handle)
    1912             : 
    1913             : #if defined(__parallel)
    1914             : #if !defined(__GNUC__) || __GNUC__ >= 9
    1915           0 :       CPASSERT(IS_CONTIGUOUS(msg_scatter))
    1916             : #endif
    1917           0 :       msglen = 1
    1918             :       CALL mpi_iscatter(msg_scatter, msglen, ${mpi_type1}$, msg, &
    1919           0 :                         msglen, ${mpi_type1}$, root, comm%handle, request%handle, ierr)
    1920           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iscatter @ "//routineN)
    1921           0 :       CALL add_perf(perf_id=24, count=1, msg_size=1*${bytes1}$)
    1922             : #else
    1923             :       MARK_USED(root)
    1924             :       MARK_USED(comm)
    1925             :       msg = msg_scatter(1)
    1926             :       request = mp_request_null
    1927             : #endif
    1928           0 :       CALL mp_timestop(handle)
    1929           0 :    END SUBROUTINE mp_iscatter_${nametype1}$
    1930             : 
    1931             : ! **************************************************************************************************
    1932             : !> \brief Scatters data from one processes to all others
    1933             : !> \param[in] msg_scatter     Data to scatter (for root process)
    1934             : !> \param[in] root            Process which scatters data
    1935             : !> \param[in] comm            Message passing environment identifier
    1936             : !> \par MPI mapping
    1937             : !>      mpi_scatter
    1938             : ! **************************************************************************************************
    1939           0 :    SUBROUTINE mp_iscatter_${nametype1}$v2(msg_scatter, msg, root, comm, request)
    1940             :       ${type1}$, INTENT(IN)                      :: msg_scatter(:, :)
    1941             :       ${type1}$, INTENT(INOUT)                   :: msg(:)
    1942             :       INTEGER, INTENT(IN)                      :: root
    1943             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1944             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    1945             : 
    1946             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iscatter_${nametype1}$v2'
    1947             : 
    1948             :       INTEGER                                  :: handle
    1949             : #if defined(__parallel)
    1950             :       INTEGER :: ierr, msglen
    1951             : #endif
    1952             : 
    1953           0 :       CALL mp_timeset(routineN, handle)
    1954             : 
    1955             : #if defined(__parallel)
    1956             : #if !defined(__GNUC__) || __GNUC__ >= 9
    1957           0 :       CPASSERT(IS_CONTIGUOUS(msg_scatter))
    1958             : #endif
    1959           0 :       msglen = SIZE(msg)
    1960             :       CALL mpi_iscatter(msg_scatter, msglen, ${mpi_type1}$, msg, &
    1961           0 :                         msglen, ${mpi_type1}$, root, comm%handle, request%handle, ierr)
    1962           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iscatter @ "//routineN)
    1963           0 :       CALL add_perf(perf_id=24, count=1, msg_size=1*${bytes1}$)
    1964             : #else
    1965             :       MARK_USED(root)
    1966             :       MARK_USED(comm)
    1967             :       msg(:) = msg_scatter(:, 1)
    1968             :       request = mp_request_null
    1969             : #endif
    1970           0 :       CALL mp_timestop(handle)
    1971           0 :    END SUBROUTINE mp_iscatter_${nametype1}$v2
    1972             : 
    1973             : ! **************************************************************************************************
    1974             : !> \brief Scatters data from one processes to all others
    1975             : !> \param[in] msg_scatter     Data to scatter (for root process)
    1976             : !> \param[in] root            Process which scatters data
    1977             : !> \param[in] comm            Message passing environment identifier
    1978             : !> \par MPI mapping
    1979             : !>      mpi_scatter
    1980             : ! **************************************************************************************************
    1981           0 :    SUBROUTINE mp_iscatterv_${nametype1}$v(msg_scatter, sendcounts, displs, msg, recvcount, root, comm, request)
    1982             :       ${type1}$, INTENT(IN)                      :: msg_scatter(:)
    1983             :       INTEGER, INTENT(IN)                      :: sendcounts(:), displs(:)
    1984             :       ${type1}$, INTENT(INOUT)                   :: msg(:)
    1985             :       INTEGER, INTENT(IN)                      :: recvcount, root
    1986             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    1987             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    1988             : 
    1989             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iscatterv_${nametype1}$v'
    1990             : 
    1991             :       INTEGER                                  :: handle
    1992             : #if defined(__parallel)
    1993             :       INTEGER :: ierr
    1994             : #endif
    1995             : 
    1996           0 :       CALL mp_timeset(routineN, handle)
    1997             : 
    1998             : #if defined(__parallel)
    1999             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2000           0 :       CPASSERT(IS_CONTIGUOUS(msg_scatter))
    2001           0 :       CPASSERT(IS_CONTIGUOUS(msg))
    2002           0 :       CPASSERT(IS_CONTIGUOUS(sendcounts))
    2003           0 :       CPASSERT(IS_CONTIGUOUS(displs))
    2004             : #endif
    2005             :       CALL mpi_iscatterv(msg_scatter, sendcounts, displs, ${mpi_type1}$, msg, &
    2006           0 :                          recvcount, ${mpi_type1}$, root, comm%handle, request%handle, ierr)
    2007           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iscatterv @ "//routineN)
    2008           0 :       CALL add_perf(perf_id=24, count=1, msg_size=1*${bytes1}$)
    2009             : #else
    2010             :       MARK_USED(sendcounts)
    2011             :       MARK_USED(displs)
    2012             :       MARK_USED(recvcount)
    2013             :       MARK_USED(root)
    2014             :       MARK_USED(comm)
    2015             :       msg(1:recvcount) = msg_scatter(1 + displs(1):1 + displs(1) + sendcounts(1))
    2016             :       request = mp_request_null
    2017             : #endif
    2018           0 :       CALL mp_timestop(handle)
    2019           0 :    END SUBROUTINE mp_iscatterv_${nametype1}$v
    2020             : 
    2021             : ! **************************************************************************************************
    2022             : !> \brief Gathers a datum from all processes to one
    2023             : !> \param[in] msg             Datum to send to root
    2024             : !> \param[out] msg_gather     Received data (on root)
    2025             : !> \param[in] root            Process which gathers the data
    2026             : !> \param[in] comm            Message passing environment identifier
    2027             : !> \par MPI mapping
    2028             : !>      mpi_gather
    2029             : ! **************************************************************************************************
    2030           0 :    SUBROUTINE mp_gather_${nametype1}$ (msg, msg_gather, root, comm)
    2031             :       ${type1}$, INTENT(IN)                      :: msg
    2032             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:)
    2033             :       INTEGER, INTENT(IN)                      :: root
    2034             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2035             : 
    2036             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$'
    2037             : 
    2038             :       INTEGER                                  :: handle
    2039             : #if defined(__parallel)
    2040             :       INTEGER :: ierr, msglen
    2041             : #endif
    2042             : 
    2043           0 :       CALL mp_timeset(routineN, handle)
    2044             : 
    2045             : #if defined(__parallel)
    2046           0 :       msglen = 1
    2047             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2048           0 :                       msglen, ${mpi_type1}$, root, comm%handle, ierr)
    2049           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2050           0 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2051             : #else
    2052             :       MARK_USED(root)
    2053             :       MARK_USED(comm)
    2054             :       msg_gather(1) = msg
    2055             : #endif
    2056           0 :       CALL mp_timestop(handle)
    2057           0 :    END SUBROUTINE mp_gather_${nametype1}$
    2058             : 
    2059             : ! **************************************************************************************************
    2060             : !> \brief Gathers a datum from all processes to one, uses the source process of comm
    2061             : !> \param[in] msg             Datum to send to root
    2062             : !> \param[out] msg_gather     Received data (on root)
    2063             : !> \param[in] comm            Message passing environment identifier
    2064             : !> \par MPI mapping
    2065             : !>      mpi_gather
    2066             : ! **************************************************************************************************
    2067          30 :    SUBROUTINE mp_gather_${nametype1}$_src(msg, msg_gather, comm)
    2068             :       ${type1}$, INTENT(IN)                      :: msg
    2069             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:)
    2070             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2071             : 
    2072             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$_src'
    2073             : 
    2074             :       INTEGER                                  :: handle
    2075             : #if defined(__parallel)
    2076             :       INTEGER :: ierr, msglen
    2077             : #endif
    2078             : 
    2079          30 :       CALL mp_timeset(routineN, handle)
    2080             : 
    2081             : #if defined(__parallel)
    2082          30 :       msglen = 1
    2083             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2084          30 :                       msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    2085          30 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2086          30 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2087             : #else
    2088             :       MARK_USED(comm)
    2089             :       msg_gather(1) = msg
    2090             : #endif
    2091          30 :       CALL mp_timestop(handle)
    2092          30 :    END SUBROUTINE mp_gather_${nametype1}$_src
    2093             : 
    2094             : ! **************************************************************************************************
    2095             : !> \brief Gathers data from all processes to one
    2096             : !> \param[in] msg             Datum to send to root
    2097             : !> \param msg_gather ...
    2098             : !> \param root ...
    2099             : !> \param comm ...
    2100             : !> \par Data length
    2101             : !>      All data (msg) is equal-sized
    2102             : !> \par MPI mapping
    2103             : !>      mpi_gather
    2104             : !> \note see mp_gather_${nametype1}$
    2105             : ! **************************************************************************************************
    2106           0 :    SUBROUTINE mp_gather_${nametype1}$v(msg, msg_gather, root, comm)
    2107             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:)
    2108             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:)
    2109             :       INTEGER, INTENT(IN)                      :: root
    2110             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2111             : 
    2112             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$v'
    2113             : 
    2114             :       INTEGER                                  :: handle
    2115             : #if defined(__parallel)
    2116             :       INTEGER :: ierr, msglen
    2117             : #endif
    2118             : 
    2119           0 :       CALL mp_timeset(routineN, handle)
    2120             : 
    2121             : #if defined(__parallel)
    2122           0 :       msglen = SIZE(msg)
    2123             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2124           0 :                       msglen, ${mpi_type1}$, root, comm%handle, ierr)
    2125           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2126           0 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2127             : #else
    2128             :       MARK_USED(root)
    2129             :       MARK_USED(comm)
    2130             :       msg_gather = msg
    2131             : #endif
    2132           0 :       CALL mp_timestop(handle)
    2133           0 :    END SUBROUTINE mp_gather_${nametype1}$v
    2134             : 
    2135             : ! **************************************************************************************************
    2136             : !> \brief Gathers data from all processes to one. Gathers from comm%source
    2137             : !> \param[in] msg             Datum to send to root
    2138             : !> \param msg_gather ...
    2139             : !> \param comm ...
    2140             : !> \par Data length
    2141             : !>      All data (msg) is equal-sized
    2142             : !> \par MPI mapping
    2143             : !>      mpi_gather
    2144             : !> \note see mp_gather_${nametype1}$
    2145             : ! **************************************************************************************************
    2146           0 :    SUBROUTINE mp_gather_${nametype1}$v_src(msg, msg_gather, comm)
    2147             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:)
    2148             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:)
    2149             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2150             : 
    2151             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$v_src'
    2152             : 
    2153             :       INTEGER                                  :: handle
    2154             : #if defined(__parallel)
    2155             :       INTEGER :: ierr, msglen
    2156             : #endif
    2157             : 
    2158           0 :       CALL mp_timeset(routineN, handle)
    2159             : 
    2160             : #if defined(__parallel)
    2161           0 :       msglen = SIZE(msg)
    2162             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2163           0 :                       msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    2164           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2165           0 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2166             : #else
    2167             :       MARK_USED(comm)
    2168             :       msg_gather = msg
    2169             : #endif
    2170           0 :       CALL mp_timestop(handle)
    2171           0 :    END SUBROUTINE mp_gather_${nametype1}$v_src
    2172             : 
    2173             : ! **************************************************************************************************
    2174             : !> \brief Gathers data from all processes to one
    2175             : !> \param[in] msg             Datum to send to root
    2176             : !> \param msg_gather ...
    2177             : !> \param root ...
    2178             : !> \param comm ...
    2179             : !> \par Data length
    2180             : !>      All data (msg) is equal-sized
    2181             : !> \par MPI mapping
    2182             : !>      mpi_gather
    2183             : !> \note see mp_gather_${nametype1}$
    2184             : ! **************************************************************************************************
    2185           0 :    SUBROUTINE mp_gather_${nametype1}$m(msg, msg_gather, root, comm)
    2186             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:, :)
    2187             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:, :)
    2188             :       INTEGER, INTENT(IN)                      :: root
    2189             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2190             : 
    2191             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$m'
    2192             : 
    2193             :       INTEGER                                  :: handle
    2194             : #if defined(__parallel)
    2195             :       INTEGER :: ierr, msglen
    2196             : #endif
    2197             : 
    2198           0 :       CALL mp_timeset(routineN, handle)
    2199             : 
    2200             : #if defined(__parallel)
    2201           0 :       msglen = SIZE(msg)
    2202             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2203           0 :                       msglen, ${mpi_type1}$, root, comm%handle, ierr)
    2204           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2205           0 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2206             : #else
    2207             :       MARK_USED(root)
    2208             :       MARK_USED(comm)
    2209             :       msg_gather = msg
    2210             : #endif
    2211           0 :       CALL mp_timestop(handle)
    2212           0 :    END SUBROUTINE mp_gather_${nametype1}$m
    2213             : 
    2214             : ! **************************************************************************************************
    2215             : !> \brief Gathers data from all processes to one. Gathers from comm%source
    2216             : !> \param[in] msg             Datum to send to root
    2217             : !> \param msg_gather ...
    2218             : !> \param comm ...
    2219             : !> \par Data length
    2220             : !>      All data (msg) is equal-sized
    2221             : !> \par MPI mapping
    2222             : !>      mpi_gather
    2223             : !> \note see mp_gather_${nametype1}$
    2224             : ! **************************************************************************************************
    2225          82 :    SUBROUTINE mp_gather_${nametype1}$m_src(msg, msg_gather, comm)
    2226             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:, :)
    2227             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msg_gather(:, :)
    2228             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2229             : 
    2230             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gather_${nametype1}$m_src'
    2231             : 
    2232             :       INTEGER                                  :: handle
    2233             : #if defined(__parallel)
    2234             :       INTEGER :: ierr, msglen
    2235             : #endif
    2236             : 
    2237          82 :       CALL mp_timeset(routineN, handle)
    2238             : 
    2239             : #if defined(__parallel)
    2240         246 :       msglen = SIZE(msg)
    2241             :       CALL mpi_gather(msg, msglen, ${mpi_type1}$, msg_gather, &
    2242          82 :                       msglen, ${mpi_type1}$, comm%source, comm%handle, ierr)
    2243          82 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gather @ "//routineN)
    2244          82 :       CALL add_perf(perf_id=4, count=1, msg_size=msglen*${bytes1}$)
    2245             : #else
    2246             :       MARK_USED(comm)
    2247             :       msg_gather = msg
    2248             : #endif
    2249          82 :       CALL mp_timestop(handle)
    2250          82 :    END SUBROUTINE mp_gather_${nametype1}$m_src
    2251             : 
    2252             : ! **************************************************************************************************
    2253             : !> \brief Gathers data from all processes to one.
    2254             : !> \param[in] sendbuf         Data to send to root
    2255             : !> \param[out] recvbuf        Received data (on root)
    2256             : !> \param[in] recvcounts      Sizes of data received from processes
    2257             : !> \param[in] displs          Offsets of data received from processes
    2258             : !> \param[in] root            Process which gathers the data
    2259             : !> \param[in] comm            Message passing environment identifier
    2260             : !> \par Data length
    2261             : !>      Data can have different lengths
    2262             : !> \par Offsets
    2263             : !>      Offsets start at 0
    2264             : !> \par MPI mapping
    2265             : !>      mpi_gather
    2266             : ! **************************************************************************************************
    2267           0 :    SUBROUTINE mp_gatherv_${nametype1}$v(sendbuf, recvbuf, recvcounts, displs, root, comm)
    2268             : 
    2269             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: sendbuf
    2270             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(OUT)       :: recvbuf
    2271             :       INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: recvcounts, displs
    2272             :       INTEGER, INTENT(IN)                      :: root
    2273             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2274             : 
    2275             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gatherv_${nametype1}$v'
    2276             : 
    2277             :       INTEGER                                  :: handle
    2278             : #if defined(__parallel)
    2279             :       INTEGER                                  :: ierr, sendcount
    2280             : #endif
    2281             : 
    2282           0 :       CALL mp_timeset(routineN, handle)
    2283             : 
    2284             : #if defined(__parallel)
    2285           0 :       sendcount = SIZE(sendbuf)
    2286             :       CALL mpi_gatherv(sendbuf, sendcount, ${mpi_type1}$, &
    2287             :                        recvbuf, recvcounts, displs, ${mpi_type1}$, &
    2288           0 :                        root, comm%handle, ierr)
    2289           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gatherv @ "//routineN)
    2290             :       CALL add_perf(perf_id=4, &
    2291             :                     count=1, &
    2292           0 :                     msg_size=sendcount*${bytes1}$)
    2293             : #else
    2294             :       MARK_USED(recvcounts)
    2295             :       MARK_USED(root)
    2296             :       MARK_USED(comm)
    2297             :       recvbuf(1 + displs(1):) = sendbuf
    2298             : #endif
    2299           0 :       CALL mp_timestop(handle)
    2300           0 :    END SUBROUTINE mp_gatherv_${nametype1}$v
    2301             : 
    2302             : ! **************************************************************************************************
    2303             : !> \brief Gathers data from all processes to one. Gathers from comm%source
    2304             : !> \param[in] sendbuf         Data to send to root
    2305             : !> \param[out] recvbuf        Received data (on root)
    2306             : !> \param[in] recvcounts      Sizes of data received from processes
    2307             : !> \param[in] displs          Offsets of data received from processes
    2308             : !> \param[in] comm            Message passing environment identifier
    2309             : !> \par Data length
    2310             : !>      Data can have different lengths
    2311             : !> \par Offsets
    2312             : !>      Offsets start at 0
    2313             : !> \par MPI mapping
    2314             : !>      mpi_gather
    2315             : ! **************************************************************************************************
    2316         210 :    SUBROUTINE mp_gatherv_${nametype1}$v_src(sendbuf, recvbuf, recvcounts, displs, comm)
    2317             : 
    2318             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: sendbuf
    2319             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(OUT)       :: recvbuf
    2320             :       INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: recvcounts, displs
    2321             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2322             : 
    2323             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gatherv_${nametype1}$v_src'
    2324             : 
    2325             :       INTEGER                                  :: handle
    2326             : #if defined(__parallel)
    2327             :       INTEGER                                  :: ierr, sendcount
    2328             : #endif
    2329             : 
    2330         210 :       CALL mp_timeset(routineN, handle)
    2331             : 
    2332             : #if defined(__parallel)
    2333         210 :       sendcount = SIZE(sendbuf)
    2334             :       CALL mpi_gatherv(sendbuf, sendcount, ${mpi_type1}$, &
    2335             :                        recvbuf, recvcounts, displs, ${mpi_type1}$, &
    2336         210 :                        comm%source, comm%handle, ierr)
    2337         210 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gatherv @ "//routineN)
    2338             :       CALL add_perf(perf_id=4, &
    2339             :                     count=1, &
    2340         210 :                     msg_size=sendcount*${bytes1}$)
    2341             : #else
    2342             :       MARK_USED(recvcounts)
    2343             :       MARK_USED(comm)
    2344             :       recvbuf(1 + displs(1):) = sendbuf
    2345             : #endif
    2346         210 :       CALL mp_timestop(handle)
    2347         210 :    END SUBROUTINE mp_gatherv_${nametype1}$v_src
    2348             : 
    2349             : ! **************************************************************************************************
    2350             : !> \brief Gathers data from all processes to one.
    2351             : !> \param[in] sendbuf         Data to send to root
    2352             : !> \param[out] recvbuf        Received data (on root)
    2353             : !> \param[in] recvcounts      Sizes of data received from processes
    2354             : !> \param[in] displs          Offsets of data received from processes
    2355             : !> \param[in] root            Process which gathers the data
    2356             : !> \param[in] comm            Message passing environment identifier
    2357             : !> \par Data length
    2358             : !>      Data can have different lengths
    2359             : !> \par Offsets
    2360             : !>      Offsets start at 0
    2361             : !> \par MPI mapping
    2362             : !>      mpi_gather
    2363             : ! **************************************************************************************************
    2364           0 :    SUBROUTINE mp_gatherv_${nametype1}$m2(sendbuf, recvbuf, recvcounts, displs, root, comm)
    2365             : 
    2366             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(IN)        :: sendbuf
    2367             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(OUT)       :: recvbuf
    2368             :       INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: recvcounts, displs
    2369             :       INTEGER, INTENT(IN)                      :: root
    2370             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2371             : 
    2372             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gatherv_${nametype1}$m2'
    2373             : 
    2374             :       INTEGER                                  :: handle
    2375             : #if defined(__parallel)
    2376             :       INTEGER                                  :: ierr, sendcount
    2377             : #endif
    2378             : 
    2379           0 :       CALL mp_timeset(routineN, handle)
    2380             : 
    2381             : #if defined(__parallel)
    2382           0 :       sendcount = SIZE(sendbuf)
    2383             :       CALL mpi_gatherv(sendbuf, sendcount, ${mpi_type1}$, &
    2384             :                        recvbuf, recvcounts, displs, ${mpi_type1}$, &
    2385           0 :                        root, comm%handle, ierr)
    2386           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gatherv @ "//routineN)
    2387             :       CALL add_perf(perf_id=4, &
    2388             :                     count=1, &
    2389           0 :                     msg_size=sendcount*${bytes1}$)
    2390             : #else
    2391             :       MARK_USED(recvcounts)
    2392             :       MARK_USED(root)
    2393             :       MARK_USED(comm)
    2394             :       recvbuf(:, 1 + displs(1):) = sendbuf
    2395             : #endif
    2396           0 :       CALL mp_timestop(handle)
    2397           0 :    END SUBROUTINE mp_gatherv_${nametype1}$m2
    2398             : 
    2399             : ! **************************************************************************************************
    2400             : !> \brief Gathers data from all processes to one.
    2401             : !> \param[in] sendbuf         Data to send to root
    2402             : !> \param[out] recvbuf        Received data (on root)
    2403             : !> \param[in] recvcounts      Sizes of data received from processes
    2404             : !> \param[in] displs          Offsets of data received from processes
    2405             : !> \param[in] comm            Message passing environment identifier
    2406             : !> \par Data length
    2407             : !>      Data can have different lengths
    2408             : !> \par Offsets
    2409             : !>      Offsets start at 0
    2410             : !> \par MPI mapping
    2411             : !>      mpi_gather
    2412             : ! **************************************************************************************************
    2413           0 :    SUBROUTINE mp_gatherv_${nametype1}$m2_src(sendbuf, recvbuf, recvcounts, displs, comm)
    2414             : 
    2415             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(IN)        :: sendbuf
    2416             :       ${type1}$, DIMENSION(:, :), CONTIGUOUS, INTENT(OUT)       :: recvbuf
    2417             :       INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: recvcounts, displs
    2418             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2419             : 
    2420             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_gatherv_${nametype1}$m2_src'
    2421             : 
    2422             :       INTEGER                                  :: handle
    2423             : #if defined(__parallel)
    2424             :       INTEGER                                  :: ierr, sendcount
    2425             : #endif
    2426             : 
    2427           0 :       CALL mp_timeset(routineN, handle)
    2428             : 
    2429             : #if defined(__parallel)
    2430           0 :       sendcount = SIZE(sendbuf)
    2431             :       CALL mpi_gatherv(sendbuf, sendcount, ${mpi_type1}$, &
    2432             :                        recvbuf, recvcounts, displs, ${mpi_type1}$, &
    2433           0 :                        comm%source, comm%handle, ierr)
    2434           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gatherv @ "//routineN)
    2435             :       CALL add_perf(perf_id=4, &
    2436             :                     count=1, &
    2437           0 :                     msg_size=sendcount*${bytes1}$)
    2438             : #else
    2439             :       MARK_USED(recvcounts)
    2440             :       MARK_USED(comm)
    2441             :       recvbuf(:, 1 + displs(1):) = sendbuf
    2442             : #endif
    2443           0 :       CALL mp_timestop(handle)
    2444           0 :    END SUBROUTINE mp_gatherv_${nametype1}$m2_src
    2445             : 
    2446             : ! **************************************************************************************************
    2447             : !> \brief Gathers data from all processes to one.
    2448             : !> \param[in] sendbuf         Data to send to root
    2449             : !> \param[out] recvbuf        Received data (on root)
    2450             : !> \param[in] recvcounts      Sizes of data received from processes
    2451             : !> \param[in] displs          Offsets of data received from processes
    2452             : !> \param[in] root            Process which gathers the data
    2453             : !> \param[in] comm            Message passing environment identifier
    2454             : !> \par Data length
    2455             : !>      Data can have different lengths
    2456             : !> \par Offsets
    2457             : !>      Offsets start at 0
    2458             : !> \par MPI mapping
    2459             : !>      mpi_gather
    2460             : ! **************************************************************************************************
    2461           0 :    SUBROUTINE mp_igatherv_${nametype1}$v(sendbuf, sendcount, recvbuf, recvcounts, displs, root, comm, request)
    2462             :       ${type1}$, DIMENSION(:), INTENT(IN)        :: sendbuf
    2463             :       ${type1}$, DIMENSION(:), INTENT(OUT)       :: recvbuf
    2464             :       INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN)        :: recvcounts, displs
    2465             :       INTEGER, INTENT(IN)                      :: sendcount, root
    2466             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2467             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    2468             : 
    2469             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_igatherv_${nametype1}$v'
    2470             : 
    2471             :       INTEGER                                  :: handle
    2472             : #if defined(__parallel)
    2473             :       INTEGER :: ierr
    2474             : #endif
    2475             : 
    2476           0 :       CALL mp_timeset(routineN, handle)
    2477             : 
    2478             : #if defined(__parallel)
    2479             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2480           0 :       CPASSERT(IS_CONTIGUOUS(sendbuf))
    2481           0 :       CPASSERT(IS_CONTIGUOUS(recvbuf))
    2482             :       CPASSERT(IS_CONTIGUOUS(recvcounts))
    2483             :       CPASSERT(IS_CONTIGUOUS(displs))
    2484             : #endif
    2485             :       CALL mpi_igatherv(sendbuf, sendcount, ${mpi_type1}$, &
    2486             :                         recvbuf, recvcounts, displs, ${mpi_type1}$, &
    2487           0 :                         root, comm%handle, request%handle, ierr)
    2488           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_gatherv @ "//routineN)
    2489             :       CALL add_perf(perf_id=24, &
    2490             :                     count=1, &
    2491           0 :                     msg_size=sendcount*${bytes1}$)
    2492             : #else
    2493             :       MARK_USED(sendcount)
    2494             :       MARK_USED(recvcounts)
    2495             :       MARK_USED(root)
    2496             :       MARK_USED(comm)
    2497             :       recvbuf(1 + displs(1):1 + displs(1) + recvcounts(1)) = sendbuf(1:sendcount)
    2498             :       request = mp_request_null
    2499             : #endif
    2500           0 :       CALL mp_timestop(handle)
    2501           0 :    END SUBROUTINE mp_igatherv_${nametype1}$v
    2502             : 
    2503             : ! **************************************************************************************************
    2504             : !> \brief Gathers a datum from all processes and all processes receive the
    2505             : !>        same data
    2506             : !> \param[in] msgout          Datum to send
    2507             : !> \param[out] msgin          Received data
    2508             : !> \param[in] comm             Message passing environment identifier
    2509             : !> \par Data size
    2510             : !>      All processes send equal-sized data
    2511             : !> \par MPI mapping
    2512             : !>      mpi_allgather
    2513             : ! **************************************************************************************************
    2514      346088 :    SUBROUTINE mp_allgather_${nametype1}$ (msgout, msgin, comm)
    2515             :       ${type1}$, INTENT(IN)                      :: msgout
    2516             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:)
    2517             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2518             : 
    2519             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$'
    2520             : 
    2521             :       INTEGER                                  :: handle
    2522             : #if defined(__parallel)
    2523             :       INTEGER                                  :: ierr, rcount, scount
    2524             : #endif
    2525             : 
    2526      346088 :       CALL mp_timeset(routineN, handle)
    2527             : 
    2528             : #if defined(__parallel)
    2529      346088 :       scount = 1
    2530      346088 :       rcount = 1
    2531             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2532             :                          msgin, rcount, ${mpi_type1}$, &
    2533      346088 :                          comm%handle, ierr)
    2534      346088 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2535             : #else
    2536             :       MARK_USED(comm)
    2537             :       msgin = msgout
    2538             : #endif
    2539      346088 :       CALL mp_timestop(handle)
    2540      346088 :    END SUBROUTINE mp_allgather_${nametype1}$
    2541             : 
    2542             : ! **************************************************************************************************
    2543             : !> \brief Gathers a datum from all processes and all processes receive the
    2544             : !>        same data
    2545             : !> \param[in] msgout          Datum to send
    2546             : !> \param[out] msgin          Received data
    2547             : !> \param[in] comm            Message passing environment identifier
    2548             : !> \par Data size
    2549             : !>      All processes send equal-sized data
    2550             : !> \par MPI mapping
    2551             : !>      mpi_allgather
    2552             : ! **************************************************************************************************
    2553           0 :    SUBROUTINE mp_allgather_${nametype1}$2(msgout, msgin, comm)
    2554             :       ${type1}$, INTENT(IN)                      :: msgout
    2555             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:, :)
    2556             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2557             : 
    2558             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$2'
    2559             : 
    2560             :       INTEGER                                  :: handle
    2561             : #if defined(__parallel)
    2562             :       INTEGER                                  :: ierr, rcount, scount
    2563             : #endif
    2564             : 
    2565           0 :       CALL mp_timeset(routineN, handle)
    2566             : 
    2567             : #if defined(__parallel)
    2568           0 :       scount = 1
    2569           0 :       rcount = 1
    2570             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2571             :                          msgin, rcount, ${mpi_type1}$, &
    2572           0 :                          comm%handle, ierr)
    2573           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2574             : #else
    2575             :       MARK_USED(comm)
    2576             :       msgin = msgout
    2577             : #endif
    2578           0 :       CALL mp_timestop(handle)
    2579           0 :    END SUBROUTINE mp_allgather_${nametype1}$2
    2580             : 
    2581             : ! **************************************************************************************************
    2582             : !> \brief Gathers a datum from all processes and all processes receive the
    2583             : !>        same data
    2584             : !> \param[in] msgout          Datum to send
    2585             : !> \param[out] msgin          Received data
    2586             : !> \param[in] comm            Message passing environment identifier
    2587             : !> \par Data size
    2588             : !>      All processes send equal-sized data
    2589             : !> \par MPI mapping
    2590             : !>      mpi_allgather
    2591             : ! **************************************************************************************************
    2592           0 :    SUBROUTINE mp_iallgather_${nametype1}$ (msgout, msgin, comm, request)
    2593             :       ${type1}$, INTENT(IN)                      :: msgout
    2594             :       ${type1}$, INTENT(OUT)                     :: msgin(:)
    2595             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2596             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    2597             : 
    2598             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$'
    2599             : 
    2600             :       INTEGER                                  :: handle
    2601             : #if defined(__parallel)
    2602             :       INTEGER                                  :: ierr, rcount, scount
    2603             : #endif
    2604             : 
    2605           0 :       CALL mp_timeset(routineN, handle)
    2606             : 
    2607             : #if defined(__parallel)
    2608             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2609           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2610             : #endif
    2611           0 :       scount = 1
    2612           0 :       rcount = 1
    2613             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2614             :                           msgin, rcount, ${mpi_type1}$, &
    2615           0 :                           comm%handle, request%handle, ierr)
    2616           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2617             : #else
    2618             :       MARK_USED(comm)
    2619             :       msgin = msgout
    2620             :       request = mp_request_null
    2621             : #endif
    2622           0 :       CALL mp_timestop(handle)
    2623           0 :    END SUBROUTINE mp_iallgather_${nametype1}$
    2624             : 
    2625             : ! **************************************************************************************************
    2626             : !> \brief Gathers vector data from all processes and all processes receive the
    2627             : !>        same data
    2628             : !> \param[in] msgout          Rank-1 data to send
    2629             : !> \param[out] msgin          Received data
    2630             : !> \param[in] comm            Message passing environment identifier
    2631             : !> \par Data size
    2632             : !>      All processes send equal-sized data
    2633             : !> \par Ranks
    2634             : !>      The last rank counts the processes
    2635             : !> \par MPI mapping
    2636             : !>      mpi_allgather
    2637             : ! **************************************************************************************************
    2638        4878 :    SUBROUTINE mp_allgather_${nametype1}$12(msgout, msgin, comm)
    2639             :       ${type1}$, INTENT(IN), CONTIGUOUS                      :: msgout(:)
    2640             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:, :)
    2641             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2642             : 
    2643             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$12'
    2644             : 
    2645             :       INTEGER                                  :: handle
    2646             : #if defined(__parallel)
    2647             :       INTEGER                                  :: ierr, rcount, scount
    2648             : #endif
    2649             : 
    2650        4878 :       CALL mp_timeset(routineN, handle)
    2651             : 
    2652             : #if defined(__parallel)
    2653        4878 :       scount = SIZE(msgout(:))
    2654        4878 :       rcount = scount
    2655             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2656             :                          msgin, rcount, ${mpi_type1}$, &
    2657        4878 :                          comm%handle, ierr)
    2658        4878 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2659             : #else
    2660             :       MARK_USED(comm)
    2661             :       msgin(:, 1) = msgout(:)
    2662             : #endif
    2663        4878 :       CALL mp_timestop(handle)
    2664        4878 :    END SUBROUTINE mp_allgather_${nametype1}$12
    2665             : 
    2666             : ! **************************************************************************************************
    2667             : !> \brief Gathers matrix data from all processes and all processes receive the
    2668             : !>        same data
    2669             : !> \param[in] msgout          Rank-2 data to send
    2670             : !> \param msgin ...
    2671             : !> \param comm ...
    2672             : !> \note see mp_allgather_${nametype1}$12
    2673             : ! **************************************************************************************************
    2674       89628 :    SUBROUTINE mp_allgather_${nametype1}$23(msgout, msgin, comm)
    2675             :       ${type1}$, INTENT(IN), CONTIGUOUS                      :: msgout(:, :)
    2676             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:, :, :)
    2677             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2678             : 
    2679             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$23'
    2680             : 
    2681             :       INTEGER                                  :: handle
    2682             : #if defined(__parallel)
    2683             :       INTEGER                                  :: ierr, rcount, scount
    2684             : #endif
    2685             : 
    2686       89628 :       CALL mp_timeset(routineN, handle)
    2687             : 
    2688             : #if defined(__parallel)
    2689      268884 :       scount = SIZE(msgout(:, :))
    2690       89628 :       rcount = scount
    2691             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2692             :                          msgin, rcount, ${mpi_type1}$, &
    2693       89628 :                          comm%handle, ierr)
    2694       89628 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2695             : #else
    2696             :       MARK_USED(comm)
    2697             :       msgin(:, :, 1) = msgout(:, :)
    2698             : #endif
    2699       89628 :       CALL mp_timestop(handle)
    2700       89628 :    END SUBROUTINE mp_allgather_${nametype1}$23
    2701             : 
    2702             : ! **************************************************************************************************
    2703             : !> \brief Gathers rank-3 data from all processes and all processes receive the
    2704             : !>        same data
    2705             : !> \param[in] msgout          Rank-3 data to send
    2706             : !> \param msgin ...
    2707             : !> \param comm ...
    2708             : !> \note see mp_allgather_${nametype1}$12
    2709             : ! **************************************************************************************************
    2710         438 :    SUBROUTINE mp_allgather_${nametype1}$34(msgout, msgin, comm)
    2711             :       ${type1}$, INTENT(IN), CONTIGUOUS                      :: msgout(:, :, :)
    2712             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:, :, :, :)
    2713             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2714             : 
    2715             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$34'
    2716             : 
    2717             :       INTEGER                                  :: handle
    2718             : #if defined(__parallel)
    2719             :       INTEGER                                  :: ierr, rcount, scount
    2720             : #endif
    2721             : 
    2722         438 :       CALL mp_timeset(routineN, handle)
    2723             : 
    2724             : #if defined(__parallel)
    2725        1752 :       scount = SIZE(msgout(:, :, :))
    2726         438 :       rcount = scount
    2727             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2728             :                          msgin, rcount, ${mpi_type1}$, &
    2729         438 :                          comm%handle, ierr)
    2730         438 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2731             : #else
    2732             :       MARK_USED(comm)
    2733             :       msgin(:, :, :, 1) = msgout(:, :, :)
    2734             : #endif
    2735         438 :       CALL mp_timestop(handle)
    2736         438 :    END SUBROUTINE mp_allgather_${nametype1}$34
    2737             : 
    2738             : ! **************************************************************************************************
    2739             : !> \brief Gathers rank-2 data from all processes and all processes receive the
    2740             : !>        same data
    2741             : !> \param[in] msgout          Rank-2 data to send
    2742             : !> \param msgin ...
    2743             : !> \param comm ...
    2744             : !> \note see mp_allgather_${nametype1}$12
    2745             : ! **************************************************************************************************
    2746           0 :    SUBROUTINE mp_allgather_${nametype1}$22(msgout, msgin, comm)
    2747             :       ${type1}$, INTENT(IN), CONTIGUOUS                      :: msgout(:, :)
    2748             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msgin(:, :)
    2749             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2750             : 
    2751             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgather_${nametype1}$22'
    2752             : 
    2753             :       INTEGER                                  :: handle
    2754             : #if defined(__parallel)
    2755             :       INTEGER                                  :: ierr, rcount, scount
    2756             : #endif
    2757             : 
    2758           0 :       CALL mp_timeset(routineN, handle)
    2759             : 
    2760             : #if defined(__parallel)
    2761           0 :       scount = SIZE(msgout(:, :))
    2762           0 :       rcount = scount
    2763             :       CALL MPI_ALLGATHER(msgout, scount, ${mpi_type1}$, &
    2764             :                          msgin, rcount, ${mpi_type1}$, &
    2765           0 :                          comm%handle, ierr)
    2766           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgather @ "//routineN)
    2767             : #else
    2768             :       MARK_USED(comm)
    2769             :       msgin(:, :) = msgout(:, :)
    2770             : #endif
    2771           0 :       CALL mp_timestop(handle)
    2772           0 :    END SUBROUTINE mp_allgather_${nametype1}$22
    2773             : 
    2774             : ! **************************************************************************************************
    2775             : !> \brief Gathers rank-1 data from all processes and all processes receive the
    2776             : !>        same data
    2777             : !> \param[in] msgout          Rank-1 data to send
    2778             : !> \param msgin ...
    2779             : !> \param comm ...
    2780             : !> \param request ...
    2781             : !> \note see mp_allgather_${nametype1}$11
    2782             : ! **************************************************************************************************
    2783           0 :    SUBROUTINE mp_iallgather_${nametype1}$11(msgout, msgin, comm, request)
    2784             :       ${type1}$, INTENT(IN)                      :: msgout(:)
    2785             :       ${type1}$, INTENT(OUT)                     :: msgin(:)
    2786             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2787             :       TYPE(mp_request_type), INTENT(OUT)                     :: request
    2788             : 
    2789             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$11'
    2790             : 
    2791             :       INTEGER                                  :: handle
    2792             : #if defined(__parallel)
    2793             :       INTEGER                                  :: ierr, rcount, scount
    2794             : #endif
    2795             : 
    2796           0 :       CALL mp_timeset(routineN, handle)
    2797             : 
    2798             : #if defined(__parallel)
    2799             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2800           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    2801           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2802             : #endif
    2803           0 :       scount = SIZE(msgout(:))
    2804           0 :       rcount = scount
    2805             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2806             :                           msgin, rcount, ${mpi_type1}$, &
    2807           0 :                           comm%handle, request%handle, ierr)
    2808           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgather @ "//routineN)
    2809             : #else
    2810             :       MARK_USED(comm)
    2811             :       msgin = msgout
    2812             :       request = mp_request_null
    2813             : #endif
    2814           0 :       CALL mp_timestop(handle)
    2815           0 :    END SUBROUTINE mp_iallgather_${nametype1}$11
    2816             : 
    2817             : ! **************************************************************************************************
    2818             : !> \brief Gathers rank-2 data from all processes and all processes receive the
    2819             : !>        same data
    2820             : !> \param[in] msgout          Rank-2 data to send
    2821             : !> \param msgin ...
    2822             : !> \param comm ...
    2823             : !> \param request ...
    2824             : !> \note see mp_allgather_${nametype1}$12
    2825             : ! **************************************************************************************************
    2826           0 :    SUBROUTINE mp_iallgather_${nametype1}$13(msgout, msgin, comm, request)
    2827             :       ${type1}$, INTENT(IN)                      :: msgout(:)
    2828             :       ${type1}$, INTENT(OUT)                     :: msgin(:, :, :)
    2829             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2830             :       TYPE(mp_request_type), INTENT(OUT)                     :: request
    2831             : 
    2832             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$13'
    2833             : 
    2834             :       INTEGER                                  :: handle
    2835             : #if defined(__parallel)
    2836             :       INTEGER                                  :: ierr, rcount, scount
    2837             : #endif
    2838             : 
    2839           0 :       CALL mp_timeset(routineN, handle)
    2840             : 
    2841             : #if defined(__parallel)
    2842             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2843           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    2844           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2845             : #endif
    2846             : 
    2847           0 :       scount = SIZE(msgout(:))
    2848           0 :       rcount = scount
    2849             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2850             :                           msgin, rcount, ${mpi_type1}$, &
    2851           0 :                           comm%handle, request%handle, ierr)
    2852           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgather @ "//routineN)
    2853             : #else
    2854             :       MARK_USED(comm)
    2855             :       msgin(:, 1, 1) = msgout(:)
    2856             :       request = mp_request_null
    2857             : #endif
    2858           0 :       CALL mp_timestop(handle)
    2859           0 :    END SUBROUTINE mp_iallgather_${nametype1}$13
    2860             : 
    2861             : ! **************************************************************************************************
    2862             : !> \brief Gathers rank-2 data from all processes and all processes receive the
    2863             : !>        same data
    2864             : !> \param[in] msgout          Rank-2 data to send
    2865             : !> \param msgin ...
    2866             : !> \param comm ...
    2867             : !> \param request ...
    2868             : !> \note see mp_allgather_${nametype1}$12
    2869             : ! **************************************************************************************************
    2870           0 :    SUBROUTINE mp_iallgather_${nametype1}$22(msgout, msgin, comm, request)
    2871             :       ${type1}$, INTENT(IN)                      :: msgout(:, :)
    2872             :       ${type1}$, INTENT(OUT)                     :: msgin(:, :)
    2873             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2874             :       TYPE(mp_request_type), INTENT(OUT)                     :: request
    2875             : 
    2876             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$22'
    2877             : 
    2878             :       INTEGER                                  :: handle
    2879             : #if defined(__parallel)
    2880             :       INTEGER                                  :: ierr, rcount, scount
    2881             : #endif
    2882             : 
    2883           0 :       CALL mp_timeset(routineN, handle)
    2884             : 
    2885             : #if defined(__parallel)
    2886             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2887           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    2888           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2889             : #endif
    2890             : 
    2891           0 :       scount = SIZE(msgout(:, :))
    2892           0 :       rcount = scount
    2893             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2894             :                           msgin, rcount, ${mpi_type1}$, &
    2895           0 :                           comm%handle, request%handle, ierr)
    2896           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgather @ "//routineN)
    2897             : #else
    2898             :       MARK_USED(comm)
    2899             :       msgin(:, :) = msgout(:, :)
    2900             :       request = mp_request_null
    2901             : #endif
    2902           0 :       CALL mp_timestop(handle)
    2903           0 :    END SUBROUTINE mp_iallgather_${nametype1}$22
    2904             : 
    2905             : ! **************************************************************************************************
    2906             : !> \brief Gathers rank-2 data from all processes and all processes receive the
    2907             : !>        same data
    2908             : !> \param[in] msgout          Rank-2 data to send
    2909             : !> \param msgin ...
    2910             : !> \param comm ...
    2911             : !> \param request ...
    2912             : !> \note see mp_allgather_${nametype1}$12
    2913             : ! **************************************************************************************************
    2914           0 :    SUBROUTINE mp_iallgather_${nametype1}$24(msgout, msgin, comm, request)
    2915             :       ${type1}$, INTENT(IN)                      :: msgout(:, :)
    2916             :       ${type1}$, INTENT(OUT)                     :: msgin(:, :, :, :)
    2917             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2918             :       TYPE(mp_request_type), INTENT(OUT)                     :: request
    2919             : 
    2920             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$24'
    2921             : 
    2922             :       INTEGER                                  :: handle
    2923             : #if defined(__parallel)
    2924             :       INTEGER                                  :: ierr, rcount, scount
    2925             : #endif
    2926             : 
    2927           0 :       CALL mp_timeset(routineN, handle)
    2928             : 
    2929             : #if defined(__parallel)
    2930             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2931           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    2932           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2933             : #endif
    2934             : 
    2935           0 :       scount = SIZE(msgout(:, :))
    2936           0 :       rcount = scount
    2937             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2938             :                           msgin, rcount, ${mpi_type1}$, &
    2939           0 :                           comm%handle, request%handle, ierr)
    2940           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgather @ "//routineN)
    2941             : #else
    2942             :       MARK_USED(comm)
    2943             :       msgin(:, :, 1, 1) = msgout(:, :)
    2944             :       request = mp_request_null
    2945             : #endif
    2946           0 :       CALL mp_timestop(handle)
    2947           0 :    END SUBROUTINE mp_iallgather_${nametype1}$24
    2948             : 
    2949             : ! **************************************************************************************************
    2950             : !> \brief Gathers rank-3 data from all processes and all processes receive the
    2951             : !>        same data
    2952             : !> \param[in] msgout          Rank-3 data to send
    2953             : !> \param msgin ...
    2954             : !> \param comm ...
    2955             : !> \param request ...
    2956             : !> \note see mp_allgather_${nametype1}$12
    2957             : ! **************************************************************************************************
    2958           0 :    SUBROUTINE mp_iallgather_${nametype1}$33(msgout, msgin, comm, request)
    2959             :       ${type1}$, INTENT(IN)                      :: msgout(:, :, :)
    2960             :       ${type1}$, INTENT(OUT)                     :: msgin(:, :, :)
    2961             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    2962             :       TYPE(mp_request_type), INTENT(OUT)                     :: request
    2963             : 
    2964             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgather_${nametype1}$33'
    2965             : 
    2966             :       INTEGER                                  :: handle
    2967             : #if defined(__parallel)
    2968             :       INTEGER                                  :: ierr, rcount, scount
    2969             : #endif
    2970             : 
    2971           0 :       CALL mp_timeset(routineN, handle)
    2972             : 
    2973             : #if defined(__parallel)
    2974             : #if !defined(__GNUC__) || __GNUC__ >= 9
    2975           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    2976           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    2977             : #endif
    2978             : 
    2979           0 :       scount = SIZE(msgout(:, :, :))
    2980           0 :       rcount = scount
    2981             :       CALL MPI_IALLGATHER(msgout, scount, ${mpi_type1}$, &
    2982             :                           msgin, rcount, ${mpi_type1}$, &
    2983           0 :                           comm%handle, request%handle, ierr)
    2984           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgather @ "//routineN)
    2985             : #else
    2986             :       MARK_USED(comm)
    2987             :       msgin(:, :, :) = msgout(:, :, :)
    2988             :       request = mp_request_null
    2989             : #endif
    2990           0 :       CALL mp_timestop(handle)
    2991           0 :    END SUBROUTINE mp_iallgather_${nametype1}$33
    2992             : 
    2993             : ! **************************************************************************************************
    2994             : !> \brief Gathers vector data from all processes and all processes receive the
    2995             : !>        same data
    2996             : !> \param[in] msgout          Rank-1 data to send
    2997             : !> \param[out] msgin          Received data
    2998             : !> \param[in] rcount          Size of sent data for every process
    2999             : !> \param[in] rdispl          Offset of sent data for every process
    3000             : !> \param[in] comm             Message passing environment identifier
    3001             : !> \par Data size
    3002             : !>      Processes can send different-sized data
    3003             : !> \par Ranks
    3004             : !>      The last rank counts the processes
    3005             : !> \par Offsets
    3006             : !>      Offsets are from 0
    3007             : !> \par MPI mapping
    3008             : !>      mpi_allgather
    3009             : ! **************************************************************************************************
    3010      267826 :    SUBROUTINE mp_allgatherv_${nametype1}$v(msgout, msgin, rcount, rdispl, comm)
    3011             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgout(:)
    3012             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgin(:)
    3013             :       INTEGER, CONTIGUOUS, INTENT(IN)                      :: rcount(:), rdispl(:)
    3014             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3015             : 
    3016             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgatherv_${nametype1}$v'
    3017             : 
    3018             :       INTEGER                                  :: handle
    3019             : #if defined(__parallel)
    3020             :       INTEGER                                  :: ierr, scount
    3021             : #endif
    3022             : 
    3023      267826 :       CALL mp_timeset(routineN, handle)
    3024             : 
    3025             : #if defined(__parallel)
    3026      267826 :       scount = SIZE(msgout)
    3027             :       CALL MPI_ALLGATHERV(msgout, scount, ${mpi_type1}$, msgin, rcount, &
    3028      267826 :                           rdispl, ${mpi_type1}$, comm%handle, ierr)
    3029      267826 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgatherv @ "//routineN)
    3030             : #else
    3031             :       MARK_USED(rcount)
    3032             :       MARK_USED(rdispl)
    3033             :       MARK_USED(comm)
    3034             :       msgin = msgout
    3035             : #endif
    3036      267826 :       CALL mp_timestop(handle)
    3037      267826 :    END SUBROUTINE mp_allgatherv_${nametype1}$v
    3038             : 
    3039             : ! **************************************************************************************************
    3040             : !> \brief Gathers vector data from all processes and all processes receive the
    3041             : !>        same data
    3042             : !> \param[in] msgout          Rank-1 data to send
    3043             : !> \param[out] msgin          Received data
    3044             : !> \param[in] rcount          Size of sent data for every process
    3045             : !> \param[in] rdispl          Offset of sent data for every process
    3046             : !> \param[in] comm            Message passing environment identifier
    3047             : !> \par Data size
    3048             : !>      Processes can send different-sized data
    3049             : !> \par Ranks
    3050             : !>      The last rank counts the processes
    3051             : !> \par Offsets
    3052             : !>      Offsets are from 0
    3053             : !> \par MPI mapping
    3054             : !>      mpi_allgather
    3055             : ! **************************************************************************************************
    3056           8 :    SUBROUTINE mp_allgatherv_${nametype1}$m2(msgout, msgin, rcount, rdispl, comm)
    3057             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgout(:, :)
    3058             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgin(:, :)
    3059             :       INTEGER, CONTIGUOUS, INTENT(IN)                      :: rcount(:), rdispl(:)
    3060             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3061             : 
    3062             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allgatherv_${nametype1}$v'
    3063             : 
    3064             :       INTEGER                                  :: handle
    3065             : #if defined(__parallel)
    3066             :       INTEGER                                  :: ierr, scount
    3067             : #endif
    3068             : 
    3069           8 :       CALL mp_timeset(routineN, handle)
    3070             : 
    3071             : #if defined(__parallel)
    3072          24 :       scount = SIZE(msgout)
    3073             :       CALL MPI_ALLGATHERV(msgout, scount, ${mpi_type1}$, msgin, rcount, &
    3074           8 :                           rdispl, ${mpi_type1}$, comm%handle, ierr)
    3075           8 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_allgatherv @ "//routineN)
    3076             : #else
    3077             :       MARK_USED(rcount)
    3078             :       MARK_USED(rdispl)
    3079             :       MARK_USED(comm)
    3080             :       msgin = msgout
    3081             : #endif
    3082           8 :       CALL mp_timestop(handle)
    3083           8 :    END SUBROUTINE mp_allgatherv_${nametype1}$m2
    3084             : 
    3085             : ! **************************************************************************************************
    3086             : !> \brief Gathers vector data from all processes and all processes receive the
    3087             : !>        same data
    3088             : !> \param[in] msgout          Rank-1 data to send
    3089             : !> \param[out] msgin          Received data
    3090             : !> \param[in] rcount          Size of sent data for every process
    3091             : !> \param[in] rdispl          Offset of sent data for every process
    3092             : !> \param[in] comm            Message passing environment identifier
    3093             : !> \par Data size
    3094             : !>      Processes can send different-sized data
    3095             : !> \par Ranks
    3096             : !>      The last rank counts the processes
    3097             : !> \par Offsets
    3098             : !>      Offsets are from 0
    3099             : !> \par MPI mapping
    3100             : !>      mpi_allgather
    3101             : ! **************************************************************************************************
    3102           0 :    SUBROUTINE mp_iallgatherv_${nametype1}$v(msgout, msgin, rcount, rdispl, comm, request)
    3103             :       ${type1}$, INTENT(IN)                      :: msgout(:)
    3104             :       ${type1}$, INTENT(OUT)                     :: msgin(:)
    3105             :       INTEGER, CONTIGUOUS, INTENT(IN)                      :: rcount(:), rdispl(:)
    3106             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3107             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    3108             : 
    3109             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgatherv_${nametype1}$v'
    3110             : 
    3111             :       INTEGER                                  :: handle
    3112             : #if defined(__parallel)
    3113             :       INTEGER                                  :: ierr, scount, rsize
    3114             : #endif
    3115             : 
    3116           0 :       CALL mp_timeset(routineN, handle)
    3117             : 
    3118             : #if defined(__parallel)
    3119             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3120           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    3121           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3122             :       CPASSERT(IS_CONTIGUOUS(rcount))
    3123             :       CPASSERT(IS_CONTIGUOUS(rdispl))
    3124             : #endif
    3125             : 
    3126           0 :       scount = SIZE(msgout)
    3127           0 :       rsize = SIZE(rcount)
    3128             :       CALL mp_iallgatherv_${nametype1}$v_internal(msgout, scount, msgin, rsize, rcount, &
    3129           0 :                                                   rdispl, comm, request, ierr)
    3130           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgatherv @ "//routineN)
    3131             : #else
    3132             :       MARK_USED(rcount)
    3133             :       MARK_USED(rdispl)
    3134             :       MARK_USED(comm)
    3135             :       msgin = msgout
    3136             :       request = mp_request_null
    3137             : #endif
    3138           0 :       CALL mp_timestop(handle)
    3139           0 :    END SUBROUTINE mp_iallgatherv_${nametype1}$v
    3140             : 
    3141             : ! **************************************************************************************************
    3142             : !> \brief Gathers vector data from all processes and all processes receive the
    3143             : !>        same data
    3144             : !> \param[in] msgout          Rank-1 data to send
    3145             : !> \param[out] msgin          Received data
    3146             : !> \param[in] rcount          Size of sent data for every process
    3147             : !> \param[in] rdispl          Offset of sent data for every process
    3148             : !> \param[in] comm            Message passing environment identifier
    3149             : !> \par Data size
    3150             : !>      Processes can send different-sized data
    3151             : !> \par Ranks
    3152             : !>      The last rank counts the processes
    3153             : !> \par Offsets
    3154             : !>      Offsets are from 0
    3155             : !> \par MPI mapping
    3156             : !>      mpi_allgather
    3157             : ! **************************************************************************************************
    3158           0 :    SUBROUTINE mp_iallgatherv_${nametype1}$v2(msgout, msgin, rcount, rdispl, comm, request)
    3159             :       ${type1}$, INTENT(IN)                      :: msgout(:)
    3160             :       ${type1}$, INTENT(OUT)                     :: msgin(:)
    3161             :       INTEGER, INTENT(IN)                      :: rcount(:, :), rdispl(:, :)
    3162             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3163             :       TYPE(mp_request_type), INTENT(OUT)                   :: request
    3164             : 
    3165             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_iallgatherv_${nametype1}$v2'
    3166             : 
    3167             :       INTEGER                                  :: handle
    3168             : #if defined(__parallel)
    3169             :       INTEGER                                  :: ierr, scount, rsize
    3170             : #endif
    3171             : 
    3172           0 :       CALL mp_timeset(routineN, handle)
    3173             : 
    3174             : #if defined(__parallel)
    3175             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3176           0 :       CPASSERT(IS_CONTIGUOUS(msgout))
    3177           0 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3178           0 :       CPASSERT(IS_CONTIGUOUS(rcount))
    3179           0 :       CPASSERT(IS_CONTIGUOUS(rdispl))
    3180             : #endif
    3181             : 
    3182           0 :       scount = SIZE(msgout)
    3183           0 :       rsize = SIZE(rcount)
    3184             :       CALL mp_iallgatherv_${nametype1}$v_internal(msgout, scount, msgin, rsize, rcount, &
    3185           0 :                                                   rdispl, comm, request, ierr)
    3186           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_iallgatherv @ "//routineN)
    3187             : #else
    3188             :       MARK_USED(rcount)
    3189             :       MARK_USED(rdispl)
    3190             :       MARK_USED(comm)
    3191             :       msgin = msgout
    3192             :       request = mp_request_null
    3193             : #endif
    3194           0 :       CALL mp_timestop(handle)
    3195           0 :    END SUBROUTINE mp_iallgatherv_${nametype1}$v2
    3196             : 
    3197             : ! **************************************************************************************************
    3198             : !> \brief wrapper needed to deal with interfaces as present in openmpi 1.8.1
    3199             : !>        the issue is with the rank of rcount and rdispl
    3200             : !> \param count ...
    3201             : !> \param array_of_requests ...
    3202             : !> \param array_of_statuses ...
    3203             : !> \param ierr ...
    3204             : !> \author Alfio Lazzaro
    3205             : ! **************************************************************************************************
    3206             : #if defined(__parallel)
    3207           0 :    SUBROUTINE mp_iallgatherv_${nametype1}$v_internal(msgout, scount, msgin, rsize, rcount, rdispl, comm, request, ierr)
    3208             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgout(:)
    3209             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgin(:)
    3210             :       INTEGER, INTENT(IN)                      :: rsize
    3211             :       INTEGER, INTENT(IN)                      :: rcount(rsize), rdispl(rsize), scount
    3212             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3213             :       TYPE(mp_request_type), INTENT(OUT) :: request
    3214             :       INTEGER, INTENT(INOUT)                   :: ierr
    3215             : 
    3216             :       CALL MPI_IALLGATHERV(msgout, scount, ${mpi_type1}$, msgin, rcount, &
    3217           0 :                            rdispl, ${mpi_type1}$, comm%handle, request%handle, ierr)
    3218             : 
    3219           0 :    END SUBROUTINE mp_iallgatherv_${nametype1}$v_internal
    3220             : #endif
    3221             : 
    3222             : ! **************************************************************************************************
    3223             : !> \brief Sums a vector and partitions the result among processes
    3224             : !> \param[in] msgout          Data to sum
    3225             : !> \param[out] msgin          Received portion of summed data
    3226             : !> \param[in] rcount          Partition sizes of the summed data for
    3227             : !>                            every process
    3228             : !> \param[in] comm             Message passing environment identifier
    3229             : ! **************************************************************************************************
    3230           6 :    SUBROUTINE mp_sum_scatter_${nametype1}$v(msgout, msgin, rcount, comm)
    3231             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgout(:, :)
    3232             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgin(:)
    3233             :       INTEGER, CONTIGUOUS, INTENT(IN)                      :: rcount(:)
    3234             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3235             : 
    3236             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sum_scatter_${nametype1}$v'
    3237             : 
    3238             :       INTEGER                                  :: handle
    3239             : #if defined(__parallel)
    3240             :       INTEGER :: ierr
    3241             : #endif
    3242             : 
    3243           6 :       CALL mp_timeset(routineN, handle)
    3244             : 
    3245             : #if defined(__parallel)
    3246             :       CALL MPI_REDUCE_SCATTER(msgout, msgin, rcount, ${mpi_type1}$, MPI_SUM, &
    3247           6 :                               comm%handle, ierr)
    3248           6 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_reduce_scatter @ "//routineN)
    3249             : 
    3250             :       CALL add_perf(perf_id=3, count=1, &
    3251           6 :                     msg_size=rcount(1)*2*${bytes1}$)
    3252             : #else
    3253             :       MARK_USED(rcount)
    3254             :       MARK_USED(comm)
    3255             :       msgin = msgout(:, 1)
    3256             : #endif
    3257           6 :       CALL mp_timestop(handle)
    3258           6 :    END SUBROUTINE mp_sum_scatter_${nametype1}$v
    3259             : 
    3260             : ! **************************************************************************************************
    3261             : !> \brief Sends and receives vector data
    3262             : !> \param[in] msgin           Data to send
    3263             : !> \param[in] dest            Process to send data to
    3264             : !> \param[out] msgout         Received data
    3265             : !> \param[in] source          Process from which to receive
    3266             : !> \param[in] comm            Message passing environment identifier
    3267             : !> \param[in] tag             Send and recv tag (default: 0)
    3268             : ! **************************************************************************************************
    3269           0 :    SUBROUTINE mp_sendrecv_${nametype1}$ (msgin, dest, msgout, source, comm, tag)
    3270             :       ${type1}$, INTENT(IN)                      :: msgin
    3271             :       INTEGER, INTENT(IN)                      :: dest
    3272             :       ${type1}$, INTENT(OUT)                     :: msgout
    3273             :       INTEGER, INTENT(IN)                      :: source
    3274             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3275             :       INTEGER, INTENT(IN), OPTIONAL            :: tag
    3276             : 
    3277             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sendrecv_${nametype1}$'
    3278             : 
    3279             :       INTEGER                                  :: handle
    3280             : #if defined(__parallel)
    3281             :       INTEGER                                  :: ierr, msglen_in, msglen_out, &
    3282             :                                                   recv_tag, send_tag
    3283             : #endif
    3284             : 
    3285           0 :       CALL mp_timeset(routineN, handle)
    3286             : 
    3287             : #if defined(__parallel)
    3288           0 :       msglen_in = 1
    3289           0 :       msglen_out = 1
    3290           0 :       send_tag = 0 ! cannot think of something better here, this might be dangerous
    3291           0 :       recv_tag = 0 ! cannot think of something better here, this might be dangerous
    3292           0 :       IF (PRESENT(tag)) THEN
    3293           0 :          send_tag = tag
    3294           0 :          recv_tag = tag
    3295             :       END IF
    3296             :       CALL mpi_sendrecv(msgin, msglen_in, ${mpi_type1}$, dest, send_tag, msgout, &
    3297           0 :                         msglen_out, ${mpi_type1}$, source, recv_tag, comm%handle, MPI_STATUS_IGNORE, ierr)
    3298           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_sendrecv @ "//routineN)
    3299             :       CALL add_perf(perf_id=7, count=1, &
    3300           0 :                     msg_size=(msglen_in + msglen_out)*${bytes1}$/2)
    3301             : #else
    3302             :       MARK_USED(dest)
    3303             :       MARK_USED(source)
    3304             :       MARK_USED(comm)
    3305             :       MARK_USED(tag)
    3306             :       msgout = msgin
    3307             : #endif
    3308           0 :       CALL mp_timestop(handle)
    3309           0 :    END SUBROUTINE mp_sendrecv_${nametype1}$
    3310             : 
    3311             : ! **************************************************************************************************
    3312             : !> \brief Sends and receives vector data
    3313             : !> \param[in] msgin           Data to send
    3314             : !> \param[in] dest            Process to send data to
    3315             : !> \param[out] msgout         Received data
    3316             : !> \param[in] source          Process from which to receive
    3317             : !> \param[in] comm            Message passing environment identifier
    3318             : !> \param[in] tag             Send and recv tag (default: 0)
    3319             : ! **************************************************************************************************
    3320      854234 :    SUBROUTINE mp_sendrecv_${nametype1}$v(msgin, dest, msgout, source, comm, tag)
    3321             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgin(:)
    3322             :       INTEGER, INTENT(IN)                      :: dest
    3323             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgout(:)
    3324             :       INTEGER, INTENT(IN)                      :: source
    3325             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3326             :       INTEGER, INTENT(IN), OPTIONAL            :: tag
    3327             : 
    3328             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sendrecv_${nametype1}$v'
    3329             : 
    3330             :       INTEGER                                  :: handle
    3331             : #if defined(__parallel)
    3332             :       INTEGER                                  :: ierr, msglen_in, msglen_out, &
    3333             :                                                   recv_tag, send_tag
    3334             : #endif
    3335             : 
    3336      854234 :       CALL mp_timeset(routineN, handle)
    3337             : 
    3338             : #if defined(__parallel)
    3339      854234 :       msglen_in = SIZE(msgin)
    3340      854234 :       msglen_out = SIZE(msgout)
    3341      854234 :       send_tag = 0 ! cannot think of something better here, this might be dangerous
    3342      854234 :       recv_tag = 0 ! cannot think of something better here, this might be dangerous
    3343      854234 :       IF (PRESENT(tag)) THEN
    3344      854108 :          send_tag = tag
    3345      854108 :          recv_tag = tag
    3346             :       END IF
    3347             :       CALL mpi_sendrecv(msgin, msglen_in, ${mpi_type1}$, dest, send_tag, msgout, &
    3348      854234 :                         msglen_out, ${mpi_type1}$, source, recv_tag, comm%handle, MPI_STATUS_IGNORE, ierr)
    3349      854234 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_sendrecv @ "//routineN)
    3350             :       CALL add_perf(perf_id=7, count=1, &
    3351      854234 :                     msg_size=(msglen_in + msglen_out)*${bytes1}$/2)
    3352             : #else
    3353             :       MARK_USED(dest)
    3354             :       MARK_USED(source)
    3355             :       MARK_USED(comm)
    3356             :       MARK_USED(tag)
    3357             :       msgout = msgin
    3358             : #endif
    3359      854234 :       CALL mp_timestop(handle)
    3360      854234 :    END SUBROUTINE mp_sendrecv_${nametype1}$v
    3361             : 
    3362             : ! **************************************************************************************************
    3363             : !> \brief Sends and receives matrix data
    3364             : !> \param msgin ...
    3365             : !> \param dest ...
    3366             : !> \param msgout ...
    3367             : !> \param source ...
    3368             : !> \param comm ...
    3369             : !> \param tag ...
    3370             : !> \note see mp_sendrecv_${nametype1}$v
    3371             : ! **************************************************************************************************
    3372      157492 :    SUBROUTINE mp_sendrecv_${nametype1}$m2(msgin, dest, msgout, source, comm, tag)
    3373             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgin(:, :)
    3374             :       INTEGER, INTENT(IN)                      :: dest
    3375             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgout(:, :)
    3376             :       INTEGER, INTENT(IN)                      :: source
    3377             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3378             :       INTEGER, INTENT(IN), OPTIONAL            :: tag
    3379             : 
    3380             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sendrecv_${nametype1}$m2'
    3381             : 
    3382             :       INTEGER                                  :: handle
    3383             : #if defined(__parallel)
    3384             :       INTEGER                                  :: ierr, msglen_in, msglen_out, &
    3385             :                                                   recv_tag, send_tag
    3386             : #endif
    3387             : 
    3388      157492 :       CALL mp_timeset(routineN, handle)
    3389             : 
    3390             : #if defined(__parallel)
    3391      157492 :       msglen_in = SIZE(msgin, 1)*SIZE(msgin, 2)
    3392      157492 :       msglen_out = SIZE(msgout, 1)*SIZE(msgout, 2)
    3393      157492 :       send_tag = 0 ! cannot think of something better here, this might be dangerous
    3394      157492 :       recv_tag = 0 ! cannot think of something better here, this might be dangerous
    3395      157492 :       IF (PRESENT(tag)) THEN
    3396         654 :          send_tag = tag
    3397         654 :          recv_tag = tag
    3398             :       END IF
    3399             :       CALL mpi_sendrecv(msgin, msglen_in, ${mpi_type1}$, dest, send_tag, msgout, &
    3400      157492 :                         msglen_out, ${mpi_type1}$, source, recv_tag, comm%handle, MPI_STATUS_IGNORE, ierr)
    3401      157492 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_sendrecv @ "//routineN)
    3402             :       CALL add_perf(perf_id=7, count=1, &
    3403      157492 :                     msg_size=(msglen_in + msglen_out)*${bytes1}$/2)
    3404             : #else
    3405             :       MARK_USED(dest)
    3406             :       MARK_USED(source)
    3407             :       MARK_USED(comm)
    3408             :       MARK_USED(tag)
    3409             :       msgout = msgin
    3410             : #endif
    3411      157492 :       CALL mp_timestop(handle)
    3412      157492 :    END SUBROUTINE mp_sendrecv_${nametype1}$m2
    3413             : 
    3414             : ! **************************************************************************************************
    3415             : !> \brief Sends and receives rank-3 data
    3416             : !> \param msgin ...
    3417             : !> \param dest ...
    3418             : !> \param msgout ...
    3419             : !> \param source ...
    3420             : !> \param comm ...
    3421             : !> \note see mp_sendrecv_${nametype1}$v
    3422             : ! **************************************************************************************************
    3423       88140 :    SUBROUTINE mp_sendrecv_${nametype1}$m3(msgin, dest, msgout, source, comm, tag)
    3424             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgin(:, :, :)
    3425             :       INTEGER, INTENT(IN)                      :: dest
    3426             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgout(:, :, :)
    3427             :       INTEGER, INTENT(IN)                      :: source
    3428             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3429             :       INTEGER, INTENT(IN), OPTIONAL            :: tag
    3430             : 
    3431             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sendrecv_${nametype1}$m3'
    3432             : 
    3433             :       INTEGER                                  :: handle
    3434             : #if defined(__parallel)
    3435             :       INTEGER                                  :: ierr, msglen_in, msglen_out, &
    3436             :                                                   recv_tag, send_tag
    3437             : #endif
    3438             : 
    3439       88140 :       CALL mp_timeset(routineN, handle)
    3440             : 
    3441             : #if defined(__parallel)
    3442      352560 :       msglen_in = SIZE(msgin)
    3443      352560 :       msglen_out = SIZE(msgout)
    3444       88140 :       send_tag = 0 ! cannot think of something better here, this might be dangerous
    3445       88140 :       recv_tag = 0 ! cannot think of something better here, this might be dangerous
    3446       88140 :       IF (PRESENT(tag)) THEN
    3447         480 :          send_tag = tag
    3448         480 :          recv_tag = tag
    3449             :       END IF
    3450             :       CALL mpi_sendrecv(msgin, msglen_in, ${mpi_type1}$, dest, send_tag, msgout, &
    3451       88140 :                         msglen_out, ${mpi_type1}$, source, recv_tag, comm%handle, MPI_STATUS_IGNORE, ierr)
    3452       88140 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_sendrecv @ "//routineN)
    3453             :       CALL add_perf(perf_id=7, count=1, &
    3454       88140 :                     msg_size=(msglen_in + msglen_out)*${bytes1}$/2)
    3455             : #else
    3456             :       MARK_USED(dest)
    3457             :       MARK_USED(source)
    3458             :       MARK_USED(comm)
    3459             :       MARK_USED(tag)
    3460             :       msgout = msgin
    3461             : #endif
    3462       88140 :       CALL mp_timestop(handle)
    3463       88140 :    END SUBROUTINE mp_sendrecv_${nametype1}$m3
    3464             : 
    3465             : ! **************************************************************************************************
    3466             : !> \brief Sends and receives rank-4 data
    3467             : !> \param msgin ...
    3468             : !> \param dest ...
    3469             : !> \param msgout ...
    3470             : !> \param source ...
    3471             : !> \param comm ...
    3472             : !> \note see mp_sendrecv_${nametype1}$v
    3473             : ! **************************************************************************************************
    3474           0 :    SUBROUTINE mp_sendrecv_${nametype1}$m4(msgin, dest, msgout, source, comm, tag)
    3475             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msgin(:, :, :, :)
    3476             :       INTEGER, INTENT(IN)                      :: dest
    3477             :       ${type1}$, CONTIGUOUS, INTENT(OUT)                     :: msgout(:, :, :, :)
    3478             :       INTEGER, INTENT(IN)                      :: source
    3479             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3480             :       INTEGER, INTENT(IN), OPTIONAL            :: tag
    3481             : 
    3482             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_sendrecv_${nametype1}$m4'
    3483             : 
    3484             :       INTEGER                                  :: handle
    3485             : #if defined(__parallel)
    3486             :       INTEGER                                  :: ierr, msglen_in, msglen_out, &
    3487             :                                                   recv_tag, send_tag
    3488             : #endif
    3489             : 
    3490           0 :       CALL mp_timeset(routineN, handle)
    3491             : 
    3492             : #if defined(__parallel)
    3493           0 :       msglen_in = SIZE(msgin)
    3494           0 :       msglen_out = SIZE(msgout)
    3495           0 :       send_tag = 0 ! cannot think of something better here, this might be dangerous
    3496           0 :       recv_tag = 0 ! cannot think of something better here, this might be dangerous
    3497           0 :       IF (PRESENT(tag)) THEN
    3498           0 :          send_tag = tag
    3499           0 :          recv_tag = tag
    3500             :       END IF
    3501             :       CALL mpi_sendrecv(msgin, msglen_in, ${mpi_type1}$, dest, send_tag, msgout, &
    3502           0 :                         msglen_out, ${mpi_type1}$, source, recv_tag, comm%handle, MPI_STATUS_IGNORE, ierr)
    3503           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_sendrecv @ "//routineN)
    3504             :       CALL add_perf(perf_id=7, count=1, &
    3505           0 :                     msg_size=(msglen_in + msglen_out)*${bytes1}$/2)
    3506             : #else
    3507             :       MARK_USED(dest)
    3508             :       MARK_USED(source)
    3509             :       MARK_USED(comm)
    3510             :       MARK_USED(tag)
    3511             :       msgout = msgin
    3512             : #endif
    3513           0 :       CALL mp_timestop(handle)
    3514           0 :    END SUBROUTINE mp_sendrecv_${nametype1}$m4
    3515             : 
    3516             : ! **************************************************************************************************
    3517             : !> \brief Non-blocking send and receive of a scalar
    3518             : !> \param[in] msgin           Scalar data to send
    3519             : !> \param[in] dest            Which process to send to
    3520             : !> \param[out] msgout         Receive data into this pointer
    3521             : !> \param[in] source          Process to receive from
    3522             : !> \param[in] comm            Message passing environment identifier
    3523             : !> \param[out] send_request   Request handle for the send
    3524             : !> \param[out] recv_request   Request handle for the receive
    3525             : !> \param[in] tag             (optional) tag to differentiate requests
    3526             : !> \par Implementation
    3527             : !>      Calls mpi_isend and mpi_irecv.
    3528             : !> \par History
    3529             : !>      02.2005 created [Alfio Lazzaro]
    3530             : ! **************************************************************************************************
    3531           0 :    SUBROUTINE mp_isendrecv_${nametype1}$ (msgin, dest, msgout, source, comm, send_request, &
    3532             :                                           recv_request, tag)
    3533             :       ${type1}$, INTENT(IN)                                  :: msgin
    3534             :       INTEGER, INTENT(IN)                      :: dest
    3535             :       ${type1}$, INTENT(INOUT)                                  :: msgout
    3536             :       INTEGER, INTENT(IN)                      :: source
    3537             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3538             :       TYPE(mp_request_type), INTENT(out)                     :: send_request, recv_request
    3539             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3540             : 
    3541             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isendrecv_${nametype1}$'
    3542             : 
    3543             :       INTEGER                                  :: handle
    3544             : #if defined(__parallel)
    3545             :       INTEGER                                  :: ierr, my_tag
    3546             : #endif
    3547             : 
    3548           0 :       CALL mp_timeset(routineN, handle)
    3549             : 
    3550             : #if defined(__parallel)
    3551           0 :       my_tag = 0
    3552           0 :       IF (PRESENT(tag)) my_tag = tag
    3553             : 
    3554             :       CALL mpi_irecv(msgout, 1, ${mpi_type1}$, source, my_tag, &
    3555           0 :                      comm%handle, recv_request%handle, ierr)
    3556           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_irecv @ "//routineN)
    3557             : 
    3558             :       CALL mpi_isend(msgin, 1, ${mpi_type1}$, dest, my_tag, &
    3559           0 :                      comm%handle, send_request%handle, ierr)
    3560           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3561             : 
    3562           0 :       CALL add_perf(perf_id=8, count=1, msg_size=2*${bytes1}$)
    3563             : #else
    3564             :       MARK_USED(dest)
    3565             :       MARK_USED(source)
    3566             :       MARK_USED(comm)
    3567             :       MARK_USED(tag)
    3568             :       send_request = mp_request_null
    3569             :       recv_request = mp_request_null
    3570             :       msgout = msgin
    3571             : #endif
    3572           0 :       CALL mp_timestop(handle)
    3573           0 :    END SUBROUTINE mp_isendrecv_${nametype1}$
    3574             : 
    3575             : ! **************************************************************************************************
    3576             : !> \brief Non-blocking send and receive of a vector
    3577             : !> \param[in] msgin           Vector data to send
    3578             : !> \param[in] dest            Which process to send to
    3579             : !> \param[out] msgout         Receive data into this pointer
    3580             : !> \param[in] source          Process to receive from
    3581             : !> \param[in] comm            Message passing environment identifier
    3582             : !> \param[out] send_request   Request handle for the send
    3583             : !> \param[out] recv_request   Request handle for the receive
    3584             : !> \param[in] tag             (optional) tag to differentiate requests
    3585             : !> \par Implementation
    3586             : !>      Calls mpi_isend and mpi_irecv.
    3587             : !> \par History
    3588             : !>      11.2004 created [Joost VandeVondele]
    3589             : !> \note
    3590             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3591             : ! **************************************************************************************************
    3592      881334 :    SUBROUTINE mp_isendrecv_${nametype1}$v(msgin, dest, msgout, source, comm, send_request, &
    3593             :                                           recv_request, tag)
    3594             :       ${type1}$, DIMENSION(:), INTENT(IN)                    :: msgin
    3595             :       INTEGER, INTENT(IN)                      :: dest
    3596             :       ${type1}$, DIMENSION(:), INTENT(INOUT)      :: msgout
    3597             :       INTEGER, INTENT(IN)                      :: source
    3598             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3599             :       TYPE(mp_request_type), INTENT(out)                     :: send_request, recv_request
    3600             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3601             : 
    3602             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isendrecv_${nametype1}$v'
    3603             : 
    3604             :       INTEGER                                  :: handle
    3605             : #if defined(__parallel)
    3606             :       INTEGER                                  :: ierr, msglen, my_tag
    3607             :       ${type1}$                                  :: foo
    3608             : #endif
    3609             : 
    3610      881334 :       CALL mp_timeset(routineN, handle)
    3611             : 
    3612             : #if defined(__parallel)
    3613             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3614      881334 :       CPASSERT(IS_CONTIGUOUS(msgout))
    3615      881334 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3616             : #endif
    3617             : 
    3618      881334 :       my_tag = 0
    3619      881334 :       IF (PRESENT(tag)) my_tag = tag
    3620             : 
    3621      881334 :       msglen = SIZE(msgout, 1)
    3622      881334 :       IF (msglen > 0) THEN
    3623             :          CALL mpi_irecv(msgout(1), msglen, ${mpi_type1}$, source, my_tag, &
    3624      881334 :                         comm%handle, recv_request%handle, ierr)
    3625             :       ELSE
    3626             :          CALL mpi_irecv(foo, msglen, ${mpi_type1}$, source, my_tag, &
    3627           0 :                         comm%handle, recv_request%handle, ierr)
    3628             :       END IF
    3629      881334 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_irecv @ "//routineN)
    3630             : 
    3631      881334 :       msglen = SIZE(msgin, 1)
    3632      881334 :       IF (msglen > 0) THEN
    3633             :          CALL mpi_isend(msgin(1), msglen, ${mpi_type1}$, dest, my_tag, &
    3634      881334 :                         comm%handle, send_request%handle, ierr)
    3635             :       ELSE
    3636             :          CALL mpi_isend(foo, msglen, ${mpi_type1}$, dest, my_tag, &
    3637           0 :                         comm%handle, send_request%handle, ierr)
    3638             :       END IF
    3639      881334 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3640             : 
    3641      881334 :       msglen = (msglen + SIZE(msgout, 1) + 1)/2
    3642      881334 :       CALL add_perf(perf_id=8, count=1, msg_size=msglen*${bytes1}$)
    3643             : #else
    3644             :       MARK_USED(dest)
    3645             :       MARK_USED(source)
    3646             :       MARK_USED(comm)
    3647             :       MARK_USED(tag)
    3648             :       send_request = mp_request_null
    3649             :       recv_request = mp_request_null
    3650             :       msgout = msgin
    3651             : #endif
    3652      881334 :       CALL mp_timestop(handle)
    3653      881334 :    END SUBROUTINE mp_isendrecv_${nametype1}$v
    3654             : 
    3655             : ! **************************************************************************************************
    3656             : !> \brief Non-blocking send of vector data
    3657             : !> \param msgin ...
    3658             : !> \param dest ...
    3659             : !> \param comm ...
    3660             : !> \param request ...
    3661             : !> \param tag ...
    3662             : !> \par History
    3663             : !>      08.2003 created [f&j]
    3664             : !> \note see mp_isendrecv_${nametype1}$v
    3665             : !> \note
    3666             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3667             : ! **************************************************************************************************
    3668     1071823 :    SUBROUTINE mp_isend_${nametype1}$v(msgin, dest, comm, request, tag)
    3669             :       ${type1}$, DIMENSION(:), INTENT(IN)      :: msgin
    3670             :       INTEGER, INTENT(IN)                      :: dest
    3671             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3672             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3673             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3674             : 
    3675             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isend_${nametype1}$v'
    3676             : 
    3677             :       INTEGER                                  :: handle, ierr
    3678             : #if defined(__parallel)
    3679             :       INTEGER                                  :: msglen, my_tag
    3680             :       ${type1}$                                  :: foo(1)
    3681             : #endif
    3682             : 
    3683     1071823 :       CALL mp_timeset(routineN, handle)
    3684             : 
    3685             : #if defined(__parallel)
    3686             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3687     1071823 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3688             : #endif
    3689     1071823 :       my_tag = 0
    3690     1071823 :       IF (PRESENT(tag)) my_tag = tag
    3691             : 
    3692     1071823 :       msglen = SIZE(msgin)
    3693     1071823 :       IF (msglen > 0) THEN
    3694             :          CALL mpi_isend(msgin(1), msglen, ${mpi_type1}$, dest, my_tag, &
    3695     1071793 :                         comm%handle, request%handle, ierr)
    3696             :       ELSE
    3697             :          CALL mpi_isend(foo, msglen, ${mpi_type1}$, dest, my_tag, &
    3698          30 :                         comm%handle, request%handle, ierr)
    3699             :       END IF
    3700     1071823 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3701             : 
    3702     1071823 :       CALL add_perf(perf_id=11, count=1, msg_size=msglen*${bytes1}$)
    3703             : #else
    3704             :       MARK_USED(msgin)
    3705             :       MARK_USED(dest)
    3706             :       MARK_USED(comm)
    3707             :       MARK_USED(request)
    3708             :       MARK_USED(tag)
    3709             :       ierr = 1
    3710             :       request = mp_request_null
    3711             :       CALL mp_stop(ierr, "mp_isend called in non parallel case")
    3712             : #endif
    3713     1071823 :       CALL mp_timestop(handle)
    3714     1071823 :    END SUBROUTINE mp_isend_${nametype1}$v
    3715             : 
    3716             : ! **************************************************************************************************
    3717             : !> \brief Non-blocking send of matrix data
    3718             : !> \param msgin ...
    3719             : !> \param dest ...
    3720             : !> \param comm ...
    3721             : !> \param request ...
    3722             : !> \param tag ...
    3723             : !> \par History
    3724             : !>      2009-11-25 [UB] Made type-generic for templates
    3725             : !> \author fawzi
    3726             : !> \note see mp_isendrecv_${nametype1}$v
    3727             : !> \note see mp_isend_${nametype1}$v
    3728             : !> \note
    3729             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3730             : ! **************************************************************************************************
    3731      747269 :    SUBROUTINE mp_isend_${nametype1}$m2(msgin, dest, comm, request, tag)
    3732             :       ${type1}$, DIMENSION(:, :), INTENT(IN)                 :: msgin
    3733             :       INTEGER, INTENT(IN)                      :: dest
    3734             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3735             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3736             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3737             : 
    3738             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isend_${nametype1}$m2'
    3739             : 
    3740             :       INTEGER                                  :: handle, ierr
    3741             : #if defined(__parallel)
    3742             :       INTEGER                                  :: msglen, my_tag
    3743             :       ${type1}$                                  :: foo(1)
    3744             : #endif
    3745             : 
    3746      747269 :       CALL mp_timeset(routineN, handle)
    3747             : 
    3748             : #if defined(__parallel)
    3749             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3750      747269 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3751             : #endif
    3752             : 
    3753      747269 :       my_tag = 0
    3754      747269 :       IF (PRESENT(tag)) my_tag = tag
    3755             : 
    3756      747269 :       msglen = SIZE(msgin, 1)*SIZE(msgin, 2)
    3757      747269 :       IF (msglen > 0) THEN
    3758             :          CALL mpi_isend(msgin(1, 1), msglen, ${mpi_type1}$, dest, my_tag, &
    3759      747269 :                         comm%handle, request%handle, ierr)
    3760             :       ELSE
    3761             :          CALL mpi_isend(foo, msglen, ${mpi_type1}$, dest, my_tag, &
    3762           0 :                         comm%handle, request%handle, ierr)
    3763             :       END IF
    3764      747269 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3765             : 
    3766      747269 :       CALL add_perf(perf_id=11, count=1, msg_size=msglen*${bytes1}$)
    3767             : #else
    3768             :       MARK_USED(msgin)
    3769             :       MARK_USED(dest)
    3770             :       MARK_USED(comm)
    3771             :       MARK_USED(request)
    3772             :       MARK_USED(tag)
    3773             :       ierr = 1
    3774             :       request = mp_request_null
    3775             :       CALL mp_stop(ierr, "mp_isend called in non parallel case")
    3776             : #endif
    3777      747269 :       CALL mp_timestop(handle)
    3778      747269 :    END SUBROUTINE mp_isend_${nametype1}$m2
    3779             : 
    3780             : ! **************************************************************************************************
    3781             : !> \brief Non-blocking send of rank-3 data
    3782             : !> \param msgin ...
    3783             : !> \param dest ...
    3784             : !> \param comm ...
    3785             : !> \param request ...
    3786             : !> \param tag ...
    3787             : !> \par History
    3788             : !>      9.2008 added _rm3 subroutine [Iain Bethune]
    3789             : !>     (c) The Numerical Algorithms Group (NAG) Ltd, 2008 on behalf of the HECToR project
    3790             : !>      2009-11-25 [UB] Made type-generic for templates
    3791             : !> \author fawzi
    3792             : !> \note see mp_isendrecv_${nametype1}$v
    3793             : !> \note see mp_isend_${nametype1}$v
    3794             : !> \note
    3795             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3796             : ! **************************************************************************************************
    3797       46345 :    SUBROUTINE mp_isend_${nametype1}$m3(msgin, dest, comm, request, tag)
    3798             :       ${type1}$, DIMENSION(:, :, :), INTENT(IN)      :: msgin
    3799             :       INTEGER, INTENT(IN)                      :: dest
    3800             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3801             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3802             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3803             : 
    3804             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isend_${nametype1}$m3'
    3805             : 
    3806             :       INTEGER                                  :: handle, ierr
    3807             : #if defined(__parallel)
    3808             :       INTEGER                                  :: msglen, my_tag
    3809             :       ${type1}$                                  :: foo(1)
    3810             : #endif
    3811             : 
    3812       46345 :       CALL mp_timeset(routineN, handle)
    3813             : 
    3814             : #if defined(__parallel)
    3815             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3816       46345 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3817             : #endif
    3818             : 
    3819       46345 :       my_tag = 0
    3820       46345 :       IF (PRESENT(tag)) my_tag = tag
    3821             : 
    3822       46345 :       msglen = SIZE(msgin, 1)*SIZE(msgin, 2)*SIZE(msgin, 3)
    3823       46345 :       IF (msglen > 0) THEN
    3824             :          CALL mpi_isend(msgin(1, 1, 1), msglen, ${mpi_type1}$, dest, my_tag, &
    3825       46345 :                         comm%handle, request%handle, ierr)
    3826             :       ELSE
    3827             :          CALL mpi_isend(foo, msglen, ${mpi_type1}$, dest, my_tag, &
    3828           0 :                         comm%handle, request%handle, ierr)
    3829             :       END IF
    3830       46345 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3831             : 
    3832       46345 :       CALL add_perf(perf_id=11, count=1, msg_size=msglen*${bytes1}$)
    3833             : #else
    3834             :       MARK_USED(msgin)
    3835             :       MARK_USED(dest)
    3836             :       MARK_USED(comm)
    3837             :       MARK_USED(request)
    3838             :       MARK_USED(tag)
    3839             :       ierr = 1
    3840             :       request = mp_request_null
    3841             :       CALL mp_stop(ierr, "mp_isend called in non parallel case")
    3842             : #endif
    3843       46345 :       CALL mp_timestop(handle)
    3844       46345 :    END SUBROUTINE mp_isend_${nametype1}$m3
    3845             : 
    3846             : ! **************************************************************************************************
    3847             : !> \brief Non-blocking send of rank-4 data
    3848             : !> \param msgin the input message
    3849             : !> \param dest the destination processor
    3850             : !> \param comm the communicator object
    3851             : !> \param request the communication request id
    3852             : !> \param tag the message tag
    3853             : !> \par History
    3854             : !>      2.2016 added _${nametype1}$m4 subroutine [Nico Holmberg]
    3855             : !> \author fawzi
    3856             : !> \note see mp_isend_${nametype1}$v
    3857             : !> \note
    3858             : !>     arrays can be pointers or assumed shape, but they must be contiguous!
    3859             : ! **************************************************************************************************
    3860          56 :    SUBROUTINE mp_isend_${nametype1}$m4(msgin, dest, comm, request, tag)
    3861             :       ${type1}$, DIMENSION(:, :, :, :), INTENT(IN)           :: msgin
    3862             :       INTEGER, INTENT(IN)                      :: dest
    3863             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3864             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3865             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3866             : 
    3867             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_isend_${nametype1}$m4'
    3868             : 
    3869             :       INTEGER                                  :: handle, ierr
    3870             : #if defined(__parallel)
    3871             :       INTEGER                                  :: msglen, my_tag
    3872             :       ${type1}$                                  :: foo(1)
    3873             : #endif
    3874             : 
    3875          56 :       CALL mp_timeset(routineN, handle)
    3876             : 
    3877             : #if defined(__parallel)
    3878             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3879          56 :       CPASSERT(IS_CONTIGUOUS(msgin))
    3880             : #endif
    3881             : 
    3882          56 :       my_tag = 0
    3883          56 :       IF (PRESENT(tag)) my_tag = tag
    3884             : 
    3885          56 :       msglen = SIZE(msgin, 1)*SIZE(msgin, 2)*SIZE(msgin, 3)*SIZE(msgin, 4)
    3886          56 :       IF (msglen > 0) THEN
    3887             :          CALL mpi_isend(msgin(1, 1, 1, 1), msglen, ${mpi_type1}$, dest, my_tag, &
    3888          56 :                         comm%handle, request%handle, ierr)
    3889             :       ELSE
    3890             :          CALL mpi_isend(foo, msglen, ${mpi_type1}$, dest, my_tag, &
    3891           0 :                         comm%handle, request%handle, ierr)
    3892             :       END IF
    3893          56 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_isend @ "//routineN)
    3894             : 
    3895          56 :       CALL add_perf(perf_id=11, count=1, msg_size=msglen*${bytes1}$)
    3896             : #else
    3897             :       MARK_USED(msgin)
    3898             :       MARK_USED(dest)
    3899             :       MARK_USED(comm)
    3900             :       MARK_USED(request)
    3901             :       MARK_USED(tag)
    3902             :       ierr = 1
    3903             :       request = mp_request_null
    3904             :       CALL mp_stop(ierr, "mp_isend called in non parallel case")
    3905             : #endif
    3906          56 :       CALL mp_timestop(handle)
    3907          56 :    END SUBROUTINE mp_isend_${nametype1}$m4
    3908             : 
    3909             : ! **************************************************************************************************
    3910             : !> \brief Non-blocking receive of vector data
    3911             : !> \param msgout ...
    3912             : !> \param source ...
    3913             : !> \param comm ...
    3914             : !> \param request ...
    3915             : !> \param tag ...
    3916             : !> \par History
    3917             : !>      08.2003 created [f&j]
    3918             : !>      2009-11-25 [UB] Made type-generic for templates
    3919             : !> \note see mp_isendrecv_${nametype1}$v
    3920             : !> \note
    3921             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3922             : ! **************************************************************************************************
    3923     1071843 :    SUBROUTINE mp_irecv_${nametype1}$v(msgout, source, comm, request, tag)
    3924             :       ${type1}$, DIMENSION(:), INTENT(INOUT)           :: msgout
    3925             :       INTEGER, INTENT(IN)                      :: source
    3926             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3927             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3928             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3929             : 
    3930             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_irecv_${nametype1}$v'
    3931             : 
    3932             :       INTEGER                                  :: handle
    3933             : #if defined(__parallel)
    3934             :       INTEGER                                  :: ierr, msglen, my_tag
    3935             :       ${type1}$                                  :: foo(1)
    3936             : #endif
    3937             : 
    3938     1071843 :       CALL mp_timeset(routineN, handle)
    3939             : 
    3940             : #if defined(__parallel)
    3941             : #if !defined(__GNUC__) || __GNUC__ >= 9
    3942     1071843 :       CPASSERT(IS_CONTIGUOUS(msgout))
    3943             : #endif
    3944             : 
    3945     1071843 :       my_tag = 0
    3946     1071843 :       IF (PRESENT(tag)) my_tag = tag
    3947             : 
    3948     1071843 :       msglen = SIZE(msgout)
    3949     1071843 :       IF (msglen > 0) THEN
    3950             :          CALL mpi_irecv(msgout(1), msglen, ${mpi_type1}$, source, my_tag, &
    3951     1071798 :                         comm%handle, request%handle, ierr)
    3952             :       ELSE
    3953             :          CALL mpi_irecv(foo, msglen, ${mpi_type1}$, source, my_tag, &
    3954          45 :                         comm%handle, request%handle, ierr)
    3955             :       END IF
    3956     1071843 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_irecv @ "//routineN)
    3957             : 
    3958     1071843 :       CALL add_perf(perf_id=12, count=1, msg_size=msglen*${bytes1}$)
    3959             : #else
    3960             :       CPABORT("mp_irecv called in non parallel case")
    3961             :       MARK_USED(msgout)
    3962             :       MARK_USED(source)
    3963             :       MARK_USED(comm)
    3964             :       MARK_USED(tag)
    3965             :       request = mp_request_null
    3966             : #endif
    3967     1071843 :       CALL mp_timestop(handle)
    3968     1071843 :    END SUBROUTINE mp_irecv_${nametype1}$v
    3969             : 
    3970             : ! **************************************************************************************************
    3971             : !> \brief Non-blocking receive of matrix data
    3972             : !> \param msgout ...
    3973             : !> \param source ...
    3974             : !> \param comm ...
    3975             : !> \param request ...
    3976             : !> \param tag ...
    3977             : !> \par History
    3978             : !>      2009-11-25 [UB] Made type-generic for templates
    3979             : !> \author fawzi
    3980             : !> \note see mp_isendrecv_${nametype1}$v
    3981             : !> \note see mp_irecv_${nametype1}$v
    3982             : !> \note
    3983             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    3984             : ! **************************************************************************************************
    3985      747269 :    SUBROUTINE mp_irecv_${nametype1}$m2(msgout, source, comm, request, tag)
    3986             :       ${type1}$, DIMENSION(:, :), INTENT(INOUT)    :: msgout
    3987             :       INTEGER, INTENT(IN)                      :: source
    3988             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    3989             :       TYPE(mp_request_type), INTENT(out)                     :: request
    3990             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    3991             : 
    3992             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_irecv_${nametype1}$m2'
    3993             : 
    3994             :       INTEGER                                  :: handle
    3995             : #if defined(__parallel)
    3996             :       INTEGER                                  :: ierr, msglen, my_tag
    3997             :       ${type1}$                                  :: foo(1)
    3998             : #endif
    3999             : 
    4000      747269 :       CALL mp_timeset(routineN, handle)
    4001             : 
    4002             : #if defined(__parallel)
    4003             : #if !defined(__GNUC__) || __GNUC__ >= 9
    4004      747269 :       CPASSERT(IS_CONTIGUOUS(msgout))
    4005             : #endif
    4006             : 
    4007      747269 :       my_tag = 0
    4008      747269 :       IF (PRESENT(tag)) my_tag = tag
    4009             : 
    4010      747269 :       msglen = SIZE(msgout, 1)*SIZE(msgout, 2)
    4011      747269 :       IF (msglen > 0) THEN
    4012             :          CALL mpi_irecv(msgout(1, 1), msglen, ${mpi_type1}$, source, my_tag, &
    4013      747269 :                         comm%handle, request%handle, ierr)
    4014             :       ELSE
    4015             :          CALL mpi_irecv(foo, msglen, ${mpi_type1}$, source, my_tag, &
    4016           0 :                         comm%handle, request%handle, ierr)
    4017             :       END IF
    4018      747269 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_irecv @ "//routineN)
    4019             : 
    4020      747269 :       CALL add_perf(perf_id=12, count=1, msg_size=msglen*${bytes1}$)
    4021             : #else
    4022             :       MARK_USED(msgout)
    4023             :       MARK_USED(source)
    4024             :       MARK_USED(comm)
    4025             :       MARK_USED(tag)
    4026             :       request = mp_request_null
    4027             :       CPABORT("mp_irecv called in non parallel case")
    4028             : #endif
    4029      747269 :       CALL mp_timestop(handle)
    4030      747269 :    END SUBROUTINE mp_irecv_${nametype1}$m2
    4031             : 
    4032             : ! **************************************************************************************************
    4033             : !> \brief Non-blocking send of rank-3 data
    4034             : !> \param msgout ...
    4035             : !> \param source ...
    4036             : !> \param comm ...
    4037             : !> \param request ...
    4038             : !> \param tag ...
    4039             : !> \par History
    4040             : !>      9.2008 added _rm3 subroutine [Iain Bethune] (c) The Numerical Algorithms Group (NAG) Ltd, 2008 on behalf of the HECToR project
    4041             : !>      2009-11-25 [UB] Made type-generic for templates
    4042             : !> \author fawzi
    4043             : !> \note see mp_isendrecv_${nametype1}$v
    4044             : !> \note see mp_irecv_${nametype1}$v
    4045             : !> \note
    4046             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    4047             : ! **************************************************************************************************
    4048       46345 :    SUBROUTINE mp_irecv_${nametype1}$m3(msgout, source, comm, request, tag)
    4049             :       ${type1}$, DIMENSION(:, :, :), INTENT(INOUT)      :: msgout
    4050             :       INTEGER, INTENT(IN)                      :: source
    4051             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    4052             :       TYPE(mp_request_type), INTENT(out)                     :: request
    4053             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    4054             : 
    4055             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_irecv_${nametype1}$m3'
    4056             : 
    4057             :       INTEGER                                  :: handle
    4058             : #if defined(__parallel)
    4059             :       INTEGER                                  :: ierr, msglen, my_tag
    4060             :       ${type1}$                                  :: foo(1)
    4061             : #endif
    4062             : 
    4063       46345 :       CALL mp_timeset(routineN, handle)
    4064             : 
    4065             : #if defined(__parallel)
    4066             : #if !defined(__GNUC__) || __GNUC__ >= 9
    4067       46345 :       CPASSERT(IS_CONTIGUOUS(msgout))
    4068             : #endif
    4069             : 
    4070       46345 :       my_tag = 0
    4071       46345 :       IF (PRESENT(tag)) my_tag = tag
    4072             : 
    4073       46345 :       msglen = SIZE(msgout, 1)*SIZE(msgout, 2)*SIZE(msgout, 3)
    4074       46345 :       IF (msglen > 0) THEN
    4075             :          CALL mpi_irecv(msgout(1, 1, 1), msglen, ${mpi_type1}$, source, my_tag, &
    4076       46345 :                         comm%handle, request%handle, ierr)
    4077             :       ELSE
    4078             :          CALL mpi_irecv(foo, msglen, ${mpi_type1}$, source, my_tag, &
    4079           0 :                         comm%handle, request%handle, ierr)
    4080             :       END IF
    4081       46345 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_ircv @ "//routineN)
    4082             : 
    4083       46345 :       CALL add_perf(perf_id=12, count=1, msg_size=msglen*${bytes1}$)
    4084             : #else
    4085             :       MARK_USED(msgout)
    4086             :       MARK_USED(source)
    4087             :       MARK_USED(comm)
    4088             :       MARK_USED(tag)
    4089             :       request = mp_request_null
    4090             :       CPABORT("mp_irecv called in non parallel case")
    4091             : #endif
    4092       46345 :       CALL mp_timestop(handle)
    4093       46345 :    END SUBROUTINE mp_irecv_${nametype1}$m3
    4094             : 
    4095             : ! **************************************************************************************************
    4096             : !> \brief Non-blocking receive of rank-4 data
    4097             : !> \param msgout the output message
    4098             : !> \param source the source processor
    4099             : !> \param comm the communicator object
    4100             : !> \param request the communication request id
    4101             : !> \param tag the message tag
    4102             : !> \par History
    4103             : !>      2.2016 added _${nametype1}$m4 subroutine [Nico Holmberg]
    4104             : !> \author fawzi
    4105             : !> \note see mp_irecv_${nametype1}$v
    4106             : !> \note
    4107             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    4108             : ! **************************************************************************************************
    4109          56 :    SUBROUTINE mp_irecv_${nametype1}$m4(msgout, source, comm, request, tag)
    4110             :       ${type1}$, DIMENSION(:, :, :, :), INTENT(INOUT)   :: msgout
    4111             :       INTEGER, INTENT(IN)                      :: source
    4112             :       CLASS(mp_comm_type), INTENT(IN) :: comm
    4113             :       TYPE(mp_request_type), INTENT(out)                     :: request
    4114             :       INTEGER, INTENT(in), OPTIONAL            :: tag
    4115             : 
    4116             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_irecv_${nametype1}$m4'
    4117             : 
    4118             :       INTEGER                                  :: handle
    4119             : #if defined(__parallel)
    4120             :       INTEGER                                  :: ierr, msglen, my_tag
    4121             :       ${type1}$                                  :: foo(1)
    4122             : #endif
    4123             : 
    4124          56 :       CALL mp_timeset(routineN, handle)
    4125             : 
    4126             : #if defined(__parallel)
    4127             : #if !defined(__GNUC__) || __GNUC__ >= 9
    4128          56 :       CPASSERT(IS_CONTIGUOUS(msgout))
    4129             : #endif
    4130             : 
    4131          56 :       my_tag = 0
    4132          56 :       IF (PRESENT(tag)) my_tag = tag
    4133             : 
    4134          56 :       msglen = SIZE(msgout, 1)*SIZE(msgout, 2)*SIZE(msgout, 3)*SIZE(msgout, 4)
    4135          56 :       IF (msglen > 0) THEN
    4136             :          CALL mpi_irecv(msgout(1, 1, 1, 1), msglen, ${mpi_type1}$, source, my_tag, &
    4137          56 :                         comm%handle, request%handle, ierr)
    4138             :       ELSE
    4139             :          CALL mpi_irecv(foo, msglen, ${mpi_type1}$, source, my_tag, &
    4140           0 :                         comm%handle, request%handle, ierr)
    4141             :       END IF
    4142          56 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_ircv @ "//routineN)
    4143             : 
    4144          56 :       CALL add_perf(perf_id=12, count=1, msg_size=msglen*${bytes1}$)
    4145             : #else
    4146             :       MARK_USED(msgout)
    4147             :       MARK_USED(source)
    4148             :       MARK_USED(comm)
    4149             :       MARK_USED(tag)
    4150             :       request = mp_request_null
    4151             :       CPABORT("mp_irecv called in non parallel case")
    4152             : #endif
    4153          56 :       CALL mp_timestop(handle)
    4154          56 :    END SUBROUTINE mp_irecv_${nametype1}$m4
    4155             : 
    4156             : ! **************************************************************************************************
    4157             : !> \brief Window initialization function for vector data
    4158             : !> \param base ...
    4159             : !> \param comm ...
    4160             : !> \param win ...
    4161             : !> \par History
    4162             : !>      02.2015 created [Alfio Lazzaro]
    4163             : !> \note
    4164             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    4165             : ! **************************************************************************************************
    4166           0 :    SUBROUTINE mp_win_create_${nametype1}$v(base, comm, win)
    4167             :       ${type1}$, DIMENSION(:), INTENT(INOUT), CONTIGUOUS   :: base
    4168             :       TYPE(mp_comm_type), INTENT(IN) :: comm
    4169             :       CLASS(mp_win_type), INTENT(INOUT)         :: win
    4170             : 
    4171             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_win_create_${nametype1}$v'
    4172             : 
    4173             :       INTEGER                                  :: handle
    4174             : #if defined(__parallel)
    4175             :       INTEGER :: ierr
    4176             :       INTEGER(kind=mpi_address_kind)           :: len
    4177             :       ${type1}$                                  :: foo(1)
    4178             : #endif
    4179             : 
    4180           0 :       CALL mp_timeset(routineN, handle)
    4181             : 
    4182             : #if defined(__parallel)
    4183             : 
    4184           0 :       len = SIZE(base)*${bytes1}$
    4185           0 :       IF (len > 0) THEN
    4186           0 :          CALL mpi_win_create(base(1), len, ${bytes1}$, MPI_INFO_NULL, comm%handle, win%handle, ierr)
    4187             :       ELSE
    4188           0 :          CALL mpi_win_create(foo, len, ${bytes1}$, MPI_INFO_NULL, comm%handle, win%handle, ierr)
    4189             :       END IF
    4190           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_win_create @ "//routineN)
    4191             : 
    4192           0 :       CALL add_perf(perf_id=20, count=1)
    4193             : #else
    4194             :       MARK_USED(base)
    4195             :       MARK_USED(comm)
    4196             :       win%handle = mp_win_null_handle
    4197             : #endif
    4198           0 :       CALL mp_timestop(handle)
    4199           0 :    END SUBROUTINE mp_win_create_${nametype1}$v
    4200             : 
    4201             : ! **************************************************************************************************
    4202             : !> \brief Single-sided get function for vector data
    4203             : !> \param base ...
    4204             : !> \param comm ...
    4205             : !> \param win ...
    4206             : !> \par History
    4207             : !>      02.2015 created [Alfio Lazzaro]
    4208             : !> \note
    4209             : !>      arrays can be pointers or assumed shape, but they must be contiguous!
    4210             : ! **************************************************************************************************
    4211           0 :    SUBROUTINE mp_rget_${nametype1}$v(base, source, win, win_data, myproc, disp, request, &
    4212             :                                      origin_datatype, target_datatype)
    4213             :       ${type1}$, DIMENSION(:), CONTIGUOUS, INTENT(INOUT)            :: base
    4214             :       INTEGER, INTENT(IN)                                 :: source
    4215             :       CLASS(mp_win_type), INTENT(IN) :: win
    4216             :       ${type1}$, DIMENSION(:), INTENT(IN)                               :: win_data
    4217             :       INTEGER, INTENT(IN), OPTIONAL                       :: myproc, disp
    4218             :       TYPE(mp_request_type), INTENT(OUT)                                :: request
    4219             :       TYPE(mp_type_descriptor_type), INTENT(IN), OPTIONAL :: origin_datatype, target_datatype
    4220             : 
    4221             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_rget_${nametype1}$v'
    4222             : 
    4223             :       INTEGER                                  :: handle
    4224             : #if defined(__parallel)
    4225             :       INTEGER                                  :: ierr, len, &
    4226             :                                                   origin_len, target_len
    4227             :       LOGICAL                                  :: do_local_copy
    4228             :       INTEGER(kind=mpi_address_kind)           :: disp_aint
    4229             :       MPI_DATA_TYPE :: handle_origin_datatype, handle_target_datatype
    4230             : #endif
    4231             : 
    4232           0 :       CALL mp_timeset(routineN, handle)
    4233             : 
    4234             : #if defined(__parallel)
    4235           0 :       len = SIZE(base)
    4236           0 :       disp_aint = 0
    4237           0 :       IF (PRESENT(disp)) THEN
    4238           0 :          disp_aint = INT(disp, KIND=mpi_address_kind)
    4239             :       END IF
    4240           0 :       handle_origin_datatype = ${mpi_type1}$
    4241           0 :       origin_len = len
    4242           0 :       IF (PRESENT(origin_datatype)) THEN
    4243           0 :          handle_origin_datatype = origin_datatype%type_handle
    4244           0 :          origin_len = 1
    4245             :       END IF
    4246           0 :       handle_target_datatype = ${mpi_type1}$
    4247           0 :       target_len = len
    4248           0 :       IF (PRESENT(target_datatype)) THEN
    4249           0 :          handle_target_datatype = target_datatype%type_handle
    4250           0 :          target_len = 1
    4251             :       END IF
    4252           0 :       IF (len > 0) THEN
    4253           0 :          do_local_copy = .FALSE.
    4254           0 :          IF (PRESENT(myproc) .AND. .NOT. PRESENT(origin_datatype) .AND. .NOT. PRESENT(target_datatype)) THEN
    4255           0 :             IF (myproc .EQ. source) do_local_copy = .TRUE.
    4256             :          END IF
    4257             :          IF (do_local_copy) THEN
    4258           0 :             !$OMP PARALLEL WORKSHARE DEFAULT(none) SHARED(base,win_data,disp_aint,len)
    4259             :             base(:) = win_data(disp_aint + 1:disp_aint + len)
    4260             :             !$OMP END PARALLEL WORKSHARE
    4261           0 :             request = mp_request_null
    4262           0 :             ierr = 0
    4263             :          ELSE
    4264             :             CALL mpi_rget(base(1), origin_len, handle_origin_datatype, source, disp_aint, &
    4265           0 :                           target_len, handle_target_datatype, win%handle, request%handle, ierr)
    4266             :          END IF
    4267             :       ELSE
    4268           0 :          request = mp_request_null
    4269           0 :          ierr = 0
    4270             :       END IF
    4271           0 :       IF (ierr /= 0) CALL mp_stop(ierr, "mpi_rget @ "//routineN)
    4272             : 
    4273           0 :       CALL add_perf(perf_id=25, count=1, msg_size=SIZE(base)*${bytes1}$)
    4274             : #else
    4275             :       MARK_USED(source)
    4276             :       MARK_USED(win)
    4277             :       MARK_USED(myproc)
    4278             :       MARK_USED(origin_datatype)
    4279             :       MARK_USED(target_datatype)
    4280             : 
    4281             :       request = mp_request_null
    4282             :       !
    4283             :       IF (PRESENT(disp)) THEN
    4284             :          base(:) = win_data(disp + 1:disp + SIZE(base))
    4285             :       ELSE
    4286             :          base(:) = win_data(:SIZE(base))
    4287             :       END IF
    4288             : 
    4289             : #endif
    4290           0 :       CALL mp_timestop(handle)
    4291           0 :    END SUBROUTINE mp_rget_${nametype1}$v
    4292             : 
    4293             : ! **************************************************************************************************
    4294             : !> \brief ...
    4295             : !> \param count ...
    4296             : !> \param lengths ...
    4297             : !> \param displs ...
    4298             : !> \return ...
    4299             : ! ***************************************************************************
    4300           0 :    FUNCTION mp_type_indexed_make_${nametype1}$ (count, lengths, displs) &
    4301             :       RESULT(type_descriptor)
    4302             :       INTEGER, INTENT(IN)                      :: count
    4303             :       INTEGER, DIMENSION(1:count), INTENT(IN), TARGET  :: lengths, displs
    4304             :       TYPE(mp_type_descriptor_type)            :: type_descriptor
    4305             : 
    4306             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_type_indexed_make_${nametype1}$'
    4307             : 
    4308             :       INTEGER :: handle
    4309             : #if defined(__parallel)
    4310             :       INTEGER :: ierr
    4311             : #endif
    4312             : 
    4313           0 :       CALL mp_timeset(routineN, handle)
    4314             : 
    4315             : #if defined(__parallel)
    4316             :       CALL mpi_type_indexed(count, lengths, displs, ${mpi_type1}$, &
    4317           0 :                             type_descriptor%type_handle, ierr)
    4318           0 :       IF (ierr /= 0) &
    4319           0 :          CPABORT("MPI_Type_Indexed @ "//routineN)
    4320           0 :       CALL mpi_type_commit(type_descriptor%type_handle, ierr)
    4321           0 :       IF (ierr /= 0) &
    4322           0 :          CPABORT("MPI_Type_commit @ "//routineN)
    4323             : #else
    4324             :       type_descriptor%type_handle = ${handle1}$
    4325             : #endif
    4326           0 :       type_descriptor%length = count
    4327           0 :       NULLIFY (type_descriptor%subtype)
    4328           0 :       type_descriptor%vector_descriptor(1:2) = 1
    4329           0 :       type_descriptor%has_indexing = .TRUE.
    4330           0 :       type_descriptor%index_descriptor%index => lengths
    4331           0 :       type_descriptor%index_descriptor%chunks => displs
    4332             : 
    4333           0 :       CALL mp_timestop(handle)
    4334             : 
    4335           0 :    END FUNCTION mp_type_indexed_make_${nametype1}$
    4336             : 
    4337             : ! **************************************************************************************************
    4338             : !> \brief Allocates special parallel memory
    4339             : !> \param[in]  DATA      pointer to integer array to allocate
    4340             : !> \param[in]  len       number of integers to allocate
    4341             : !> \param[out] stat      (optional) allocation status result
    4342             : !> \author UB
    4343             : ! **************************************************************************************************
    4344           0 :    SUBROUTINE mp_allocate_${nametype1}$ (DATA, len, stat)
    4345             :       ${type1}$, CONTIGUOUS, DIMENSION(:), POINTER      :: DATA
    4346             :       INTEGER, INTENT(IN)                 :: len
    4347             :       INTEGER, INTENT(OUT), OPTIONAL      :: stat
    4348             : 
    4349             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_allocate_${nametype1}$'
    4350             : 
    4351             :       INTEGER                             :: handle, ierr
    4352             : 
    4353           0 :       CALL mp_timeset(routineN, handle)
    4354             : 
    4355             : #if defined(__parallel)
    4356           0 :       NULLIFY (DATA)
    4357           0 :       CALL mp_alloc_mem(DATA, len, stat=ierr)
    4358           0 :       IF (ierr /= 0 .AND. .NOT. PRESENT(stat)) &
    4359           0 :          CALL mp_stop(ierr, "mpi_alloc_mem @ "//routineN)
    4360           0 :       CALL add_perf(perf_id=15, count=1)
    4361             : #else
    4362             :       ALLOCATE (DATA(len), stat=ierr)
    4363             :       IF (ierr /= 0 .AND. .NOT. PRESENT(stat)) &
    4364             :          CALL mp_stop(ierr, "ALLOCATE @ "//routineN)
    4365             : #endif
    4366           0 :       IF (PRESENT(stat)) stat = ierr
    4367           0 :       CALL mp_timestop(handle)
    4368           0 :    END SUBROUTINE mp_allocate_${nametype1}$
    4369             : 
    4370             : ! **************************************************************************************************
    4371             : !> \brief Deallocates special parallel memory
    4372             : !> \param[in] DATA         pointer to special memory to deallocate
    4373             : !> \param stat ...
    4374             : !> \author UB
    4375             : ! **************************************************************************************************
    4376           0 :    SUBROUTINE mp_deallocate_${nametype1}$ (DATA, stat)
    4377             :       ${type1}$, CONTIGUOUS, DIMENSION(:), POINTER      :: DATA
    4378             :       INTEGER, INTENT(OUT), OPTIONAL      :: stat
    4379             : 
    4380             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_deallocate_${nametype1}$'
    4381             : 
    4382             :       INTEGER                             :: handle
    4383             : #if defined(__parallel)
    4384             :       INTEGER :: ierr
    4385             : #endif
    4386             : 
    4387           0 :       CALL mp_timeset(routineN, handle)
    4388             : 
    4389             : #if defined(__parallel)
    4390           0 :       CALL mp_free_mem(DATA, ierr)
    4391           0 :       IF (PRESENT(stat)) THEN
    4392           0 :          stat = ierr
    4393             :       ELSE
    4394           0 :          IF (ierr /= 0) CALL mp_stop(ierr, "mpi_free_mem @ "//routineN)
    4395             :       END IF
    4396           0 :       NULLIFY (DATA)
    4397           0 :       CALL add_perf(perf_id=15, count=1)
    4398             : #else
    4399             :       DEALLOCATE (DATA)
    4400             :       IF (PRESENT(stat)) stat = 0
    4401             : #endif
    4402           0 :       CALL mp_timestop(handle)
    4403           0 :    END SUBROUTINE mp_deallocate_${nametype1}$
    4404             : 
    4405             : ! **************************************************************************************************
    4406             : !> \brief (parallel) Blocking individual file write using explicit offsets
    4407             : !>        (serial) Unformatted stream write
    4408             : !> \param[in] fh     file handle (file storage unit)
    4409             : !> \param[in] offset file offset (position)
    4410             : !> \param[in] msg    data to be written to the file
    4411             : !> \param msglen ...
    4412             : !> \par MPI-I/O mapping   mpi_file_write_at
    4413             : !> \par STREAM-I/O mapping   WRITE
    4414             : !> \param[in](optional) msglen number of the elements of data
    4415             : ! **************************************************************************************************
    4416           0 :    SUBROUTINE mp_file_write_at_${nametype1}$v(fh, offset, msg, msglen)
    4417             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:)
    4418             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4419             :       INTEGER, INTENT(IN), OPTIONAL              :: msglen
    4420             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4421             : 
    4422             :       INTEGER :: msg_len
    4423             : #if defined(__parallel)
    4424             :       INTEGER                                    :: ierr
    4425             : #endif
    4426             : 
    4427           0 :       msg_len = SIZE(msg)
    4428           0 :       IF (PRESENT(msglen)) msg_len = msglen
    4429             : #if defined(__parallel)
    4430           0 :       CALL MPI_FILE_WRITE_AT(fh%handle, offset, msg, msg_len, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4431           0 :       IF (ierr .NE. 0) &
    4432           0 :          CPABORT("mpi_file_write_at_${nametype1}$v @ mp_file_write_at_${nametype1}$v")
    4433             : #else
    4434             :       WRITE (UNIT=fh%handle, POS=offset + 1) msg(1:msg_len)
    4435             : #endif
    4436           0 :    END SUBROUTINE mp_file_write_at_${nametype1}$v
    4437             : 
    4438             : ! **************************************************************************************************
    4439             : !> \brief ...
    4440             : !> \param fh ...
    4441             : !> \param offset ...
    4442             : !> \param msg ...
    4443             : ! **************************************************************************************************
    4444           0 :    SUBROUTINE mp_file_write_at_${nametype1}$ (fh, offset, msg)
    4445             :       ${type1}$, INTENT(IN)               :: msg
    4446             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4447             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4448             : 
    4449             : #if defined(__parallel)
    4450             :       INTEGER                                    :: ierr
    4451             : 
    4452           0 :       ierr = 0
    4453           0 :       CALL MPI_FILE_WRITE_AT(fh%handle, offset, msg, 1, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4454           0 :       IF (ierr .NE. 0) &
    4455           0 :          CPABORT("mpi_file_write_at_${nametype1}$ @ mp_file_write_at_${nametype1}$")
    4456             : #else
    4457             :       WRITE (UNIT=fh%handle, POS=offset + 1) msg
    4458             : #endif
    4459           0 :    END SUBROUTINE mp_file_write_at_${nametype1}$
    4460             : 
    4461             : ! **************************************************************************************************
    4462             : !> \brief (parallel) Blocking collective file write using explicit offsets
    4463             : !>        (serial) Unformatted stream write
    4464             : !> \param fh ...
    4465             : !> \param offset ...
    4466             : !> \param msg ...
    4467             : !> \param msglen ...
    4468             : !> \par MPI-I/O mapping   mpi_file_write_at_all
    4469             : !> \par STREAM-I/O mapping   WRITE
    4470             : ! **************************************************************************************************
    4471           0 :    SUBROUTINE mp_file_write_at_all_${nametype1}$v(fh, offset, msg, msglen)
    4472             :       ${type1}$, CONTIGUOUS, INTENT(IN)                      :: msg(:)
    4473             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4474             :       INTEGER, INTENT(IN), OPTIONAL              :: msglen
    4475             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4476             : 
    4477             :       INTEGER :: msg_len
    4478             : #if defined(__parallel)
    4479             :       INTEGER                                    :: ierr
    4480             : #endif
    4481             : 
    4482           0 :       msg_len = SIZE(msg)
    4483           0 :       IF (PRESENT(msglen)) msg_len = msglen
    4484             : #if defined(__parallel)
    4485           0 :       CALL MPI_FILE_WRITE_AT_ALL(fh%handle, offset, msg, msg_len, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4486           0 :       IF (ierr .NE. 0) &
    4487           0 :          CPABORT("mpi_file_write_at_all_${nametype1}$v @ mp_file_write_at_all_${nametype1}$v")
    4488             : #else
    4489             :       WRITE (UNIT=fh%handle, POS=offset + 1) msg(1:msg_len)
    4490             : #endif
    4491           0 :    END SUBROUTINE mp_file_write_at_all_${nametype1}$v
    4492             : 
    4493             : ! **************************************************************************************************
    4494             : !> \brief ...
    4495             : !> \param fh ...
    4496             : !> \param offset ...
    4497             : !> \param msg ...
    4498             : ! **************************************************************************************************
    4499           0 :    SUBROUTINE mp_file_write_at_all_${nametype1}$ (fh, offset, msg)
    4500             :       ${type1}$, INTENT(IN)               :: msg
    4501             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4502             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4503             : 
    4504             : #if defined(__parallel)
    4505             :       INTEGER                                    :: ierr
    4506             : 
    4507           0 :       ierr = 0
    4508           0 :       CALL MPI_FILE_WRITE_AT_ALL(fh%handle, offset, msg, 1, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4509           0 :       IF (ierr .NE. 0) &
    4510           0 :          CPABORT("mpi_file_write_at_all_${nametype1}$ @ mp_file_write_at_all_${nametype1}$")
    4511             : #else
    4512             :       WRITE (UNIT=fh%handle, POS=offset + 1) msg
    4513             : #endif
    4514           0 :    END SUBROUTINE mp_file_write_at_all_${nametype1}$
    4515             : 
    4516             : ! **************************************************************************************************
    4517             : !> \brief (parallel) Blocking individual file read using explicit offsets
    4518             : !>        (serial) Unformatted stream read
    4519             : !> \param[in] fh     file handle (file storage unit)
    4520             : !> \param[in] offset file offset (position)
    4521             : !> \param[out] msg   data to be read from the file
    4522             : !> \param msglen ...
    4523             : !> \par MPI-I/O mapping   mpi_file_read_at
    4524             : !> \par STREAM-I/O mapping   READ
    4525             : !> \param[in](optional) msglen  number of elements of data
    4526             : ! **************************************************************************************************
    4527           0 :    SUBROUTINE mp_file_read_at_${nametype1}$v(fh, offset, msg, msglen)
    4528             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msg(:)
    4529             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4530             :       INTEGER, INTENT(IN), OPTIONAL              :: msglen
    4531             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4532             : 
    4533             :       INTEGER :: msg_len
    4534             : #if defined(__parallel)
    4535             :       INTEGER                                    :: ierr
    4536             : #endif
    4537             : 
    4538           0 :       msg_len = SIZE(msg)
    4539           0 :       IF (PRESENT(msglen)) msg_len = msglen
    4540             : #if defined(__parallel)
    4541           0 :       CALL MPI_FILE_READ_AT(fh%handle, offset, msg, msg_len, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4542           0 :       IF (ierr .NE. 0) &
    4543           0 :          CPABORT("mpi_file_read_at_${nametype1}$v @ mp_file_read_at_${nametype1}$v")
    4544             : #else
    4545             :       READ (UNIT=fh%handle, POS=offset + 1) msg(1:msg_len)
    4546             : #endif
    4547           0 :    END SUBROUTINE mp_file_read_at_${nametype1}$v
    4548             : 
    4549             : ! **************************************************************************************************
    4550             : !> \brief ...
    4551             : !> \param fh ...
    4552             : !> \param offset ...
    4553             : !> \param msg ...
    4554             : ! **************************************************************************************************
    4555           0 :    SUBROUTINE mp_file_read_at_${nametype1}$ (fh, offset, msg)
    4556             :       ${type1}$, INTENT(OUT)               :: msg
    4557             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4558             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4559             : 
    4560             : #if defined(__parallel)
    4561             :       INTEGER                                    :: ierr
    4562             : 
    4563           0 :       ierr = 0
    4564           0 :       CALL MPI_FILE_READ_AT(fh%handle, offset, msg, 1, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4565           0 :       IF (ierr .NE. 0) &
    4566           0 :          CPABORT("mpi_file_read_at_${nametype1}$ @ mp_file_read_at_${nametype1}$")
    4567             : #else
    4568             :       READ (UNIT=fh%handle, POS=offset + 1) msg
    4569             : #endif
    4570           0 :    END SUBROUTINE mp_file_read_at_${nametype1}$
    4571             : 
    4572             : ! **************************************************************************************************
    4573             : !> \brief (parallel) Blocking collective file read using explicit offsets
    4574             : !>        (serial) Unformatted stream read
    4575             : !> \param fh ...
    4576             : !> \param offset ...
    4577             : !> \param msg ...
    4578             : !> \param msglen ...
    4579             : !> \par MPI-I/O mapping    mpi_file_read_at_all
    4580             : !> \par STREAM-I/O mapping   READ
    4581             : ! **************************************************************************************************
    4582           0 :    SUBROUTINE mp_file_read_at_all_${nametype1}$v(fh, offset, msg, msglen)
    4583             :       ${type1}$, INTENT(OUT), CONTIGUOUS                     :: msg(:)
    4584             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4585             :       INTEGER, INTENT(IN), OPTIONAL              :: msglen
    4586             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4587             : 
    4588             :       INTEGER :: msg_len
    4589             : #if defined(__parallel)
    4590             :       INTEGER                                    :: ierr
    4591             : #endif
    4592             : 
    4593           0 :       msg_len = SIZE(msg)
    4594           0 :       IF (PRESENT(msglen)) msg_len = msglen
    4595             : #if defined(__parallel)
    4596           0 :       CALL MPI_FILE_READ_AT_ALL(fh%handle, offset, msg, msg_len, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4597           0 :       IF (ierr .NE. 0) &
    4598           0 :          CPABORT("mpi_file_read_at_all_${nametype1}$v @ mp_file_read_at_all_${nametype1}$v")
    4599             : #else
    4600             :       READ (UNIT=fh%handle, POS=offset + 1) msg(1:msg_len)
    4601             : #endif
    4602           0 :    END SUBROUTINE mp_file_read_at_all_${nametype1}$v
    4603             : 
    4604             : ! **************************************************************************************************
    4605             : !> \brief ...
    4606             : !> \param fh ...
    4607             : !> \param offset ...
    4608             : !> \param msg ...
    4609             : ! **************************************************************************************************
    4610           0 :    SUBROUTINE mp_file_read_at_all_${nametype1}$ (fh, offset, msg)
    4611             :       ${type1}$, INTENT(OUT)               :: msg
    4612             :       CLASS(mp_file_type), INTENT(IN)                        :: fh
    4613             :       INTEGER(kind=file_offset), INTENT(IN)      :: offset
    4614             : 
    4615             : #if defined(__parallel)
    4616             :       INTEGER                                    :: ierr
    4617             : 
    4618           0 :       ierr = 0
    4619           0 :       CALL MPI_FILE_READ_AT_ALL(fh%handle, offset, msg, 1, ${mpi_type1}$, MPI_STATUS_IGNORE, ierr)
    4620           0 :       IF (ierr .NE. 0) &
    4621           0 :          CPABORT("mpi_file_read_at_all_${nametype1}$ @ mp_file_read_at_all_${nametype1}$")
    4622             : #else
    4623             :       READ (UNIT=fh%handle, POS=offset + 1) msg
    4624             : #endif
    4625           0 :    END SUBROUTINE mp_file_read_at_all_${nametype1}$
    4626             : 
    4627             : ! **************************************************************************************************
    4628             : !> \brief ...
    4629             : !> \param ptr ...
    4630             : !> \param vector_descriptor ...
    4631             : !> \param index_descriptor ...
    4632             : !> \return ...
    4633             : ! **************************************************************************************************
    4634           0 :    FUNCTION mp_type_make_${nametype1}$ (ptr, &
    4635             :                                         vector_descriptor, index_descriptor) &
    4636             :       RESULT(type_descriptor)
    4637             :       ${type1}$, DIMENSION(:), TARGET, ASYNCHRONOUS     :: ptr
    4638             :       INTEGER, DIMENSION(2), INTENT(IN), OPTIONAL       :: vector_descriptor
    4639             :       TYPE(mp_indexing_meta_type), INTENT(IN), OPTIONAL :: index_descriptor
    4640             :       TYPE(mp_type_descriptor_type)                     :: type_descriptor
    4641             : 
    4642             :       CHARACTER(len=*), PARAMETER :: routineN = 'mp_type_make_${nametype1}$'
    4643             : 
    4644             : #if defined(__parallel)
    4645             :       INTEGER :: ierr
    4646             : #endif
    4647             : 
    4648             :       NULLIFY (type_descriptor%subtype)
    4649           0 :       type_descriptor%length = SIZE(ptr)
    4650             : #if defined(__parallel)
    4651           0 :       type_descriptor%type_handle = ${mpi_type1}$
    4652           0 :       CALL MPI_Get_address(ptr, type_descriptor%base, ierr)
    4653           0 :       IF (ierr /= 0) &
    4654           0 :          CPABORT("MPI_Get_address @ "//routineN)
    4655             : #else
    4656             :       type_descriptor%type_handle = ${handle1}$
    4657             : #endif
    4658           0 :       type_descriptor%vector_descriptor(1:2) = 1
    4659           0 :       type_descriptor%has_indexing = .FALSE.
    4660           0 :       type_descriptor%data_${nametype1}$ => ptr
    4661           0 :       IF (PRESENT(vector_descriptor) .OR. PRESENT(index_descriptor)) THEN
    4662           0 :          CPABORT(routineN//": Vectors and indices NYI")
    4663             :       END IF
    4664           0 :    END FUNCTION mp_type_make_${nametype1}$
    4665             : 
    4666             : ! **************************************************************************************************
    4667             : !> \brief Allocates an array, using MPI_ALLOC_MEM ... this is hackish
    4668             : !>        as the Fortran version returns an integer, which we take to be a C_PTR
    4669             : !> \param DATA           data array to allocate
    4670             : !> \param[in] len        length (in data elements) of data array allocation
    4671             : !> \param[out] stat      (optional) allocation status result
    4672             : ! **************************************************************************************************
    4673           0 :    SUBROUTINE mp_alloc_mem_${nametype1}$ (DATA, len, stat)
    4674             :       ${type1}$, CONTIGUOUS, DIMENSION(:), POINTER           :: DATA
    4675             :       INTEGER, INTENT(IN)                      :: len
    4676             :       INTEGER, INTENT(OUT), OPTIONAL           :: stat
    4677             : 
    4678             : #if defined(__parallel)
    4679             :       INTEGER                                  :: size, ierr, length, &
    4680             :                                                   mp_res
    4681             :       INTEGER(KIND=MPI_ADDRESS_KIND)           :: mp_size
    4682             :       TYPE(C_PTR)                              :: mp_baseptr
    4683             :       MPI_INFO_TYPE :: mp_info
    4684             : 
    4685           0 :       length = MAX(len, 1)
    4686           0 :       CALL MPI_TYPE_SIZE(${mpi_type1}$, size, ierr)
    4687           0 :       mp_size = INT(length, KIND=MPI_ADDRESS_KIND)*size
    4688           0 :       IF (mp_size .GT. mp_max_memory_size) THEN
    4689           0 :          CPABORT("MPI cannot allocate more than 2 GiByte")
    4690             :       END IF
    4691           0 :       mp_info = MPI_INFO_NULL
    4692           0 :       CALL MPI_ALLOC_MEM(mp_size, mp_info, mp_baseptr, mp_res)
    4693           0 :       CALL C_F_POINTER(mp_baseptr, DATA, (/length/))
    4694           0 :       IF (PRESENT(stat)) stat = mp_res
    4695             : #else
    4696             :       INTEGER                                 :: length, mystat
    4697             :       length = MAX(len, 1)
    4698             :       IF (PRESENT(stat)) THEN
    4699             :          ALLOCATE (DATA(length), stat=mystat)
    4700             :          stat = mystat ! show to convention checker that stat is used
    4701             :       ELSE
    4702             :          ALLOCATE (DATA(length))
    4703             :       END IF
    4704             : #endif
    4705           0 :    END SUBROUTINE mp_alloc_mem_${nametype1}$
    4706             : 
    4707             : ! **************************************************************************************************
    4708             : !> \brief Deallocates am array, ... this is hackish
    4709             : !>        as the Fortran version takes an integer, which we hope to get by reference
    4710             : !> \param DATA           data array to allocate
    4711             : !> \param[out] stat      (optional) allocation status result
    4712             : ! **************************************************************************************************
    4713           0 :    SUBROUTINE mp_free_mem_${nametype1}$ (DATA, stat)
    4714             :       ${type1}$, DIMENSION(:), &
    4715             :          POINTER, ASYNCHRONOUS                 :: DATA
    4716             :       INTEGER, INTENT(OUT), OPTIONAL           :: stat
    4717             : 
    4718             : #if defined(__parallel)
    4719             :       INTEGER                                  :: mp_res
    4720           0 :       CALL MPI_FREE_MEM(DATA, mp_res)
    4721           0 :       IF (PRESENT(stat)) stat = mp_res
    4722             : #else
    4723             :       DEALLOCATE (DATA)
    4724             :       IF (PRESENT(stat)) stat = 0
    4725             : #endif
    4726           0 :    END SUBROUTINE mp_free_mem_${nametype1}$
    4727             : #:endfor

Generated by: LCOV version 1.15