#include "unused_dummy.inc" !> Easier Fortran90 interface to the MPI Message Passing Library. !> !> (c) Copyright 1991 to 1998 by Michael A. Beer, William D. Dorland, !> P. B. Snyder, Q. P. Liu, and Gregory W. Hammett. ALL RIGHTS RESERVED. !> !> @note mp_mpi_r8.f90 is a version of mp_mpi.f90 to use when compiling !> with -r8 (where the default real type is taken to be 8 bytes). Just !> replaced all occurances of MPI_REAL with MPI_DOUBLE_PRECISION and !> MPI_COMPLEX with MPI_DOUBLE_COMPLEX. module mp use, intrinsic :: iso_fortran_env, only : error_unit #ifdef MPI # ifndef MPIINC use mpi # endif #endif implicit none private public :: init_mp, finish_mp public :: mp_initialized, timer_local, time_message public :: get_mp_times, reset_mp_times public :: broadcast, sum_reduce, nb_sum_reduce, sum_allreduce, nb_sum_allreduce public :: sum_allreduce_sub, nb_sum_allreduce_sub public :: broadcast_sub, sum_reduce_sub, nb_sum_reduce_sub public :: max_reduce, max_allreduce, nb_max_allreduce public :: min_reduce, min_allreduce, min_allreduce_sub public :: maxloc_allreduce public :: nproc, iproc, proc0, job public :: send, ssend, receive public :: send_init, recv_init, start_comm, free_request !For persistent comms public :: barrier public :: comm_type public :: waitany public :: mp_comm_self public :: mp_undefined, mp_status_size ! JH> new abort method public :: mp_abort ! needed by Trinity public :: scope, allprocs, subprocs public :: all_to_group, group_to_all ! Currently active communicator integer, pointer :: mp_comm !> Communicator for all processors integer, target :: comm_all = mp_comm_null !> Communicator for ensemble simulations integer, target :: comm_group = mp_comm_null !> Communicator for multiscale GS2 integer, target :: comm_multigs2 = mp_comm_null integer (kind(MPI_REAL)) :: mpireal, mpicmplx, mpi2real #ifndef SINGLE_PRECISION integer (kind(MPI_REAL)) :: mpicmplx8 #endif # else integer, target :: nproc_actual = 1, iproc_actual = 0 logical, target :: proc0_actual = .true. integer, pointer :: nproc => nproc_actual, iproc => iproc_actual logical, pointer :: proc0 => proc0_actual integer, target :: mp_comm_actual = -1 integer, pointer :: mp_comm => mp_comm_actual integer, parameter :: mp_info = -1 integer, parameter :: mp_comm_null = -1 integer, parameter :: mp_request_null = -1 integer, parameter :: mp_comm_self = -1 integer, parameter :: mp_undefined = -1 integer, parameter :: mp_status_size = 1 # endif !> Selectors for different communicator focuses integer, parameter :: allprocs = 0, subprocs = 1, multigs2procs = 2 integer :: job = 0 ! needed for Trinity -- MAB integer, dimension (:), allocatable :: grp0 !> True if the communicator has been initialised. !! Used for unit tests to work out whether to !! call mp_abort or stop logical :: mp_initialized = .false. !> If using nprocs File unit for the error file for [[mp_abort]] integer :: err_unit = error_unit !> Timers for mpi routines real, dimension(2) :: time_mp_other = 0., time_mp_collectives = 0. real, dimension(2) :: time_mp_ptp = 0., time_mp_sync = 0. !> A simple object for storing details of a communicator type comm_type sequence integer :: id = mp_comm_null !< The communicator id, used in calls to MPI routines integer :: iproc = -1 !< The procs local rank integer :: nproc = -1 !< The total number of processors in the communicator logical :: proc0 = .false. !< Is iproc equal to 0? end type comm_type interface wait module procedure wait_stat module procedure wait_nostat end interface interface waitall module procedure waitall_stat module procedure waitall_nostat end interface interface waitany module procedure waitany_stat module procedure waitany_nostat end interface interface testall module procedure testall_stat module procedure testall_nostat module procedure testall_nostat_noflag end interface interface nbsend module procedure nbsend_real_array module procedure nbsend_real_array_count module procedure nbsend_complex_array module procedure nbsend_complex_2d_array module procedure nbsend_complex_2d_array_count module procedure nbsend_complex_3d_array module procedure nbsend_complex_3d_array_count module procedure nbsend_complex_array_sub module procedure nbsend_complex_array_count end interface interface nbrecv module procedure nbrecv_real_array module procedure nbrecv_real_array_count module procedure nbrecv_complex_array module procedure nbrecv_complex_2d_array module procedure nbrecv_complex_2d_array_count module procedure nbrecv_complex_3d_array module procedure nbrecv_complex_3d_array_count module procedure nbrecv_complex_array_sub module procedure nbrecv_complex_array_count end interface interface send_init module procedure send_init_complex_array module procedure send_init_real_array end interface interface recv_init module procedure recv_init_complex_array module procedure recv_init_real_array end interface interface start_comm module procedure start_persist module procedure startall_persist end interface interface free_request module procedure free_handle_persist module procedure free_handles_persist end interface interface split module procedure split_nokey module procedure split_key module procedure split_nokey_to_commtype module procedure split_key_to_commtype module procedure split_nokey_to_commtype_sub module procedure split_key_to_commtype_sub end interface interface free_comm module procedure free_comm_id module procedure free_comm_type end interface interface allgather module procedure allgather_integer_array_1to1 end interface allgather interface allgatherv module procedure allgatherv_complex_array_1to1 module procedure allgatherv_complex_array_1to3 module procedure allgatherv_complex_array_1to1_sub module procedure allgatherv_complex_array_1to3_sub end interface interface nb_allgatherv module procedure nb_allgatherv_complex_array_1to1 module procedure nb_allgatherv_complex_array_1to3_sub end interface interface broadcast module procedure broadcast_integer module procedure broadcast_integer_array module procedure broadcast_integer_2array module procedure broadcast_real module procedure broadcast_real_array module procedure broadcast_real_2array module procedure broadcast_real_3array module procedure broadcast_real_4array module procedure broadcast_real_5array module procedure broadcast_complex module procedure broadcast_complex_array #ifndef SINGLE_PRECISION ! This is needed for the gs2_gryfx_zonal module module procedure broadcast_complex8_array #endif module procedure broadcast_complex_2array module procedure broadcast_complex_3array module procedure broadcast_complex_4array module procedure broadcast_logical module procedure broadcast_logical_array module procedure broadcast_logical_2array module procedure bcastfrom_integer module procedure bcastfrom_integer_array module procedure bcastfrom_real module procedure bcastfrom_real_array module procedure bcastfrom_complex module procedure bcastfrom_complex_array module procedure bcastfrom_complex_2array module procedure bcastfrom_complex_3array module procedure bcastfrom_logical module procedure bcastfrom_logical_array module procedure broadcast_character module procedure broadcast_character_array module procedure bcastfrom_character end interface interface broadcast_sub module procedure bcastfrom_complex_array_sub module procedure bcastfrom_complex_2array_sub module procedure bcastfrom_complex_3array_sub module procedure bcastfrom_complex_4array_sub end interface interface sum_reduce_sub module procedure sum_reduce_complex_array_sub module procedure sum_reduce_complex_2array_sub module procedure sum_reduce_complex_3array_sub module procedure sum_reduce_complex_4array_sub end interface interface nb_sum_reduce_sub module procedure nb_sum_reduce_complex_array_sub module procedure nb_sum_reduce_complex_4array_sub end interface interface sum_reduce module procedure sum_reduce_logical module procedure sum_reduce_integer module procedure sum_reduce_integer_array module procedure sum_reduce_integer_2array module procedure sum_reduce_real module procedure sum_reduce_real_array module procedure sum_reduce_real_2array module procedure sum_reduce_real_3array module procedure sum_reduce_real_4array module procedure sum_reduce_real_5array module procedure sum_reduce_complex module procedure sum_reduce_complex_array module procedure sum_reduce_complex_2array module procedure sum_reduce_complex_3array module procedure sum_reduce_complex_4array module procedure sum_reduce_complex_5array end interface interface nb_sum_reduce module procedure nb_sum_reduce_complex module procedure nb_sum_reduce_complex_array module procedure nb_sum_reduce_complex_2array module procedure nb_sum_reduce_complex_3array module procedure nb_sum_reduce_complex_4array module procedure nb_sum_reduce_complex_5array end interface interface sum_allreduce module procedure sum_allreduce_integer module procedure sum_allreduce_integer_array module procedure sum_allreduce_integer_2array module procedure sum_allreduce_integer_3array module procedure sum_allreduce_real module procedure sum_allreduce_real_array module procedure sum_allreduce_real_2array module procedure sum_allreduce_real_3array module procedure sum_allreduce_real_4array module procedure sum_allreduce_real_5array module procedure sum_allreduce_complex module procedure sum_allreduce_complex_array module procedure sum_allreduce_complex_2array module procedure sum_allreduce_complex_3array module procedure sum_allreduce_complex_4array module procedure sum_allreduce_complex_5array end interface interface nb_sum_allreduce module procedure nb_sum_allreduce_integer module procedure nb_sum_allreduce_complex_array module procedure nb_sum_allreduce_complex_3array module procedure nb_sum_allreduce_complex_4array module procedure nb_sum_allreduce_complex_5array end interface interface sum_allreduce_sub module procedure sum_allreduce_sub_integer module procedure sum_allreduce_sub_integer_array module procedure sum_allreduce_sub_real module procedure sum_allreduce_sub_real_array module procedure sum_allreduce_sub_real_2array module procedure sum_allreduce_sub_real_3array module procedure sum_allreduce_sub_real_4array module procedure sum_allreduce_sub_real_5array module procedure sum_allreduce_sub_complex module procedure sum_allreduce_sub_complex_array module procedure sum_allreduce_sub_complex_2array module procedure sum_allreduce_sub_complex_3array module procedure sum_allreduce_sub_complex_4array module procedure sum_allreduce_sub_complex_5array end interface interface nb_sum_allreduce_sub module procedure nb_sum_allreduce_sub_complex_2array module procedure nb_sum_allreduce_sub_complex_4array end interface interface max_reduce module procedure max_reduce_integer module procedure max_reduce_integer_array module procedure max_reduce_real module procedure max_reduce_real_array end interface interface max_allreduce module procedure max_allreduce_integer module procedure max_allreduce_integer_array module procedure max_allreduce_real module procedure max_allreduce_real_array end interface interface nb_max_allreduce module procedure nb_max_allreduce_integer module procedure nb_max_allreduce_integer_array module procedure nb_max_allreduce_real module procedure nb_max_allreduce_real_array end interface interface min_reduce module procedure min_reduce_integer module procedure min_reduce_integer_array module procedure min_reduce_real module procedure min_reduce_real_array end interface interface min_allreduce module procedure min_allreduce_integer module procedure min_allreduce_integer_array module procedure min_allreduce_real module procedure min_allreduce_real_array end interface interface min_allreduce_sub module procedure min_allreduce_sub_integer end interface ! MRH interface maxloc_allreduce module procedure maxloc_allreduce_real module procedure maxloc_allreduce_real_array end interface interface land_allreduce module procedure land_allreduce_single_element end interface ! MRH interface send module procedure send_integer module procedure send_integer_array module procedure send_real module procedure send_real_array module procedure send_real_4d_array module procedure send_real_5d_array module procedure send_complex module procedure send_complex_array module procedure send_complex_2d_array module procedure send_complex_3d_array module procedure nonblocking_send_complex_array module procedure send_logical module procedure send_logical_array module procedure send_character end interface interface receive module procedure receive_integer module procedure receive_integer_array module procedure receive_real module procedure receive_real_array module procedure receive_real_4d_array module procedure receive_real_5d_array module procedure receive_complex module procedure receive_complex_array module procedure receive_complex_2array module procedure receive_complex_3d_array module procedure nonblocking_receive_complex_array module procedure receive_logical module procedure receive_logical_array module procedure receive_character end interface ! MAB> needed for Trinity ! synchronous sends interface ssend module procedure ssend_character module procedure ssend_integer module procedure ssend_integer_array module procedure ssend_real module procedure ssend_real_array module procedure ssend_complex module procedure ssend_complex_array module procedure ssend_complex_2array module procedure ssend_logical module procedure ssend_logical_array end interface ! send stuff from global proc0 to group proc0s interface all_to_group module procedure all_to_group_real module procedure all_to_group_real_array end interface ! send stuff from group proc0s to global proc0 interface group_to_all module procedure group_to_all_real module procedure group_to_all_real_array end interface ! Returns current requested timer values subroutine get_mp_times(total_time, overheads_time, collectives_time, ptp_time, sync_time) implicit none real, intent(out), optional :: total_time, overheads_time, collectives_time, ptp_time, sync_time if (present(total_time)) then total_time = time_mp_other(1) + time_mp_collectives(1) + & time_mp_ptp(1) + time_mp_sync(1) end if if (present(overheads_time)) overheads_time = time_mp_other(1) if (present(collectives_time)) collectives_time = time_mp_collectives(1) if (present(ptp_time)) ptp_time = time_mp_ptp(1) if (present(sync_time)) sync_time = time_mp_sync(1) end subroutine get_mp_times !> Resets mp timers to zero subroutine reset_mp_times implicit none time_mp_other = 0. time_mp_collectives = 0. time_mp_ptp = 0. time_mp_sync = 0. end subroutine reset_mp_times !> Returns CPU time in seconds function timer_local() # ifdef OPENMP !$ use omp_lib, only: omp_get_wtime # endif real :: timer_local timer_local=0. # ifdef OPENMP timer_local=omp_get_wtime() # else # if defined MPI && !defined MPIINC && !defined SINGLE_PRECISION timer_local=mpi_wtime() # else ! this routine is F95 standard call cpu_time(timer_local) # endif # endif end function timer_local !> This routine counts elapsed time between two calls. !> The two elements in `targ` will be populated by time_message !> and correspond to the cumulative time and the time at the last !> call to time_message for this entry or zero depending on if !> the second element is zero or non-zero. Essentially the second !> element acts both as a store for the time at a call and a flag !> which flip-flops, to work out if we're currently timing or not. subroutine time_message(lprint,targ,chmessage) use warning_helpers, only: is_zero implicit none character (len=*), intent(in) :: chmessage logical, intent(in) :: lprint real, intent(in out) :: targ(2) ! tsum and told real :: tnew real, parameter :: small_number=1.e-10 tnew=timer_local() if (is_zero(targ(2))) then !>RN targ(2) must be non-zero at initialization. if (is_zero(tnew)) tnew = small_number targ(2) = tnew else targ(1)=targ(1)+tnew-targ(2) if (lprint) print *, chmessage,': ',tnew-targ(2),' seconds' targ(2)=0. end if end subroutine time_message !/ MPI related routines !> FIXME : Add documentation subroutine get_proc_name(nm) implicit none #ifdef MPI character*(MPI_MAX_PROCESSOR_NAME), intent(out) :: nm integer :: ierr, len #else character(len=5), intent(out) :: nm #endif #ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_get_processor_name(nm,len,ierr) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER #else nm="local" #endif end subroutine get_proc_name !> Initialise the MPI library, communicators, and related variables subroutine init_mp (comm_in, multigs2, err_unit_in) #ifdef MPI use constants, only: pi, kind_rs, kind_rd #ifdef SHMEM use shm_mpi3 #endif #endif use optionals, only : get_option_with_default implicit none !> Communicator to use instead of `MPI_COMM_WORLD`. If present and !> set to `MPI_COMM_NULL`, gets set to `MPI_COMM_WORLD` integer, intent (inout), optional :: comm_in !> If true, initialise multiscale communicator and variables logical, intent (in), optional :: multigs2 !> Unit of open file to write any error messages to. Defaults to stderr integer, intent (in), optional :: err_unit_in # ifdef MPI integer :: ierror, err_unit_local #ifdef OPENMP integer :: provided #endif logical :: is_initialised, is_multiscale err_unit_local = get_option_with_default(err_unit_in, err_unit) call mpi_initialized (is_initialised, ierror) #ifdef OPENMP if (.not. is_initialised) then call mpi_init_thread(MPI_THREAD_MULTIPLE, provided, ierror) if(provided .ne. MPI_THREAD_MULTIPLE) then write(err_unit_local,*) 'Problem with MPI_INIT_THREAD, stopping' stop end if end if #else if (.not. is_initialised) call mpi_init (ierror) #endif is_multiscale = get_option_with_default(multigs2, .false.) if (is_multiscale) then call init_comm(comm_multigs2, mulntot_proc, mulproc, mulproc0, comm_in) else call init_comm(comm_all, ntot_proc, aproc, aproc0, comm_in) end if if (is_multiscale) then call scope(multigs2procs) else call scope(allprocs) #ifdef SHMEM call shm_init(comm_all) #endif end if #ifndef SINGLE_PRECISION mpicmplx8 = MPI_COMPLEX #endif if ( (kind(pi)==kind_rs) .and. (kind_rs/=kind_rd) ) then mpireal = MPI_REAL mpi2real = MPI_2REAL mpicmplx = MPI_COMPLEX else if (kind(pi)==kind_rd) then mpireal = MPI_DOUBLE_PRECISION mpi2real = MPI_2DOUBLE_PRECISION mpicmplx = MPI_DOUBLE_COMPLEX else write (err_unit_local, *) 'ERROR: precision mismatch in mpi' error stop 'ERROR: precision mismatch in mpi' end if # else UNUSED_DUMMY(comm_in); UNUSED_DUMMY(multigs2); UNUSED_DUMMY(err_unit_in) # endif mp_initialized = .true. end subroutine init_mp #ifdef MPI !> Initialise a communicator and associated variables !> !> Defaults to using `MPI_COMM_WORLD`, but can be set to another !> communicator `comm_in`. subroutine init_comm(comm, total_procs, rank, is_rank0, comm_in) !> Communicator to initialise integer, intent(out) :: comm !> Total number of processors in communicator integer, intent(out) :: total_procs !> This processor's rank integer, intent(out) :: rank !> True if this processor's rank is zero logical, intent(out) :: is_rank0 !> Communicator to use instead of `MPI_COMM_WORLD`: if this is !> `MPI_COMM_NULL`, this is also initialised to `MPI_COMM_WORLD` integer, intent(inout), optional :: comm_in integer :: ierror if (present(comm_in)) then if (comm_in == mp_comm_null) then comm_in = mpi_comm_world end if comm = comm_in else comm = mpi_comm_world end if !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_size(comm, total_procs, ierror) call mpi_comm_rank(comm, rank, ierror) is_rank0 = (rank == 0) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER end subroutine init_comm #endif !> How many procs are in passed communicator subroutine nproc_comm(comm,nproc) integer, intent(in) :: comm integer, intent(out) :: nproc #ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_size(comm,nproc,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER #else UNUSED_DUMMY(comm) nproc = 1 #endif end subroutine nproc_comm !> What is rank of current proc in passed communicator subroutine rank_comm(comm,rank) integer, intent(in) :: comm integer, intent(out) :: rank #ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_rank(comm,rank,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER #else UNUSED_DUMMY(comm) rank = 0 #endif end subroutine rank_comm !> Switch the module communicator (and size/rank variables) between different scopes. subroutine scope (focus) !> Which scope to use. Should be one of [[allprocs]], [[multigs2procs]], !> [[subprocs]]. Other values are equivalent to [[subprocs]] integer, intent (in) :: focus # ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER if (focus == allprocs) then mp_comm => comm_all nproc => ntot_proc iproc => aproc proc0 => aproc0 else if (focus == multigs2procs) then mp_comm => comm_multigs2 nproc => mulntot_proc iproc => mulproc proc0 => mulproc0 else mp_comm => comm_group nproc => ngroup_proc iproc => gproc proc0 => gproc0 end if !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER # else UNUSED_DUMMY(focus) # endif end subroutine scope !> Finalise MPI library if it hasn't been finalised already subroutine finish_mp #ifdef MPI # ifdef SHMEM use shm_mpi3, only : shm_clean # endif implicit none integer :: ierror logical :: fin # ifdef SHMEM call shm_clean # endif call mpi_finalized (fin, ierror) if(.not.fin) call mpi_finalize (ierror) #endif mp_initialized = .false. end subroutine finish_mp ! ************** allgathers ***************************** !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine allgather_integer_array_1to1(arr,count,out,recvcnts) implicit none integer, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) integer, dimension(:), intent(out) :: out !< The gathered data integer, intent(in) :: recvcnts !< Array detailing how much data to expect from each proc # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_allgather(arr,count,MPI_INTEGER,out,recvcnts,& MPI_INTEGER,mp_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else out = reshape(arr, shape(out)) UNUSED_DUMMY(count); UNUSED_DUMMY(recvcnts) #endif end subroutine allgather_integer_array_1to1 !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine allgatherv_complex_array_1to1(arr,count,out,recvcnts,displs) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_allgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,mp_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else out = reshape(arr, shape(out)) UNUSED_DUMMY(count); UNUSED_DUMMY(recvcnts); UNUSED_DUMMY(displs) #endif end subroutine allgatherv_complex_array_1to1 !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine nb_allgatherv_complex_array_1to1(arr,count,out,recvcnts,displs,request) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored integer, intent(out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_iallgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,mp_comm,request,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call allgatherv_complex_array_1to1(arr,count,out,recvcnts,displs) request = mp_request_null #endif end subroutine nb_allgatherv_complex_array_1to1 !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine allgatherv_complex_array_1to3(arr,count,out,recvcnts,displs) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:,:,:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_allgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,mp_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else out = reshape(arr, shape(out)) UNUSED_DUMMY(count); UNUSED_DUMMY(recvcnts); UNUSED_DUMMY(displs) #endif end subroutine allgatherv_complex_array_1to3 !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine allgatherv_complex_array_1to1_sub(arr,count,out,recvcnts,displs,sub_comm) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored integer, intent(in) :: sub_comm !< Sub-communicator handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_allgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,sub_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else out = reshape(arr, shape(out)) UNUSED_DUMMY(count); UNUSED_DUMMY(recvcnts); UNUSED_DUMMY(displs); UNUSED_DUMMY(sub_comm) #endif end subroutine allgatherv_complex_array_1to1_sub !> A subroutine to do a allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine allgatherv_complex_array_1to3_sub(arr,count,out,recvcnts,displs,sub_comm) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:,:,:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored integer, intent(in) :: sub_comm !< Sub-communicator handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_allgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,sub_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER #else out = reshape(arr, shape(out)) UNUSED_DUMMY(count); UNUSED_DUMMY(recvcnts); UNUSED_DUMMY(displs); UNUSED_DUMMY(sub_comm) #endif end subroutine allgatherv_complex_array_1to3_sub !> A subroutine to do a non-blocking allgatherv operation, sending recvcnts(iproc) !! data from the iproc'th processor to all others starting at arr(start). subroutine nb_allgatherv_complex_array_1to3_sub(arr,count,out,recvcnts,displs,sub_comm,request) implicit none complex, dimension(:), intent(in) :: arr !< The data to gather integer, intent(in) :: count !< How much data to gather, <=SIZE(arr) complex, dimension(:,:,:), intent(out) :: out !< The gathered data integer, dimension(:), intent(in) :: recvcnts !< Array detailing how much data to expect from each proc integer, dimension(:), intent(in) :: displs !< Array detailing offset in array where gathered data is to be stored integer, intent(in) :: sub_comm !< Sub-communicator handle integer, intent(out) :: request !< FIXME : Add documentation # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER !Do the gather call mpi_iallgatherv(arr,count,mpicmplx,out,recvcnts,displs,& mpicmplx,sub_comm,request,ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER #else call allgatherv_complex_array_1to3_sub(arr,count,out,recvcnts,displs,sub_comm) request = mp_request_null #endif end subroutine nb_allgatherv_complex_array_1to3_sub ! ************** comm utils ***************************** !> A routine to free the communicator with id comm subroutine free_comm_id (comm) implicit none integer, intent(inout) :: comm !< Communicator id # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_free(comm,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER # endif comm = mp_comm_null end subroutine free_comm_id !> A routine to free the communicator represented by comm subroutine free_comm_type (comm) implicit none type(comm_type), intent(inout) :: comm !< Communicator object #ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_free(comm%id,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER #endif comm%id = mp_comm_null comm%iproc = -1 comm%nproc = -1 comm%proc0 = .false. end subroutine free_comm_type !> This function splits mp_comm into two pieces, !! one with nprocs_new procs, and one with all the !! remainder. For the remainder, included is set !! to false. This means that the remainder will lie !! idle. subroutine use_nproc(nprocs_new) implicit none integer, intent(in) :: nprocs_new integer :: colour included = (iproc < nprocs_new) colour = 1 if (included) colour = 0 call split_all(colour) end subroutine use_nproc !> FIXME : Add documentation subroutine unsplit_all(old_comm) implicit none integer, intent(in) :: old_comm #ifdef MPI integer :: ierror call free_comm_id(comm_all) comm_all = old_comm !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_size (comm_all, ntot_proc, ierror) call mpi_comm_rank (comm_all, aproc, ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER aproc0 = aproc == 0 included = .true. call scope (allprocs) #else UNUSED_DUMMY(old_comm) #endif end subroutine unsplit_all !> A routine to split the global communicator into sub-groups !! based on each procs specific colour "col". mp_comm is then overwritten !! to be the new split communicator !! This is different to job fork, which has the group and global communicators. !! The global communicator is replaced. !! This action can be undone with unsplit_all !! If the old mp_comm is not mpi_comm_world, you should make sure you have !! saved its value somewhere before calling this so that its value !! can be saved. subroutine split_all (col) implicit none integer, intent(inout) :: col !< Processors colour #ifdef MPI integer :: ierror, new_comm ! if (scope == subprocs) then ! write (*,*) 'Can only call split_all with global scope' ! call mpi_abort(comm_all, 1, ierror) ! end if !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group, note we use a constant key of 0 across all procs !meaning that the rank order is the same in the old and new communicators call mpi_comm_split(comm_all,col,aproc,new_comm,ierror) comm_all = new_comm call mpi_comm_size (comm_all, ntot_proc, ierror) call mpi_comm_rank (comm_all, aproc, ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER aproc0 = aproc == 0 call scope (allprocs) #else UNUSED_DUMMY(col) #endif end subroutine split_all !> A routine to split the mp_comm communicator into sub-groups !! based on each procs specific colour "col". The sub communicator's !! handle is passed back in new_comm !! !! In future we may wish to make split an interface to allow for !! user specific keys (to reorder processor ranks) and to specify !! a different communicator to split subroutine split_nokey (col,new_comm) implicit none integer, intent(inout) :: col !< Processors colour integer, intent(out) :: new_comm !< The new sub communicator's handle #ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group, note we use a constant key of 0 across all procs !meaning that the rank order is the same in the old and new communicators call mpi_comm_split(mp_comm,col,0,new_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER #else UNUSED_DUMMY(col) new_comm=-1 #endif end subroutine split_nokey !> A routine to split the mp_comm communicator into sub-groups !! based on each procs specific colour "col" and ranked by key. The sub communicator's !! handle is passed back in new_comm subroutine split_key (col,key,new_comm) implicit none integer, intent(in) :: col !< Processors colour integer, intent(in) :: key !< Processors key, used to determine rank integer, intent(out) :: new_comm !< The new sub communicator's handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group call mpi_comm_split(mp_comm,col,key,new_comm,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER # else UNUSED_DUMMY(col); UNUSED_DUMMY(key) new_comm = -1 # endif end subroutine split_key !> A routine to split the mp_comm communicator into sub-groups !! based on each procs specific colour "col". The sub communicator's !! handle is passed back in new_comm subroutine split_nokey_to_commtype (col,new_comm) implicit none integer, intent(in) :: col !< Processors colour type(comm_type), intent(out) :: new_comm !< The new sub communicator's handle # ifdef MPI integer :: ierror # endif integer :: comm_id, nproc, iproc # ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group, note we use a constant key of 0 across all procs !meaning that the rank order is the same in the old and new communicators call mpi_comm_split(mp_comm,col,0,comm_id,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !If the resulting communicator is the null communicator then !just return the default type with the appropriate id. if(comm_id == mp_comm_null) then new_comm%id = comm_id return end if # else UNUSED_DUMMY(col) comm_id = mp_comm_null # endif new_comm%id=comm_id call nproc_comm(comm_id,nproc) new_comm%nproc=nproc call rank_comm(comm_id,iproc) new_comm%iproc=iproc new_comm%proc0=iproc.eq.0 end subroutine split_nokey_to_commtype !> A routine to split the mp_comm communicator into sub-groups !! based on each procs specific colour "col" and ranked by key. The sub communicator's !! handle is passed back in new_comm subroutine split_key_to_commtype (col,key,new_comm) implicit none integer, intent(in) :: col !< Processors colour integer, intent(in) :: key !< Processors key, used to determine rank type(comm_type), intent(out) :: new_comm !< The new sub communicator's handle # ifdef MPI integer :: ierror # endif integer :: comm_id, nproc # ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group call mpi_comm_split(mp_comm,col,key,comm_id,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !If the resulting communicator is the null communicator then !just return the default type with the appropriate id. if(comm_id == mp_comm_null) then new_comm%id = comm_id return end if # else UNUSED_DUMMY(col); UNUSED_DUMMY(key) comm_id = mp_comm_null # endif new_comm%id=comm_id call nproc_comm(comm_id,nproc) new_comm%nproc=nproc call rank_comm(comm_id,nproc) new_comm%iproc=nproc new_comm%proc0=new_comm%iproc.eq.0 end subroutine split_key_to_commtype !> A routine to split a subcommunicator into sub-groups !! based on each procs specific colour "col". The sub communicator's !! handle is passed back in new_comm subroutine split_nokey_to_commtype_sub (col,new_comm,sub) implicit none integer, intent(in) :: col !< Processors colour type(comm_type), intent(out) :: new_comm !< The new sub communicator's handle integer, intent(in) :: sub # ifdef MPI integer :: ierror # endif integer :: comm_id, nproc, iproc !Split the comm group, note we use a constant key of 0 across all procs !meaning that the rank order is the same in the old and new communicators # ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_comm_split(sub,col,0,comm_id,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !If the resulting communicator is the null communicator then !just return the default type with the appropriate id. if(comm_id == mp_comm_null) then new_comm%id = comm_id return end if # else UNUSED_DUMMY(col); UNUSED_DUMMY(sub) comm_id = mp_comm_null # endif new_comm%id=comm_id call nproc_comm(comm_id,nproc) new_comm%nproc=nproc call rank_comm(comm_id,iproc) new_comm%iproc=iproc new_comm%proc0=iproc.eq.0 end subroutine split_nokey_to_commtype_sub !> A routine to split a subcommunicator into sub-groups !! based on each procs specific colour "col" and ranked by key. The sub communicator's !! handle is passed back in new_comm subroutine split_key_to_commtype_sub (col,key,new_comm,sub) implicit none integer, intent(in) :: col !< Processors colour integer, intent(in) :: key !< Processors key, used to determine rank type(comm_type), intent(out) :: new_comm !< The new sub communicator's handle integer, intent(in) :: sub !< Subcommunicator to split # ifdef MPI integer :: ierror # endif integer :: comm_id, nproc # ifdef MPI !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !Split the comm group call mpi_comm_split(sub,col,key,comm_id,ierror) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER !If the resulting communicator is the null communicator then !just return the default type with the appropriate id. if(comm_id == mp_comm_null) then new_comm%id = comm_id return end if # else UNUSED_DUMMY(col); UNUSED_DUMMY(key); UNUSED_DUMMY(sub) comm_id = mp_comm_null # endif new_comm%id=comm_id call nproc_comm(comm_id,nproc) new_comm%nproc=nproc call rank_comm(comm_id,nproc) new_comm%iproc=nproc new_comm%proc0=new_comm%iproc.eq.0 end subroutine split_key_to_commtype_sub ! ************** broadcasts ***************************** !> FIXME : Add documentation subroutine broadcast_character (char) implicit none character(*), intent (in out) :: char # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (char, len(char), MPI_CHARACTER, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(char) # endif end subroutine broadcast_character !> FIXME : Add documentation !! !! An array of characters, each of same length subroutine broadcast_character_array (char) implicit none character(len = *), dimension(:), intent (in out) :: char # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (char, size(char) * len(char(1)), MPI_CHARACTER, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else if (.false.) write(*,*) char # endif end subroutine broadcast_character_array !> FIXME : Add documentation subroutine broadcast_integer (i) implicit none integer, intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (i, 1, MPI_INTEGER, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine broadcast_integer !> FIXME : Add documentation subroutine broadcast_integer_array (i) implicit none integer, dimension (:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (i, size(i), MPI_INTEGER, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine broadcast_integer_array !> FIXME : Add documentation subroutine broadcast_integer_2array (i) implicit none integer, dimension (:,:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (i, size(i), MPI_INTEGER, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine broadcast_integer_2array !> FIAME : Add documentation subroutine broadcast_real (a) implicit none real, intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, 1, mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real !> FIAME : Add documentation subroutine broadcast_real_array (a) implicit none real, dimension (:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real_array !> FIXME : Add documentation subroutine broadcast_real_2array(a) implicit none real, dimension(:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real_2array !> FIAME : Add documentation subroutine broadcast_real_3array(a) implicit none real, dimension(:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real_3array !> FIXME : Add documentation subroutine broadcast_real_4array(a) implicit none real, dimension(:,:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real_4array !> FIXME : Add documentation subroutine broadcast_real_5array(a) implicit none real, dimension(:,:,:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine broadcast_real_5array !> FIXME : Add documentation subroutine broadcast_complex (z) implicit none complex, intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, 1, mpicmplx, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex !> FIXME : Add documentation subroutine broadcast_complex_array (z) implicit none complex, dimension (:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex_array #ifndef SINGLE_PRECISION !> FIXME : Add documentation subroutine broadcast_complex8_array (z) use constants, only: kind_rs implicit none complex (kind=kind_rs), dimension (:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx8, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex8_array #endif !> FIXME : Add documentation subroutine broadcast_complex_2array (z) implicit none complex, dimension (:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex_2array !> FIXME : Add documentation subroutine broadcast_complex_3array (z) implicit none complex, dimension (:,:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex_3array !> FIXME : Add documentation subroutine broadcast_complex_4array (z) implicit none complex, dimension (:,:,:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine broadcast_complex_4array !> FIXME : Add documentation subroutine broadcast_logical (f) implicit none logical, intent (in out) :: f # ifdef MPI integer :: ierror,rc !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (f, 1, MPI_LOGICAL, 0, mp_comm, ierror) if (ierror .ne. MPI_SUCCESS) & call MPI_ABORT(MPI_COMM_WORLD, rc, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(f) # endif end subroutine broadcast_logical !> FIXME : Add documentation subroutine broadcast_logical_array (f) implicit none logical, dimension (:), intent (in out) :: f # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (f, size(f), MPI_LOGICAL, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(f) # endif end subroutine broadcast_logical_array !> FIXME : Add documentation subroutine broadcast_logical_2array (f) implicit none logical, dimension (:,:), intent (in out) :: f # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (f, size(f), MPI_LOGICAL, 0, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(f) # endif end subroutine broadcast_logical_2array !> FIXME : Add documentation subroutine bcastfrom_logical (f, src) implicit none logical, intent (in out) :: f integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (f, 1, MPI_LOGICAL, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(f) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_logical !> FIXME : Add documentation subroutine bcastfrom_logical_array (f, src) implicit none logical, dimension (:), intent (in out) :: f integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (f, size(f), MPI_LOGICAL, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(f) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_logical_array !> FIXME : Add documentation subroutine bcastfrom_character (c, src) implicit none character(*), intent (in out) :: c integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (c, len(c), MPI_CHARACTER, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(c) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_character !> FIXME : Add documentation subroutine bcastfrom_integer (i, src) implicit none integer, intent (in out) :: i integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (i, 1, MPI_INTEGER, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_integer !> FIXME : Add documentation subroutine bcastfrom_integer_array (i, src) implicit none integer, dimension (:), intent (in out) :: i integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (i, size(i), MPI_INTEGER, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_integer_array !> FIXME : Add documentation subroutine bcastfrom_real (a, src) implicit none real, intent (in out) :: a integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, 1, mpireal, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_real !> FIXME : Add documentation subroutine bcastfrom_real_array (a, src) implicit none real, dimension (:), intent (in out) :: a integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (a, size(a), mpireal, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_real_array !> FIXME : Add documentation subroutine bcastfrom_complex (z, src) implicit none complex, intent (in out) :: z integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, 1, mpicmplx, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_complex !> FIXME : Add documentation subroutine bcastfrom_complex_array (z, src) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_complex_array !> FIXME : Add documentation subroutine bcastfrom_complex_2array (z, src) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent (in) :: src # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_complex_2array !> FIXME : Add documentation subroutine bcastfrom_complex_3array (z, src) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (in) :: src # ifdef MPI integer :: ierror call time_message(.false., time_mp_collectives, ' MPI Collectives') call mpi_bcast (z, size(z), mpicmplx, src, mp_comm, ierror) call time_message(.false., time_mp_collectives, ' MPI Collectives') # else UNUSED_DUMMY(z) if (src /= 0) call mp_abort ("broadcast from") # endif end subroutine bcastfrom_complex_3array !******************BROADCAST SUB************************* !> FIXME : Add documentation subroutine bcastfrom_complex_array_sub (z, src, sub) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: src integer, intent (in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, sub, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (src /= 0) call mp_abort ("broadcast from sub") # endif end subroutine bcastfrom_complex_array_sub !> FIXME : Add documentation subroutine bcastfrom_complex_2array_sub (z, src, sub) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent (in) :: src integer, intent (in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, sub, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (src /= 0) call mp_abort ("broadcast from sub") # endif end subroutine bcastfrom_complex_2array_sub !> FIXME : Add documentation subroutine bcastfrom_complex_3array_sub (z, src, sub) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (in) :: src integer, intent (in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, sub, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (src /= 0) call mp_abort ("broadcast from sub") # endif end subroutine bcastfrom_complex_3array_sub !> FIXME : Add documentation subroutine bcastfrom_complex_4array_sub (z, src, sub) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (in) :: src integer, intent (in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_bcast (z, size(z), mpicmplx, src, sub, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (src /= 0) call mp_abort ("broadcast from sub") # endif end subroutine bcastfrom_complex_4array_sub ! ************** reductions *********************** !> FIXME : Add documentation subroutine sum_reduce_integer (i, dest) implicit none integer, intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (i, i, 1, MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_integer !> FIXME : Add documentation subroutine sum_reduce_integer_array (i, dest) implicit none integer, dimension (:), intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (i, i, size(i), MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_integer_array !> FIXME : Add documentation subroutine sum_reduce_integer_2array (a, dest) implicit none integer, dimension (:,:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), MPI_INTEGER, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_integer_2array !> FIXME : Add documentation subroutine sum_reduce_logical (a, dest) implicit none logical, intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, 1, MPI_LOGICAL, MPI_LOR, dest, mp_comm, ierror) else call mpi_reduce & (a, a, 1, MPI_LOGICAL, MPI_LOR, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_logical !> FIXME : Add documentation subroutine sum_reduce_real (a, dest) implicit none real, intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, 1, mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real !> FIXME : Add documentation subroutine sum_reduce_real_array (a, dest) implicit none real, dimension (:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real_array !> FIXME : Add documentation subroutine sum_reduce_real_2array (a, dest) implicit none real, dimension (:,:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real_2array !> FIXME : Add documentation subroutine sum_reduce_real_3array (a, dest) implicit none real, dimension (:,:,:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real_3array !> FIXME : Add documentation subroutine sum_reduce_real_4array (a, dest) implicit none real, dimension (:,:,:,:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real_4array !> FIXME : Add documentation subroutine sum_reduce_real_5array (a, dest) implicit none real, dimension (:,:,:,:,:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_real_5array !> FIXME : Add documentation subroutine sum_reduce_complex (z, dest) implicit none complex, intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, 1, mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, 1, mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex !> FIXME : Add documentation subroutine sum_reduce_complex_array (z, dest) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_array !> FIXME : Add documentation subroutine sum_reduce_complex_2array (z, dest) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_2array !> FIXME : Add documentation subroutine sum_reduce_complex_3array (z, dest) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_3array !> FIXME : Add documentation subroutine sum_reduce_complex_4array (z, dest) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_4array !> FIXME : Add documentation subroutine sum_reduce_complex_5array (z, dest) implicit none complex, dimension (:,:,:,:,:), intent (in out) :: z integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if (iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_5array !******************NON-BLOCKING SUM REDUCE************************* !> FIXME : Add documentation subroutine nb_sum_reduce_complex (z, dest, request) implicit none complex, intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, 1, mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, 1, mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex !> FIXME : Add documentation subroutine nb_sum_reduce_complex_array (z, dest, request) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_array !> FIXME : Add documentation subroutine nb_sum_reduce_complex_2array (z, dest, request) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_2array !> FIXME : Add documentation subroutine nb_sum_reduce_complex_3array (z, dest, request) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce_complex_3array(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_3array !> FIXME : Add documentation subroutine nb_sum_reduce_complex_4array (z, dest, request) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce_complex_4array(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_4array !> FIXME : Add documentation subroutine nb_sum_reduce_complex_5array (z, dest, request) implicit none complex, dimension (:,:,:,:,:), intent (in out) :: z integer, intent (in) :: dest integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if (iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, mp_comm, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce(z, dest) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_5array !******************SUM REDUCE SUB************************* !> FIXME : Add documentation subroutine sum_reduce_complex_array_sub (z, dest, sub) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_array_sub !> FIXME : Add documentation subroutine sum_reduce_complex_2array_sub (z, dest, sub) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_2array_sub !> FIXME : Add documentation subroutine sum_reduce_complex_3array_sub (z, dest, sub) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_3array_sub !> FIXME : Add documentation subroutine sum_reduce_complex_4array_sub (z, dest, sub) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_reduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) else call mpi_reduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(sub) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine sum_reduce_complex_4array_sub !******************NON-BLOCKING SUM REDUCE SUB************************* !> FIXME : Add documentation subroutine nb_sum_reduce_complex_array_sub (z, dest, sub, request) implicit none complex, dimension (:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce_complex_array_sub(z, dest, sub) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_array_sub !> FIXME : Add documentation subroutine nb_sum_reduce_complex_4array_sub (z, dest, sub, request) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (in) :: dest type(comm_type), intent(in) :: sub integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(sub%iproc.eq.dest) then call mpi_ireduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, request, ierror) else call mpi_ireduce & (z, z, size(z), mpicmplx, MPI_SUM, dest, sub%id, request, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_reduce_complex_4array_sub(z, dest, sub) request = mp_request_null # endif end subroutine nb_sum_reduce_complex_4array_sub !******************SUM ALLREDUCE************************* !> FIXME : Add documentation subroutine sum_allreduce_integer (i) implicit none integer, intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_integer !> FIXME : Add documentation subroutine sum_allreduce_integer_array (i) implicit none integer, dimension (:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_integer_array !> FIXME : Add documentation subroutine sum_allreduce_integer_2array (i) implicit none integer, dimension (:,:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_integer_2array !> FIXME : Add documentation subroutine sum_allreduce_integer_3array (i) implicit none integer, dimension (:,:,:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_integer_3array !> FIXME : Add documentation subroutine sum_allreduce_real (a) implicit none real, intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real !> FIXME : Add documentation subroutine sum_allreduce_real_array (a) implicit none real, dimension (:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real_array !> FIXME : Add documentation subroutine sum_allreduce_real_2array (a) implicit none real, dimension (:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real_2array !> FIXME : Add documentation subroutine sum_allreduce_real_3array (a) implicit none real, dimension (:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real_3array !> FIXME : Add documentation subroutine sum_allreduce_real_4array (a) implicit none real, dimension (:,:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real_4array !> FIXME : Add documentation subroutine sum_allreduce_real_5array (a) implicit none real, dimension (:,:,:,:,:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_real_5array !> FIXME : Add documentation subroutine sum_allreduce_complex (z) implicit none complex, intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, 1, mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex !> FIXME : Add documentation subroutine sum_allreduce_complex_array (z) implicit none complex, dimension (:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex_array !> FIXME : Add documentation subroutine sum_allreduce_complex_2array (z) implicit none complex, dimension (:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex_2array !> FIXME : Add documentation subroutine sum_allreduce_complex_3array (z) implicit none complex, dimension (:,:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex_3array !> FIXME : Add documentation subroutine sum_allreduce_complex_4array (z) implicit none complex, dimension (:,:,:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex_4array !> FIXME : Add documentation subroutine sum_allreduce_complex_5array (z) implicit none complex, dimension (:,:,:,:,:), intent (in out) :: z # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_complex_5array !/Sub-communicator allreduce !> FIXME : Add documentation subroutine sum_allreduce_sub_integer (i,sub_comm) implicit none integer, intent (in out) :: i integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_sub_integer !> FIXME : Add documentation subroutine sum_allreduce_sub_integer_array (i,sub_comm) implicit none integer, dimension (:), intent (in out) :: i integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(i) # endif end subroutine sum_allreduce_sub_integer_array !> FIXME : Add documentation subroutine sum_allreduce_sub_real (a,sub_comm) implicit none real, intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real !> FIXME : Add documentation subroutine sum_allreduce_sub_real_array (a,sub_comm) implicit none real, dimension (:), intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real_array !> FIXME : Add documentation subroutine sum_allreduce_sub_real_2array (a,sub_comm) implicit none real, dimension (:,:), intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real_2array !> FIXME : Add documentation subroutine sum_allreduce_sub_real_3array (a,sub_comm) implicit none real, dimension (:,:,:), intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real_3array !> FIXME : Add documentation subroutine sum_allreduce_sub_real_4array (a,sub_comm) implicit none real, dimension (:,:,:,:), intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real_4array !> FIXME : Add documentation subroutine sum_allreduce_sub_real_5array (a,sub_comm) implicit none real, dimension (:,:,:,:,:), intent (in out) :: a integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(a) # endif end subroutine sum_allreduce_sub_real_5array !> FIXME : Add documentation subroutine sum_allreduce_sub_complex (z,sub_comm) implicit none complex, intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, 1, mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex !> FIXME : Add documentation subroutine sum_allreduce_sub_complex_array (z,sub_comm) implicit none complex, dimension (:), intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex_array !> FIXME : Add documentation subroutine sum_allreduce_sub_complex_2array (z,sub_comm) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex_2array !> FIXME : Add documentation subroutine sum_allreduce_sub_complex_3array (z,sub_comm) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex_3array !> FIXME : Add documentation subroutine sum_allreduce_sub_complex_4array (z,sub_comm) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex_4array !> FIXME : Add documentation subroutine sum_allreduce_sub_complex_5array (z,sub_comm) implicit none complex, dimension (:,:,:,:,:), intent (in out) :: z integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(sub_comm); UNUSED_DUMMY(z) # endif end subroutine sum_allreduce_sub_complex_5array !******************NON-BLOCKING SUM ALLREDUCE SUB************************* !> FIXME : Add documentation subroutine nb_sum_allreduce_sub_complex_2array (z,sub_comm,request) implicit none complex, dimension (:,:), intent (in out) :: z integer, intent(in) :: sub_comm integer, intent(out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce_sub(z, sub_comm) request = mp_request_null # endif end subroutine nb_sum_allreduce_sub_complex_2array !> FIXME : Add documentation subroutine nb_sum_allreduce_sub_complex_4array (z,sub_comm,request) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent(in) :: sub_comm integer, intent(out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, sub_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce_sub(z, sub_comm) request = mp_request_null # endif end subroutine nb_sum_allreduce_sub_complex_4array !******************NON-BLOCKING SUM ALLREDUCE************************* !> FIXME : Add documentation subroutine nb_sum_allreduce_integer (i, request) implicit none integer, intent (in out) :: i integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_SUM, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce(i) request = mp_request_null # endif end subroutine nb_sum_allreduce_integer !> FIXME : Add documentation subroutine nb_sum_allreduce_complex_array (z, request) implicit none complex, dimension (:), intent (in out) :: z integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce(z) request = mp_request_null # endif end subroutine nb_sum_allreduce_complex_array !> FIXME : Add documentation subroutine nb_sum_allreduce_complex_3array (z, request) implicit none complex, dimension (:,:,:), intent (in out) :: z integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce(z) request = mp_request_null # endif end subroutine nb_sum_allreduce_complex_3array !> FIXME : Add documentation subroutine nb_sum_allreduce_complex_4array (z, request) implicit none complex, dimension (:,:,:,:), intent (in out) :: z integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce(z) request = mp_request_null # endif end subroutine nb_sum_allreduce_complex_4array !> FIXME : Add documentation subroutine nb_sum_allreduce_complex_5array (z, request) implicit none complex, dimension (:,:,:,:,:), intent (in out) :: z integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, z, size(z), mpicmplx, MPI_SUM, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call sum_allreduce(z) request = mp_request_null # endif end subroutine nb_sum_allreduce_complex_5array !*******************MAX REDUCE************************* !> FIXME : Add documentation subroutine max_reduce_integer (i, dest) implicit none integer, intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MAX, dest, mp_comm, ierror) else call mpi_reduce & (i, i, 1, MPI_INTEGER, MPI_MAX, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine max_reduce_integer !> FIXME : Add documentation subroutine max_reduce_integer_array (i, dest) implicit none integer, dimension (:), intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_MAX, dest, mp_comm, ierror) else call mpi_reduce & (i, i, size(i), MPI_INTEGER, MPI_MAX, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine max_reduce_integer_array !> FIXME : Add documentation subroutine max_reduce_real (a, dest) implicit none real, intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_MAX, dest, mp_comm, ierror) else call mpi_reduce & (a, a, 1, mpireal, MPI_MAX, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine max_reduce_real !> FIXME : Add documentation subroutine max_reduce_real_array (a, dest) implicit none real, dimension (:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_MAX, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_MAX, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine max_reduce_real_array !> FIXME : Add documentation subroutine max_allreduce_integer (i) implicit none integer, intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MAX, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine max_allreduce_integer !> FIXME : Add documentation subroutine max_allreduce_integer_array (i) implicit none integer, dimension (:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_MAX, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine max_allreduce_integer_array !> FIXME : Add documentation subroutine max_allreduce_real (a) implicit none real, intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_MAX, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine max_allreduce_real !> FIXME : Add documentation subroutine max_allreduce_real_array (a) implicit none real, dimension (:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_MAX, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine max_allreduce_real_array !> FIXME : Add documentation subroutine maxloc_allreduce_real(a,i) implicit none real, intent (in out) :: a integer, intent (in out) :: i # ifdef MPI real, dimension(:,:), allocatable :: ai integer :: ierror allocate (ai(1,2)) ai(1,1)=a ai(1,2)=real(i,kind=kind(a)) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, ai, 1, mpi2real, MPI_MAXLOC, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER a=ai(1,1) i=int(ai(1,2)) deallocate(ai) # else UNUSED_DUMMY(a) ; UNUSED_DUMMY(i) # endif end subroutine maxloc_allreduce_real !> FIXME : Add documentation subroutine maxloc_allreduce_real_array (a,i) implicit none real, dimension (:), intent (in out) :: a integer, dimension (:), intent (in out) :: i # ifdef MPI real, dimension(:,:), allocatable :: ai integer :: ierror allocate (ai(size(a),2)) ai(:,1)=a(:) ai(:,2)=real(i(:),kind=kind(a(1))) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, ai, size(a), mpi2real, MPI_MAXLOC, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER a(:)=ai(:,1) i(:)=int(ai(:,2)) deallocate(ai) # else UNUSED_DUMMY(a) ; UNUSED_DUMMY(i) # endif end subroutine maxloc_allreduce_real_array !> FIXME : Add documentation subroutine nb_max_allreduce_integer (i,request) implicit none integer, intent (in out) :: i integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MAX, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call max_allreduce(i) request = mp_request_null # endif end subroutine nb_max_allreduce_integer !> FIXME : Add documentation subroutine nb_max_allreduce_integer_array (i, request) implicit none integer, dimension (:), intent (in out) :: i integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_MAX, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call max_allreduce(i) request = mp_request_null # endif end subroutine nb_max_allreduce_integer_array !> FIXME : Add documentation subroutine nb_max_allreduce_real (a, request) implicit none real, intent (in out) :: a integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_MAX, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call max_allreduce(a) request = mp_request_null # endif end subroutine nb_max_allreduce_real !> FIXME : Add documentation subroutine nb_max_allreduce_real_array (a, request) implicit none real, dimension (:), intent (in out) :: a integer, intent (out) :: request # ifdef MPI3 integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_iallreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_MAX, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else call max_allreduce(a) request = mp_request_null # endif end subroutine nb_max_allreduce_real_array !> FIXME : Add documentation subroutine min_reduce_integer (i, dest) implicit none integer, intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MIN, dest, mp_comm, ierror) else call mpi_reduce & (i, i, 1, MPI_INTEGER, MPI_MIN, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine min_reduce_integer !> FIXME : Add documentation subroutine min_reduce_integer_array (i, dest) implicit none integer, dimension (:), intent (in out) :: i integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_MIN, dest, mp_comm, ierror) else call mpi_reduce & (i, i, size(i), MPI_INTEGER, MPI_MIN, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine min_reduce_integer_array !> FIXME : Add documentation subroutine min_reduce_real (a, dest) implicit none real, intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_MIN, dest, mp_comm, ierror) else call mpi_reduce & (a, a, 1, mpireal, MPI_MIN, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine min_reduce_real !> FIXME : Add documentation subroutine min_reduce_real_array (a, dest) implicit none real, dimension (:), intent (in out) :: a integer, intent (in) :: dest # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER if(iproc.eq.dest)then call mpi_reduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_MIN, dest, mp_comm, ierror) else call mpi_reduce & (a, a, size(a), mpireal, MPI_MIN, dest, mp_comm, ierror) endif !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) if (dest /= 0) call mp_abort ("reduce to") # endif end subroutine min_reduce_real_array !> FIXME : Add documentation subroutine min_allreduce_integer (i) implicit none integer, intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MIN, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine min_allreduce_integer !> FIXME : Add documentation subroutine min_allreduce_integer_array (i) implicit none integer, dimension (:), intent (in out) :: i # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, size(i), MPI_INTEGER, MPI_MIN, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i) # endif end subroutine min_allreduce_integer_array !> FIXME : Add documentation subroutine min_allreduce_real (a) implicit none real, intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, 1, mpireal, MPI_MIN, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine min_allreduce_real !> FIXME : Add documentation subroutine min_allreduce_real_array (a) implicit none real, dimension (:), intent (in out) :: a # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, a, size(a), mpireal, MPI_MIN, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(a) # endif end subroutine min_allreduce_real_array !> FIXME : Add documentation subroutine min_allreduce_sub_integer (i, sub_comm) implicit none integer, intent (in out) :: i integer, intent(in) :: sub_comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, i, 1, MPI_INTEGER, MPI_MIN, sub_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(i); UNUSED_DUMMY(sub_comm) # endif end subroutine min_allreduce_sub_integer ! ****************** LAND ALLREDUCE******************* !> FIXME : Add documentation subroutine land_allreduce_single_element (l) implicit none logical, intent (in out) :: l # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER call mpi_allreduce & (MPI_IN_PLACE, l, 1, MPI_LOGICAL, MPI_LAND, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_collectives, ' MPI Collectives') !$OMP END MASTER # else UNUSED_DUMMY(l) # endif end subroutine land_allreduce_single_element ! ********************* barrier ********************** !> FIXME : Add documentation subroutine barrier_nocomm # ifdef MPI implicit none integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_barrier (mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # endif end subroutine barrier_nocomm subroutine barrier_comm(comm) implicit none integer,intent(in)::comm # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_barrier (comm, ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(comm) # endif end subroutine barrier_comm ! ********************* sends ********************** !> FIXME : Add documentation subroutine send_integer (i, dest, tag) implicit none integer, intent (in) :: i integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (i, 1, MPI_INTEGER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(i) # endif end subroutine send_integer !> FIXME : Add documentation subroutine send_integer_array (i, dest, tag) implicit none integer, dimension (:), intent (in) :: i integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (i, size(i), MPI_INTEGER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(i) # endif end subroutine send_integer_array !> FIXME : Add documentation subroutine send_real (a, dest, tag) implicit none real, intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (a, 1, mpireal, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine send_real !> FIXME : Add documentation subroutine send_real_array (a, dest, tag) implicit none real, dimension (:), intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (a, size(a), mpireal, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine send_real_array !> FIXME : Add documentation subroutine send_real_4d_array (a, dest, tag) implicit none real, dimension (:,:,:,:), intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (a, size(a), mpireal, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine send_real_4d_array !> FIXME : Add documentation subroutine send_real_5d_array (a, dest, tag) implicit none real, dimension (:,:,:,:,:), intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (a, size(a), mpireal, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine send_real_5d_array !> FIXME : Add documentation subroutine send_complex (z, dest, tag) implicit none complex, intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (z, 1, mpicmplx, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine send_complex !> FIXME : Add documentation subroutine send_complex_array (z, dest, tag) implicit none complex, dimension (:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (z, size(z), mpicmplx, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine send_complex_array !> FIXME : Add documentation subroutine send_complex_2d_array (z, dest, tag) implicit none complex, dimension (:,:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (z, size(z), mpicmplx, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine send_complex_2d_array !> FIXME : Add documentation subroutine send_complex_3d_array (z, dest, tag) implicit none complex, dimension (:,:,:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (z, size(z), mpicmplx, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine send_complex_3d_array !> FIXME : Add documentation subroutine nonblocking_send_complex_array (z, dest, tag, request) implicit none complex, dimension (:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag integer, intent (out) :: request # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend (z, size(z), mpicmplx, dest, tagp, mp_comm, request, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) request = 0 # endif end subroutine nonblocking_send_complex_array !> FIXME : Add documentation subroutine send_logical (f, dest, tag) implicit none logical, intent (in) :: f integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (f, 1, MPI_LOGICAL, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(f) # endif end subroutine send_logical !> FIXME : Add documentation subroutine send_logical_array (f, dest, tag) implicit none logical, dimension (:), intent (in) :: f integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send (f, size(f), MPI_LOGICAL, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(f) # endif end subroutine send_logical_array !> FIXME : Add documentation subroutine send_character (s, dest, tag) implicit none character(*), intent (in) :: s integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send & (s, len(s), MPI_CHARACTER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(s) # endif end subroutine send_character ! MAB> needed for Trinity ! ********************* synchronous sends ********************** !> FIXME : Add documentation subroutine ssend_integer (i, dest, tag) implicit none integer, intent (in) :: i integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (i, 1, MPI_INTEGER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(i) # endif end subroutine ssend_integer !> FIXME : Add documentation subroutine ssend_integer_array (i, dest, tag) implicit none integer, dimension (:), intent (in) :: i integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (i, size(i), MPI_INTEGER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(i) # endif end subroutine ssend_integer_array !> FIXME : Add documentation subroutine ssend_real (a, dest, tag) implicit none real, intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (a, 1, MPI_DOUBLE_PRECISION, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine ssend_real !> FIXME : Add documentation subroutine ssend_real_array (a, dest, tag) implicit none real, dimension (:), intent (in) :: a integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (a, size(a), MPI_DOUBLE_PRECISION, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(a) # endif end subroutine ssend_real_array !> FIXME : Add documentation subroutine ssend_complex (z, dest, tag) implicit none complex, intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (z, 1, MPI_DOUBLE_COMPLEX, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine ssend_complex !> FIXME : Add documentation subroutine ssend_complex_array (z, dest, tag) implicit none complex, dimension (:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (z, size(z), MPI_DOUBLE_COMPLEX, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine ssend_complex_array !> FIXME : Add documentation subroutine ssend_complex_2array (z, dest, tag) implicit none complex, dimension (:,:), intent (in) :: z integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (z, size(z), MPI_DOUBLE_COMPLEX, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) # endif end subroutine ssend_complex_2array !> FIXME : Add documentation subroutine ssend_logical (f, dest, tag) implicit none logical, intent (in) :: f integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (f, 1, MPI_LOGICAL, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(f) # endif end subroutine ssend_logical !> FIXME : Add documentation subroutine ssend_logical_array (f, dest, tag) implicit none logical, dimension (:), intent (in) :: f integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend (f, size(f), MPI_LOGICAL, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(f) # endif end subroutine ssend_logical_array !> FIXME : Add documentation subroutine ssend_character (s, dest, tag) implicit none character(*), intent (in) :: s integer, intent (in) :: dest integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_ssend & (s, len(s), MPI_CHARACTER, dest, tagp, mp_comm, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(s) # endif end subroutine ssend_character ! Routine for nonblocking send of z to dest. Use !! to label message and return handle for later checking. subroutine nbsend_real_array(z,dest,tag,handle) implicit none real, dimension(:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,size(z),mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_real_array !> Routine for nonblocking send of z (size=count) to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_real_array_count(z,count,dest,tag,handle) implicit none real, dimension(:), intent(in) :: z integer, intent(in) :: count integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,count,mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(count); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_real_array_count !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_array(z,dest,tag,handle) implicit none complex, dimension(:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,size(z),mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_array !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_2d_array(z,dest,tag,handle) implicit none complex, dimension(:,:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI call nbsend_complex_2d_array_count(z,size(z),dest,tag,handle) # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_2d_array !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_2d_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:,:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer, intent(out) :: handle integer, intent(in) :: count # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(count); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_2d_array_count !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_3d_array(z,dest,tag,handle) implicit none complex, dimension(:,:,:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI call nbsend_complex_3d_array_count(z,size(z),dest,tag,handle) # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_3d_array !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_3d_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:,:,:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer, intent(out) :: handle integer, intent(in) :: count # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(count); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_3d_array_count !> Routine for nonblocking send of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_array_sub(z,dest,tag,sub,handle) implicit none complex, dimension(:), intent(in) :: z integer, intent(in) :: dest integer, intent(in) :: tag type(comm_type), intent(in) :: sub integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,size(z),mpicmplx,dest,tag,sub%id,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest) ; UNUSED_DUMMY(tag); UNUSED_DUMMY(z); UNUSED_DUMMY(sub) handle = 0 # endif end subroutine nbsend_complex_array_sub !> Routine for nonblocking send of z (size=count) to dest. Use !! tag to label message and return handle for later checking. subroutine nbsend_complex_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:), intent(in) :: z integer, intent(in) :: count integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_isend(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(count); UNUSED_DUMMY(z) handle = 0 # endif end subroutine nbsend_complex_array_count ! ********************* persistent sends ********************** !> Routine to initialise a persistent send operation subroutine send_init_complex_array(z,dest,tag,handle) implicit none complex, dimension(:), intent(in) :: z integer, intent(in) :: dest, tag integer, intent(inout) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send_init(z,size(z),mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER #else UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(z); UNUSED_DUMMY(handle) #endif end subroutine send_init_complex_array !> Routine to initialise a persistent send operation subroutine send_init_real_array(z,dest,tag,handle) implicit none real, dimension(:), intent(in) :: z integer, intent(in) :: dest, tag integer, intent(inout) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_send_init(z,size(z),mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER #else UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(z); UNUSED_DUMMY(handle) #endif end subroutine send_init_real_array ! ********************* receives ********************** !> FIXME : Add documentation subroutine receive_integer (i, src, tag) implicit none integer, intent (out) :: i integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (i, 1, MPI_INTEGER, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) i = 0 # endif end subroutine receive_integer !> FIXME : Add documentation subroutine receive_integer_array (i, src, tag) implicit none integer, dimension (:), intent (out) :: i integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (i, size(i), MPI_INTEGER, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) i = 0 # endif end subroutine receive_integer_array !> FIXME : Add documentation subroutine receive_real (a, src, tag) implicit none real, intent (out) :: a integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (a, 1, mpireal, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) a = 0 # endif end subroutine receive_real !> FIXME : Add documentation subroutine receive_real_array (a, src, tag) implicit none real, dimension (:), intent (out) :: a integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (a, size(a), mpireal, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) a = 0 # endif end subroutine receive_real_array !> FIXME : Add documentation subroutine receive_real_4d_array (a, src, tag) implicit none real, dimension (:,:,:,:), intent (out) :: a integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag call mpi_recv (a, size(a), mpireal, src, tagp, mp_comm, & status, ierror) # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) a = 0 # endif end subroutine receive_real_4d_array !> FIXME : Add documentation subroutine receive_real_5d_array (a, src, tag) implicit none real, dimension (:,:,:,:,:), intent (out) :: a integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (a, size(a), mpireal, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) a = 0 # endif end subroutine receive_real_5d_array !> FIXME : Add documentation subroutine receive_complex (z, src, tag) implicit none complex, intent (out) :: z integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (z, 1, mpicmplx, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) z = 0 # endif end subroutine receive_complex !> FIXME : Add documentation subroutine receive_complex_array (z, src, tag) implicit none complex, dimension (:), intent (out) :: z integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (z, size(z), mpicmplx, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) z = 0 # endif end subroutine receive_complex_array !> FIXME : Add documentation subroutine receive_complex_2array (z, src, tag) implicit none complex, dimension (:,:), intent (out) :: z integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (z, size(z), mpicmplx, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) z = 0 # endif end subroutine receive_complex_2array !> FIXME : Add documentation subroutine receive_complex_3d_array (z, src, tag) implicit none complex, dimension (:,:,:), intent (out) :: z integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (z, size(z), mpicmplx, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) z = 0 # endif end subroutine receive_complex_3d_array !> FIXME : Add documentation subroutine nonblocking_receive_complex_array (z, src, tag, request) implicit none complex, dimension (:), intent (inout) :: z integer, intent (in) :: src integer, intent (in), optional :: tag integer, intent (out) :: request # ifdef MPI integer :: ierror integer :: tagp tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv (z, size(z), mpicmplx, src, tagp, mp_comm, & request, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(z); UNUSED_DUMMY(src); UNUSED_DUMMY(tag) request = 0 # endif end subroutine nonblocking_receive_complex_array !> FIXME : Add documentation subroutine receive_logical (f, src, tag) implicit none logical, intent (out) :: f integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (f, 1, MPI_LOGICAL, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) f = .false. # endif end subroutine receive_logical !> FIXME : Add documentation subroutine receive_logical_array (f, src, tag) implicit none logical, dimension (:), intent (out) :: f integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (f, size(f), MPI_LOGICAL, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) f = .false. # endif end subroutine receive_logical_array !> FIXME : Add documentation subroutine receive_character (s, src, tag) implicit none character(*), intent (out) :: s integer, intent (in) :: src integer, intent (in), optional :: tag # ifdef MPI integer :: ierror integer :: tagp integer, dimension (mp_status_size) :: status tagp = 0 if (present(tag)) tagp = tag !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv (s, len(s), MPI_CHARACTER, src, tagp, mp_comm, & status, ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort ("receive") UNUSED_DUMMY(src); UNUSED_DUMMY(tag) s = '' # endif end subroutine receive_character ! ********************* non-blocking receives ********************** !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_real_array(z,dest,tag,handle) implicit none real, dimension(:), intent(out) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,size(z),mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 ; z = 0 # endif end subroutine nbrecv_real_array !> Routine for nonblocking recv of z (size=count) to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_real_array_count(z,count,dest,tag,handle) implicit none real, dimension(:), intent(out) :: z integer, intent(in) :: count integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,count,mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(count) handle = 0 ; z = 0 # endif end subroutine nbrecv_real_array_count !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_array(z,dest,tag,handle) implicit none complex, dimension(:), intent(out) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,size(z),mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 ; z = 0 # endif end subroutine nbrecv_complex_array !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_2d_array(z,dest,tag,handle) implicit none complex, dimension(:,:), intent(out) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI call nbrecv_complex_2d_array_count(z,size(z),dest,tag,handle) # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 ; z = 0 # endif end subroutine nbrecv_complex_2d_array !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_2d_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:,:), intent(out) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer, intent(out) :: handle integer, intent(in) :: count # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(count) handle = 0 ; z = 0 # endif end subroutine nbrecv_complex_2d_array_count !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_3d_array(z,dest,tag,handle) implicit none complex, dimension(:,:,:), intent(inout) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI call nbrecv_complex_3d_array_count(z,size(z),dest,tag,handle) # else call mp_abort("receive") UNUSED_DUMMY(z); UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 # endif end subroutine nbrecv_complex_3d_array !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_3d_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:,:,:), intent(inout) :: z integer, intent(in) :: dest integer, intent(in) :: tag integer, intent(out) :: handle integer, intent(in) :: count # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(z); UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(count) handle = 0 # endif end subroutine nbrecv_complex_3d_array_count !> Routine for nonblocking recv of z to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_array_sub(z,dest,tag,sub,handle) implicit none complex, dimension(:), intent(out) :: z integer, intent(in) :: dest integer, intent(in) :: tag type(comm_type), intent(in) :: sub integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,size(z),mpicmplx,dest,tag,sub%id,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(sub) handle = 0 ; z = 0 # endif end subroutine nbrecv_complex_array_sub !> Routine for nonblocking recv of z (size=count) to dest. Use !! tag to label message and return handle for later checking. subroutine nbrecv_complex_array_count(z,count,dest,tag,handle) implicit none complex, dimension(:), intent(out) :: z integer, intent(in) :: count integer, intent(in) :: dest integer, intent(in) :: tag integer,intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_irecv(z,count,mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else call mp_abort("receive") UNUSED_DUMMY(dest); UNUSED_DUMMY(tag); UNUSED_DUMMY(count) handle = 0 ; z = 0 # endif end subroutine nbrecv_complex_array_count ! ********************* persistent recvs ********************** !> Routine to initialise a persistent recv operation subroutine recv_init_complex_array(z,dest,tag,handle) implicit none complex, dimension(:), intent(inout) :: z integer, intent(in) :: dest, tag integer, intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv_init(z,size(z),mpicmplx,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 #endif end subroutine recv_init_complex_array !> Routine to initialise a persistent recv operation subroutine recv_init_real_array(z,dest,tag,handle) implicit none real, dimension(:), intent(inout) :: z integer, intent(in) :: dest, tag integer, intent(out) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_recv_init(z,size(z),mpireal,dest,tag,mp_comm,handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(z); UNUSED_DUMMY(dest); UNUSED_DUMMY(tag) handle = 0 #endif end subroutine recv_init_real_array ! ******************* non-blocking utilities ******************** !> A Routine to initialise request arrays properly so they can have null !! requests in them and still work problems with waitall and waitany subroutine initialise_requests(requests) implicit none integer, dimension(:), intent(inout) :: requests requests = mp_request_null end subroutine initialise_requests ! ********************* non-blocking checks ********************** !> This routine waits for the communication, given by the !! message request, to complete. We ignore the status !! information !! !! @note mpi_wait will set the request handle to MPI_NULL (or similar) !! when message complete so have to set requests as inout subroutine wait_nostat (request) implicit none integer, intent (inout) :: request # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_wait(request,MPI_STATUS_IGNORE,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(request) # endif end subroutine wait_nostat !> This routine waits for the communication, given by the !! message request, to complete. We return the status !! information subroutine wait_stat (request, status) implicit none integer, intent (inout) :: request integer, dimension(mp_status_size), intent(out) :: status # ifdef MPI !Note mpi_wait will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_wait(request,status,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER #else UNUSED_DUMMY(request) status = 0 # endif end subroutine wait_stat !> A routine to wait for all count communications, given by the !! message handles in requests, to complete. We ignore the status !! information subroutine waitall_nostat (count, requests) implicit none integer, intent(in) :: count integer, dimension(:), intent (inout) :: requests !Note mpi_wait will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_waitall(count,requests,MPI_STATUSES_IGNORE,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) # endif end subroutine waitall_nostat !> A routine to wait for all count communications, given by the !! message handles in requests, to complete. We return the message !! statuses subroutine waitall_stat (count, requests, status) implicit none integer, intent(in) :: count integer, dimension(:), intent (inout) :: requests integer, dimension(mp_status_size,count), intent(out) :: status # ifdef MPI !Note mpi_wait will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_waitall(count,requests,status,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) status = 0 # endif end subroutine waitall_stat !> FIXME : Add documentation subroutine waitany_stat (count, requests, requestindex, status) implicit none integer, intent(in) :: count integer, dimension(:), intent(inout) :: requests integer, intent(out) :: requestindex integer, dimension(mp_status_size), intent(out) :: status # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_waitany(count, requests, requestindex, status, ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) status = 0 ; requestindex = 0 # endif end subroutine waitany_stat subroutine waitany_nostat(count, requests, requestindex) implicit none integer, intent(in) :: count integer, dimension(:), intent(inout) :: requests integer, intent(out) :: requestindex # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_waitany(count, requests, requestindex, MPI_STATUS_IGNORE, ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) requestindex = 0 # endif end subroutine waitany_nostat !> A routine to test for all count communications, given by the !! message handles in requests, to complete. We ignore the status !! and flag information subroutine testall_nostat_noflag (count, requests) implicit none integer, intent(in) :: count integer, dimension(:), intent (inout) :: requests !Note mpi_test will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout # ifdef MPI logical :: flag !Should this be integer? integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_testall(count,requests,flag,MPI_STATUSES_IGNORE,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) # endif end subroutine testall_nostat_noflag !> A routine to test for all count communications, given by the !! message handles in requests, to complete. We ignore the status !! information subroutine testall_nostat (count, requests, flag) implicit none integer, intent(in) :: count integer, dimension(:), intent (inout) :: requests logical, intent(out) :: flag !Note mpi_test will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_testall(count,requests,flag,MPI_STATUSES_IGNORE,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) flag = .false. # endif end subroutine testall_nostat !> A routine to test for all count communications, given by the !! message handles in requests, to complete. We return the message !! statuses and completion flag subroutine testall_stat (count, requests, status, flag) implicit none integer, intent(in) :: count integer, dimension(:), intent (inout) :: requests integer, dimension(mp_status_size, count), intent(out) :: status logical, intent(out) :: flag # ifdef MPI !Note mpi_test will set the request handle to MPI_NULL (or similar) !when message complete so have to set requests as inout integer :: ierror !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER call mpi_testall(count,requests,flag,status,ierror) !$OMP MASTER call time_message(.false., time_mp_sync, ' MPI Sync') !$OMP END MASTER # else UNUSED_DUMMY(count); UNUSED_DUMMY(requests) status = 0 flag = .false. # endif end subroutine testall_stat ! ********************* persistent utilities ********************** !> Starts a single persistent communication represented by handle subroutine start_persist(handle) implicit none integer, intent(inout) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_start(handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(handle) # endif end subroutine start_persist !> Starts multiple persistent communications represented by handles subroutine startall_persist(handles) implicit none integer, dimension(:), intent(inout) :: handles # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_startall(size(handles),handles,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(handles) # endif end subroutine startall_persist !> Frees a single persistent request handle subroutine free_handle_persist(handle) implicit none integer, intent(inout) :: handle # ifdef MPI integer :: ierror !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER call mpi_request_free(handle,ierror) !$OMP MASTER call time_message(.false., time_mp_ptp, ' MPI Point-to-point') !$OMP END MASTER # else UNUSED_DUMMY(handle) # endif end subroutine free_handle_persist !> Frees multiple persistent request handles subroutine free_handles_persist(handles) implicit none integer, dimension(:), intent(inout) :: handles integer :: i do i=1,size(handles) call free_handle_persist(handles(i)) enddo end subroutine free_handles_persist ! ********************* other routines ********************** !> FIXME : Add documentation subroutine init_jobs (ncolumns, group0, ierr) implicit none # ifdef MPI ! integer, parameter :: reorder=1 ! TT: I changed variable definition by assuming integer 1 corresponds to ! TT: logical .true. but I'm not sure if reorder is needed. ! TT: In any case this subroutine is only called when you use job fork. logical, parameter :: reorder=.true. integer :: ip, j, comm2d, id2d, nrows # endif integer, intent(in) :: ncolumns integer, dimension(0:), intent (out) :: group0 integer, intent(out) :: ierr # ifndef MPI group0 = 0 ierr = 0 if (ncolumns /= 1) call mp_abort ("jobs") # else integer, parameter :: ndim=2 integer, dimension(ndim) :: dims integer, dimension(0:ndim-1) :: coords1d, coords2d logical, dimension(0:ndim-1) :: belongs logical, dimension(ndim) :: period logical :: isroot if (.not. allocated(grp0)) allocate (grp0(0:size(group0)-1)) ! calculate dimensions mpi processor grid will have and check that ! ncolumns*nrows = number of processes ! nrows is # of processors per job (or group) nrows = ntot_proc/ncolumns dims=(/ ncolumns, nrows /) if(ntot_proc /= ncolumns*nrows) then ierr = 1 if(aproc0) write(*,*) 'Number of processes must be divisible by number of groups' return endif ngroup_proc = nrows ! create 2d cartesian topology for processes period=(/ .false., .false. /) !< no circular shift ! call mpi_cart_create(mpi_comm_world, ndim, dims, period, reorder, comm2d, ierr) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_cart_create(comm_all, ndim, dims, period, reorder, comm2d, ierr) call mpi_comm_rank(comm2d, id2d, ierr) call mpi_cart_coords(comm2d, id2d, ndim, coords2d, ierr) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER ! each processor knows which subgrid it is in from variable mpi_group job = coords2d(0) ! create 1d subgrids from 2d processor grid, variable belongs denotes ! whether processor grid is split by column or row belongs(1) = .true. ! this dimension belongs to subgrid belongs(0) = .false. !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER call mpi_cart_sub(comm2d, belongs, comm_group, ierr) call mpi_comm_rank(comm_group, gproc, ierr) call mpi_cart_coords(comm_group, gproc, 1, coords1d, ierr) !$OMP MASTER call time_message(.false., time_mp_other, ' MPI Overheads') !$OMP END MASTER gproc0 = (gproc == 0) ! find root process of each 1d subgrid and place in array group0 indexed ! from 0 to subgrids-1 ! MAB> following two lines were incorrect ! j=1 ! group0(0) = 0 ! replace with j = 0 if (proc0 .and. gproc0) then group0(0) = 0 j = 1 end if ! brought down here from init_job_name in file_utils.fpp call scope (subprocs) ! FIXME : Add documentation subroutine all_to_group_real (all, group, njobs) implicit none real, dimension (:), intent (in) :: all real, intent (out) :: group integer, intent (in) :: njobs #ifdef MPI integer :: ik, tag, idx tag = 1000 do ik = 0, njobs-1 if (proc0) then idx = mod(ik,size(all)) if (iproc == grp0(ik)) then group = all(idx+1) else call ssend (all(idx+1), grp0(ik), tag) end if else if (iproc == grp0(ik)) then call receive (group, 0, tag) end if end do #else UNUSED_DUMMY(all); UNUSED_DUMMY(njobs) group = 0. call mp_abort("all_to_group") #endif end subroutine all_to_group_real !> FIXME : Add documentation subroutine all_to_group_real_array (all, group, njobs) implicit none real, dimension (:,:), intent (in) :: all real, dimension (:), intent (out) :: group integer, intent (in) :: njobs # ifdef MPI integer :: ik, tag, idx tag = 1001 do ik = 0, njobs-1 if (proc0) then idx = mod(ik,size(all,dim=1)) if (iproc == grp0(ik)) then group = all(idx+1,:) else call ssend (all(idx+1,:), grp0(ik), tag) end if else if (iproc == grp0(ik)) then call receive (group, 0, tag) end if end do # else UNUSED_DUMMY(all); UNUSED_DUMMY(njobs) group = 0. call mp_abort ("all_to_group") # endif end subroutine all_to_group_real_array !> FIXME : Add documentation subroutine group_to_all_real (group, all, njobs) implicit none real, intent (in) :: group real, dimension (:), intent (out) :: all integer, intent (in) :: njobs #ifdef MPI integer :: ik, tag, idx tag = 1002 do ik = 0, njobs-1 if (iproc == grp0(ik)) then if (.not. proc0) then call ssend (group, 0, tag) else idx = mod(ik,size(all)) all(idx+1) = group end if else if (proc0) then idx = mod(ik,size(all)) call receive (all(idx+1), grp0(ik), tag) end if end do # else UNUSED_DUMMY(group); UNUSED_DUMMY(njobs) all = 0 call mp_abort("group_to_all") # endif end subroutine group_to_all_real !> FIXME : Add documentation subroutine group_to_all_real_array (group, all, njobs) implicit none real, dimension (:), intent (in) :: group real, dimension (:,:), intent (out) :: all integer, intent (in) :: njobs # ifdef MPI integer :: ik, tag, idx tag = 1003 do ik = 0, njobs-1 if (iproc == grp0(ik)) then if (.not. proc0) then call ssend (group, 0, tag) else idx = mod(ik,size(all)) all(idx+1,:) = group end if else if (proc0) then idx = mod(ik,size(all)) call receive (all(idx+1,:), grp0(ik), tag) end if end do # else UNUSED_DUMMY(group); UNUSED_DUMMY(njobs) all = 0 call mp_abort("group_to_all") # endif end subroutine group_to_all_real_array !> Abort the simulation, logging an error message subroutine mp_abort (msg, to_screen, err_unit_in) use, intrinsic :: iso_fortran_env, only : error_unit use optionals, only : get_option_with_default implicit none !> Error message character(len=*), intent (in) :: msg !> If true, also print [[msg]] to screen, as well as to the error file logical, intent(in), optional :: to_screen !> Unit of open file to write any error messages to. Defaults to stderr integer, intent (in), optional :: err_unit_in integer :: err_unit_local # ifdef MPI integer :: ierror integer, parameter :: error_code = MPI_ERR_UNKNOWN # endif if (proc0) then err_unit_local = get_option_with_default(err_unit_in, err_unit) if (get_option_with_default(to_screen, .false.)) write(*, *) "Error: ", msg write (err_unit_local, *) "Error: ", msg flush (err_unit_local) end if # ifndef MPI error stop "Called mp_abort without MPI." # else call mpi_abort(comm_all, error_code, ierror) # endif end subroutine mp_abort !> Set the unit for the error file to use in this module, for example for [[mp_abort]] subroutine set_default_error_file_unit(unit) !> An open file unit to use as the error file integer, intent(in) :: unit err_unit = unit end subroutine set_default_error_file_unit end module mp