2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Copyright (C) 2001 PWSCF group
|
|
|
|
! This file is distributed under the terms of the
|
|
|
|
! GNU General Public License. See the file `License'
|
|
|
|
! in the root directory of the present distribution,
|
|
|
|
! or http://www.gnu.org/copyleft/gpl.txt .
|
|
|
|
!
|
|
|
|
!
|
|
|
|
!-----------------------------------------------------------------------
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine reduce (size, ps)
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! sums a distributed variable s(size) over the processors.
|
|
|
|
! This version uses a fixed-length buffer of appropriate (?) size
|
|
|
|
! uses shmem for the t3d/t3e, MPI otherwhise
|
|
|
|
!
|
|
|
|
#undef SHMEM
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
use para
|
|
|
|
#endif
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: size
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
real (kind=DP) :: ps (size)
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-08 00:04:36 +08:00
|
|
|
include 'mpif.h'
|
|
|
|
integer :: info, n, nbuf
|
2003-01-20 05:58:50 +08:00
|
|
|
#define MAXB 10000
|
2003-02-08 00:04:36 +08:00
|
|
|
real (kind=DP) :: buff (MAXB)
|
2003-01-20 05:58:50 +08:00
|
|
|
#ifdef SHMEM
|
2003-02-08 00:04:36 +08:00
|
|
|
include 'mpp/shmem.fh'
|
|
|
|
integer :: pWrkSync, pWrkData, start
|
|
|
|
common / SH_SYNC / pWrkSync (SHMEM_BARRIER_SYNC_SIZE)
|
|
|
|
common / SH_DATA / pWrkData (1024 * 1024)
|
|
|
|
data pWrkData / 1048576 * 0 /
|
|
|
|
data pWrkSync / SHMEM_BARRIER_SYNC_SIZE * SHMEM_SYNC_VALUE /
|
2003-01-20 05:58:50 +08:00
|
|
|
!DIR$ CACHE_ALIGN /SH_SYNC/
|
|
|
|
!DIR$ CACHE_ALIGN /SH_DATA/
|
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (nprocp.le.1) return
|
|
|
|
if (size.le.0) return
|
|
|
|
call start_clock ('reduce')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! syncronize processes - maybe unneeded on t3d but necessary on t3e !!!
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call mpi_barrier (MPI_COMM_POOL, info)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('reduce', 'error in barrier', info)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
nbuf = size / MAXB
|
2003-01-20 05:58:50 +08:00
|
|
|
#ifdef SHMEM
|
2003-02-08 00:04:36 +08:00
|
|
|
start = (mypool - 1) * nprocp
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
do n = 1, nbuf
|
2003-01-20 05:58:50 +08:00
|
|
|
#ifdef SHMEM
|
|
|
|
call SHMEM_REAL8_SUM_TO_ALL (buff, ps (1 + (n - 1) * MAXB), &
|
|
|
|
MAXB, start, 0, nprocp, pWrkData, pWrkSync)
|
|
|
|
#else
|
|
|
|
call mpi_allreduce (ps (1 + (n - 1) * MAXB), buff, MAXB, &
|
|
|
|
MPI_REAL8, MPI_SUM, MPI_COMM_POOL, info)
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('reduce', 'error in allreduce1', info)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
call DCOPY (MAXB, buff, 1, ps (1 + (n - 1) * MAXB), 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! possible remaining elements < maxb
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (size-nbuf * MAXB.gt.0) then
|
2003-01-20 05:58:50 +08:00
|
|
|
#ifdef SHMEM
|
|
|
|
call SHMEM_REAL8_SUM_TO_ALL (buff, ps (1 + nbuf * MAXB), &
|
|
|
|
size-nbuf * MAXB, start, 0, nprocp, pWrkData, pWrkSync)
|
|
|
|
#else
|
|
|
|
call mpi_allreduce (ps (1 + nbuf * MAXB), buff, size-nbuf * &
|
|
|
|
MAXB, MPI_REAL8, MPI_SUM, MPI_COMM_POOL, info)
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('reduce', 'error in allreduce2', info)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
|
|
|
call DCOPY (size-nbuf * MAXB, buff, 1, ps (1 + nbuf * MAXB), &
|
|
|
|
1)
|
|
|
|
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
call stop_clock ('reduce')
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine reduce
|
|
|
|
!
|
|
|
|
!-----------------------------------------------------------------------
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine ireduce (size, is)
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! sums a distributed variable is(size) over the processors.
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
use para
|
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: size, is (size)
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-08 00:04:36 +08:00
|
|
|
include 'mpif.h'
|
|
|
|
integer :: info, n, m, nbuf
|
2003-01-20 05:58:50 +08:00
|
|
|
#define MAXI 500
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: buff (MAXI)
|
|
|
|
if (nprocp.le.1) return
|
|
|
|
if (size.le.0) return
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! syncronize processes
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call mpi_barrier (MPI_COMM_POOL, info)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('reduce', 'error in barrier', info)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
nbuf = size / MAXI
|
|
|
|
do n = 1, nbuf
|
2003-01-20 05:58:50 +08:00
|
|
|
call mpi_allreduce (is (1 + (n - 1) * MAXI), buff, MAXI, &
|
|
|
|
MPI_INTEGER, MPI_SUM, MPI_COMM_POOL, info)
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('ireduce', 'error in allreduce 1', info)
|
2003-02-08 00:04:36 +08:00
|
|
|
do m = 1, MAXI
|
|
|
|
is (m + (n - 1) * MAXI) = buff (m)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! possible remaining elements < MAXI
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (size-nbuf * MAXI.gt.0) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call mpi_allreduce (is (1 + nbuf * MAXI), buff, size-nbuf * &
|
|
|
|
MAXI, MPI_INTEGER, MPI_SUM, MPI_COMM_POOL, info)
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('reduce', 'error in allreduce 2', info)
|
2003-02-08 00:04:36 +08:00
|
|
|
do m = 1, size-nbuf * MAXI
|
|
|
|
is (m + nbuf * MAXI) = buff (m)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
|
|
|
|
endif
|
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine ireduce
|
|
|
|
|