quantum-espresso/Modules/mp_images.f90

123 lines
3.8 KiB
Fortran

!
! Copyright (C) 2013 Quantum ESPRESSO 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 .
!
!----------------------------------------------------------------------------
MODULE mp_images
!----------------------------------------------------------------------------
!! Image groups (processors within an image). Images are used for
!! coarse-grid parallelization of semi-independent calculations,
!! e.g. points along the reaction path (NEB) or phonon irreps.
!
USE mp, ONLY : mp_barrier, mp_bcast, mp_size, mp_rank, mp_comm_split
USE io_global, ONLY : ionode, ionode_id
USE parallel_include
!
IMPLICIT NONE
SAVE
!
INTEGER :: nimage = 1
!! number of images
INTEGER :: nproc_image=1
!! number of processors within an image
INTEGER :: me_image = 0
!! index of the processor within an image
INTEGER :: root_image= 0
!! index of the root processor within an image
INTEGER :: my_image_id=0
!! index of my image
INTEGER :: inter_image_comm = 0
!! inter image communicator
INTEGER :: intra_image_comm = 0
!! intra image communicator
!
CONTAINS
!
!-----------------------------------------------------------------------
SUBROUTINE mp_start_images ( nimage_, parent_comm )
!-----------------------------------------------------------------------
!! Divide processors (of the "parent_comm" group) into "images".
!! Requires: \(\text{nimage_}\), read from command line and
!! \(\text{parent_comm}\), typically world_comm = group of all processors
!
IMPLICIT NONE
INTEGER, INTENT(IN) :: nimage_, parent_comm
!
#if defined (__MPI)
INTEGER :: parent_nproc, parent_mype
!
! ... nothing needed to be done in serial calculation
!
parent_nproc = mp_size( parent_comm )
parent_mype = mp_rank( parent_comm )
!
! ... nimage_ must have been previously read from command line argument
! ... by a call to routine get_command_line
!
nimage = nimage_
!
IF ( nimage < 1 .OR. nimage > parent_nproc ) &
CALL errore( 'mp_start_images', 'invalid number of images, out of range', 1 )
IF ( MOD( parent_nproc, nimage ) /= 0 ) &
CALL errore( 'mp_start_images', 'n. of images must be divisor of nproc', 1 )
!
! ... set number of cpus per image
!
nproc_image = parent_nproc / nimage
!
! ... set index of image for this processor ( 0 : nimage - 1 )
!
my_image_id = parent_mype / nproc_image
!
! ... set index of processor within the image ( 0 : nproc_image - 1 )
!
me_image = MOD( parent_mype, nproc_image )
!
CALL mp_barrier( parent_comm )
!
! ... the intra_image_comm communicator is created
!
CALL mp_comm_split ( parent_comm, my_image_id, parent_mype, &
intra_image_comm )
!
CALL mp_barrier( parent_comm )
!
! ... the inter_image_comm communicator is created
!
CALL mp_comm_split ( parent_comm, me_image, parent_mype, &
inter_image_comm )
!
! ... set processor that performs I/O
!
ionode = ( me_image == root_image )
ionode_id = root_image
!
#endif
RETURN
!
END SUBROUTINE mp_start_images
!
SUBROUTINE mp_init_image ( parent_comm )
!
!! There is just one image: set it to the same as parent_comm (world)
!
IMPLICIT NONE
INTEGER, INTENT(IN) :: parent_comm
!
intra_image_comm = parent_comm
nproc_image = mp_size( parent_comm )
me_image = mp_rank( parent_comm )
!
! ... no need to set inter_image_comm, my_image_id, root_image
! ... set processor that performs I/O
!
ionode = ( me_image == root_image )
ionode_id = root_image
!
END SUBROUTINE mp_init_image
!
END MODULE mp_images