mirror of https://gitlab.com/QEF/q-e.git
215 lines
9.6 KiB
Fortran
215 lines
9.6 KiB
Fortran
!
|
|
! Copyright (C) 2002 FPMD 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 laxlib_descriptor
|
|
!
|
|
IMPLICIT NONE
|
|
SAVE
|
|
|
|
INTEGER, EXTERNAL :: ldim_block, ldim_cyclic, ldim_block_sca
|
|
INTEGER, EXTERNAL :: gind_block, gind_cyclic, gind_block_sca
|
|
|
|
! Descriptor for linear algebra data distribution (like in Cannon's algorithm)
|
|
!
|
|
! Remember here we use square matrixes block distributed on a square grid of processors
|
|
!
|
|
TYPE la_descriptor
|
|
INTEGER :: ir = 0
|
|
!! global index of the first row in the local block of the distributed matrix
|
|
INTEGER :: nr = 0
|
|
!! number of row in the local block of the distributed matrix
|
|
INTEGER :: ic = 0
|
|
!! global index of the first column in the local block of the distributed matrix
|
|
INTEGER :: nc = 0
|
|
!! number of column in the local block of the distributed matrix
|
|
INTEGER :: nrcx = 0
|
|
!! leading dimension of the distribute matrix (greather than nr and nc)
|
|
INTEGER :: active_node = 0
|
|
!! if > 0 the proc holds a block of the lambda matrix
|
|
INTEGER :: n = 0
|
|
!! global dimension of the matrix
|
|
INTEGER :: nx = 0
|
|
!! global leading dimension ( >= n )
|
|
INTEGER :: npr = 0
|
|
!! number of row processors
|
|
INTEGER :: npc = 0
|
|
!! number of column processors
|
|
INTEGER :: myr = 0
|
|
!! processor row index
|
|
INTEGER :: myc = 0
|
|
!! processor column index
|
|
INTEGER :: comm = 0
|
|
!! communicator
|
|
INTEGER :: cntx =-1
|
|
!! scalapack context
|
|
INTEGER :: mype = 0
|
|
!! processor index ( from 0 to desc( la_npr_ ) * desc( la_npc_ ) - 1 )
|
|
INTEGER :: nrl = 0
|
|
!! number of local rows, when the matrix rows are cyclically distributed across proc
|
|
INTEGER :: nrlx = 0
|
|
!! leading dimension, when the matrix is distributed by row
|
|
END TYPE
|
|
!
|
|
CONTAINS
|
|
!
|
|
!
|
|
SUBROUTINE descla_init( descla, n, nx, np, me, comm, cntx, includeme )
|
|
!
|
|
IMPLICIT NONE
|
|
TYPE(la_descriptor), INTENT(OUT) :: descla
|
|
INTEGER, INTENT(IN) :: n ! the size of this matrix
|
|
INTEGER, INTENT(IN) :: nx ! the max among different matrixes sharing
|
|
! this descriptor or the same data distribution
|
|
INTEGER, INTENT(IN) :: np(2), me(2), comm, cntx
|
|
INTEGER, INTENT(IN) :: includeme
|
|
INTEGER :: ir, nr, ic, nc, lnode, nrcx, nrl, nrlx
|
|
INTEGER :: ip, npp
|
|
|
|
IF( np(1) /= np(2) ) &
|
|
CALL lax_error__( ' descla_init ', ' only square grid of proc are allowed ', 2 )
|
|
IF( n < 0 ) &
|
|
CALL lax_error__( ' descla_init ', ' dummy argument n less than 1 ', 3 )
|
|
IF( nx < n ) &
|
|
CALL lax_error__( ' descla_init ', ' dummy argument nx less than n ', 4 )
|
|
IF( np(1) < 1 ) &
|
|
CALL lax_error__( ' descla_init ', ' dummy argument np less than 1 ', 5 )
|
|
|
|
! find the block maximum dimensions
|
|
|
|
#if __SCALAPACK
|
|
nrcx = ldim_block_sca( nx, np(1), 0 )
|
|
descla%cntx = cntx
|
|
#else
|
|
nrcx = ldim_block( nx, np(1), 0 )
|
|
DO ip = 1, np(1) - 1
|
|
nrcx = MAX( nrcx, ldim_block( nx, np(1), ip ) )
|
|
END DO
|
|
descla%cntx = -1
|
|
#endif
|
|
!
|
|
! find local dimensions, if appropriate
|
|
!
|
|
IF( includeme == 1 ) THEN
|
|
!
|
|
CALL descla_local_dims( ir, nr, n, nx, np(1), me(1) )
|
|
CALL descla_local_dims( ic, nc, n, nx, np(2), me(2) )
|
|
!
|
|
lnode = 1
|
|
!
|
|
ELSE
|
|
!
|
|
nr = 0
|
|
nc = 0
|
|
!
|
|
ir = 0
|
|
ic = 0
|
|
!
|
|
lnode = -1
|
|
!
|
|
END IF
|
|
|
|
descla%ir = ir ! global index of the first row in the local block of lambda
|
|
descla%nr = nr ! number of row in the local block of lambda ( the "2" accounts for spin)
|
|
descla%ic = ic ! global index of the first column in the local block of lambda
|
|
descla%nc = nc ! number of column in the local block of lambda
|
|
descla%nrcx = nrcx ! leading dimension of the distribute lambda matrix
|
|
descla%active_node = lnode
|
|
! if > 0 the proc holds a block of the lambda matrix
|
|
descla%n = n ! global dimension of the matrix
|
|
descla%nx = nx ! global leading dimension
|
|
descla%npr = np(1) ! number of row processors
|
|
descla%npc = np(2) ! number of column processors
|
|
descla%myr = me(1) ! processor row index
|
|
descla%myc = me(2) ! processor column index
|
|
descla%comm = comm ! communicator
|
|
descla%mype = descla%myc + descla%myr * descla%npr
|
|
! processor index ( from 0 to desc( la_npr_ ) * desc( la_npc_ ) - 1 )
|
|
|
|
npp = np(1) * np(2)
|
|
|
|
! Compute local dimension of the cyclically distributed matrix
|
|
!
|
|
IF( includeme == 1 ) THEN
|
|
nrl = ldim_cyclic( n, npp, descla%mype )
|
|
ELSE
|
|
nrl = 0
|
|
END IF
|
|
nrlx = n / npp + 1
|
|
|
|
descla%nrl = nrl ! number of local rows, when the matrix rows are cyclically distributed across procs
|
|
descla%nrlx = nrlx ! leading dimension
|
|
|
|
IF( nr < 0 .OR. nc < 0 ) &
|
|
CALL lax_error__( ' descla_init ', ' wrong valune for computed nr and nc ', 1 )
|
|
IF( nrcx < 1 ) &
|
|
CALL lax_error__( ' descla_init ', ' wrong value for computed nrcx ', 2 )
|
|
IF( nrcx < nr ) &
|
|
CALL lax_error__( ' descla_init ', ' nrcx < nr ', ( nr - nrcx ) )
|
|
IF( nrcx < nc ) &
|
|
CALL lax_error__( ' descla_init ', ' nrcx < nc ', ( nc - nrcx ) )
|
|
IF( nrlx < nrl ) &
|
|
CALL lax_error__( ' descla_init ', ' nrlx < nrl ', ( nrl - nrlx ) )
|
|
IF( nrl < 0 ) &
|
|
CALL lax_error__( ' descla_init ', ' nrl < 0 ', ABS( nrl ) )
|
|
|
|
|
|
RETURN
|
|
END SUBROUTINE descla_init
|
|
|
|
|
|
SUBROUTINE laxlib_desc_to_intarray( idesc, descla )
|
|
IMPLICIT NONE
|
|
include 'laxlib_param.fh'
|
|
TYPE(la_descriptor), INTENT(IN) :: descla
|
|
INTEGER, INTENT(OUT) :: idesc(LAX_DESC_SIZE)
|
|
idesc(LAX_DESC_IR) = descla%ir ! global index of the first row in the local block of the distributed matrix
|
|
idesc(LAX_DESC_NR) = descla%nr ! number of row in the local block of the distributed matrix
|
|
idesc(LAX_DESC_IC) = descla%ic ! global index of the first column in the local block of the distributed matrix
|
|
idesc(LAX_DESC_NC) = descla%nc ! number of column in the local block of the distributed matrix
|
|
idesc(LAX_DESC_NRCX) = descla%nrcx ! leading dimension of the distribute matrix (greather than nr and nc)
|
|
idesc(LAX_DESC_ACTIVE_NODE) = descla%active_node ! if > 0 the proc holds a block of the lambda matrix
|
|
idesc(LAX_DESC_N) = descla%n ! global dimension of the matrix
|
|
idesc(LAX_DESC_NX) = descla%nx ! global leading dimension ( >= n )
|
|
idesc(LAX_DESC_NPR) = descla%npr ! number of row processors
|
|
idesc(LAX_DESC_NPC) = descla%npc ! number of column processors
|
|
idesc(LAX_DESC_MYR) = descla%myr ! processor row index
|
|
idesc(LAX_DESC_MYC) = descla%myc ! processor column index
|
|
idesc(LAX_DESC_COMM) = descla%comm ! communicator
|
|
idesc(LAX_DESC_CNTX) = descla%cntx ! scalapack context
|
|
idesc(LAX_DESC_MYPE) = descla%mype ! processor index ( from 0 to desc( la_npr_ ) * desc( la_npc_ ) - 1 )
|
|
idesc(LAX_DESC_NRL) = descla%nrl ! number of local rows, when the matrix rows are cyclically distributed across proc
|
|
idesc(LAX_DESC_NRLX) = descla%nrlx ! leading dimension, when the matrix is distributed by row
|
|
RETURN
|
|
END SUBROUTINE
|
|
SUBROUTINE laxlib_intarray_to_desc( descla, idesc )
|
|
IMPLICIT NONE
|
|
include 'laxlib_param.fh'
|
|
TYPE(la_descriptor), INTENT(OUT) :: descla
|
|
INTEGER, INTENT(IN) :: idesc(LAX_DESC_SIZE)
|
|
descla%ir = idesc(LAX_DESC_IR) ! global index of the first row in the local block of the distributed matrix
|
|
descla%nr = idesc(LAX_DESC_NR) ! number of row in the local block of the distributed matrix
|
|
descla%ic = idesc(LAX_DESC_IC) ! global index of the first column in the local block of the distributed matrix
|
|
descla%nc = idesc(LAX_DESC_NC) ! number of column in the local block of the distributed matrix
|
|
descla%nrcx = idesc(LAX_DESC_NRCX) ! leading dimension of the distribute matrix (greather than nr and nc)
|
|
descla%active_node = idesc(LAX_DESC_ACTIVE_NODE) ! if > 0 the proc holds a block of the lambda matrix
|
|
descla%n = idesc(LAX_DESC_N) ! global dimension of the matrix
|
|
descla%nx = idesc(LAX_DESC_NX) ! global leading dimension ( >= n )
|
|
descla%npr = idesc(LAX_DESC_NPR) ! number of row processors
|
|
descla%npc = idesc(LAX_DESC_NPC) ! number of column processors
|
|
descla%myr = idesc(LAX_DESC_MYR) ! processor row index
|
|
descla%myc = idesc(LAX_DESC_MYC) ! processor column index
|
|
descla%comm = idesc(LAX_DESC_COMM) ! communicator
|
|
descla%cntx = idesc(LAX_DESC_CNTX) ! scalapack context
|
|
descla%mype = idesc(LAX_DESC_MYPE) ! processor index ( from 0 to desc( la_npr_ ) * desc( la_npc_ ) - 1 )
|
|
descla%nrl = idesc(LAX_DESC_NRL) ! number of local rows, when the matrix rows are cyclically distributed across proc
|
|
descla%nrlx = idesc(LAX_DESC_NRLX) ! leading dimension, when the matrix is distributed by row
|
|
RETURN
|
|
END SUBROUTINE
|
|
|
|
END MODULE laxlib_descriptor
|