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-27 21:59:04 +08:00
|
|
|
#ifdef __T3E
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-23 19:34:24 +08:00
|
|
|
#ifdef __AIX
|
2003-01-20 05:58:50 +08:00
|
|
|
#define CGERV2D zgerv2d
|
|
|
|
#define CGESD2D zgesd2d
|
|
|
|
#define CGEBR2D zgebr2d
|
|
|
|
#define CGEBS2D zgebs2d
|
|
|
|
#endif
|
|
|
|
|
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine gridsetup_local (nproc, nprow, npcol)
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! This subroutine factorizes the number of processors (NPROC)
|
|
|
|
! into NPROW and NPCOL, that are the sizes of the 2D processors mesh.
|
|
|
|
!
|
|
|
|
! Written by Carlo Cavazzoni
|
|
|
|
!
|
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 :: nproc, nprow, npcol
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: number of processors
|
|
|
|
! output: number of rows
|
|
|
|
! output: number of column
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: sqrtnp, i
|
2003-01-20 05:58:50 +08:00
|
|
|
! the maximum size to check
|
|
|
|
! counter
|
2003-02-08 00:04:36 +08:00
|
|
|
sqrtnp = int (sqrt (dble (nproc) ) + 1)
|
|
|
|
do i = 1, sqrtnp
|
|
|
|
if (mod (nproc, i) .eq.0) nprow = i
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
npcol = nproc / nprow
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
end subroutine gridsetup_local
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine blockset_priv (nb, nbuser, n, nprow, npcol)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! This subroutine try to choose an optimal block size
|
|
|
|
! for the distributed matrix.
|
|
|
|
!
|
|
|
|
! Written by Carlo Cavazzoni
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: nb, n, nprow, npcol, nbuser
|
|
|
|
nb = min (n / nprow, n / npcol)
|
|
|
|
if (nbuser.gt.0) then
|
|
|
|
nb = min (nb, nbuser)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
nb = min (nb, n)
|
|
|
|
if (n.lt.10) nb = 1
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine blockset_priv
|
|
|
|
!
|
|
|
|
!----------------------------------------------------------------------
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine eigen (n, aout, ldaout, a, desca, work)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
2003-01-20 05:58:50 +08:00
|
|
|
! This routine accumulates the eigenvectors on the root
|
|
|
|
! processor and then broadcast them to the other processors
|
|
|
|
!
|
|
|
|
! .. Scalar Arguments ..
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ia, icprnt, irprnt, ja, m, n, nout, ldaout
|
2003-01-20 05:58:50 +08:00
|
|
|
! ..
|
|
|
|
! .. Array Arguments ..
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: desca ( * )
|
|
|
|
complex (kind=8) :: aout (ldaout, * ), a ( * ), work ( * )
|
2003-01-20 05:58:50 +08:00
|
|
|
! ..
|
|
|
|
! .. Parameters ..
|
|
|
|
integer :: block_cyclic_2d, csrc_, ctxt_, dlen_, dtype_, lld_, &
|
|
|
|
mb_, m_, nb_, n_, rsrc_
|
|
|
|
parameter (block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1, ctxt_ = 2, &
|
|
|
|
m_ = 3, n_ = 4, mb_ = 5, nb_ = 6, rsrc_ = 7, csrc_ = 8, lld_ = 9)
|
|
|
|
! ..
|
|
|
|
! .. Local Scalars ..
|
|
|
|
integer :: h, i, iacol, iarow, ib, ictxt, icurcol, icurrow, ii, &
|
|
|
|
iia, in, j, jb, jj, jja, jn, k, lda, mycol, myrow, npcol, nprow
|
|
|
|
! ..
|
|
|
|
! .. External Subroutines ..
|
2003-02-08 00:04:36 +08:00
|
|
|
external blacs_barrier, blacs_gridinfo, infog2l, CGERV2D, CGESD2D
|
2003-01-20 05:58:50 +08:00
|
|
|
! ..
|
|
|
|
! .. External Functions ..
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: iceil
|
|
|
|
external iceil
|
2003-01-20 05:58:50 +08:00
|
|
|
! ..
|
|
|
|
! .. Intrinsic Functions ..
|
2003-02-08 00:04:36 +08:00
|
|
|
intrinsic min
|
2003-01-20 05:58:50 +08:00
|
|
|
! ..
|
|
|
|
! .. Executable Statements ..
|
|
|
|
!
|
|
|
|
! Get grid parameters
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
icprnt = 0
|
|
|
|
irprnt = 0
|
|
|
|
ia = 1
|
|
|
|
ja = 1
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
m = n
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-04-23 00:03:45 +08:00
|
|
|
aout(:,1:n) = (0.d0,0.d0)
|
2003-02-08 00:04:36 +08:00
|
|
|
ictxt = desca (ctxt_)
|
|
|
|
call blacs_gridinfo (ictxt, nprow, npcol, myrow, mycol)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
call infog2l (ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja, &
|
|
|
|
iarow, iacol)
|
2003-02-08 00:04:36 +08:00
|
|
|
icurrow = iarow
|
|
|
|
icurcol = iacol
|
|
|
|
ii = iia
|
|
|
|
jj = jja
|
|
|
|
lda = desca (lld_)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Handle the first block of column separately
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
jn = min (iceil (ja, desca (nb_) ) * desca (nb_), ja + n - 1)
|
|
|
|
jb = jn - ja + 1
|
|
|
|
do h = 0, jb - 1
|
|
|
|
in = min (iceil (ia, desca (mb_) ) * desca (mb_), ia + m - 1)
|
|
|
|
ib = in - ia + 1
|
|
|
|
if (icurrow.eq.irprnt.and.icurcol.eq.icprnt) then
|
|
|
|
if (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
|
|
|
do k = 0, ib - 1
|
|
|
|
aout (ia + k, ja + h) = a (ii + k + (jj + h - 1) * lda)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
if (myrow.eq.icurrow.and.mycol.eq.icurcol) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGESD2D (ictxt, ib, 1, a (ii + (jj + h - 1) * lda), &
|
|
|
|
lda, irprnt, icprnt)
|
2003-02-08 00:04:36 +08:00
|
|
|
elseif (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGERV2D (ictxt, ib, 1, work, desca (mb_), icurrow, &
|
|
|
|
icurcol)
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, ib
|
|
|
|
aout (ia + k - 1, ja + h) = work (k)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (myrow.eq.icurrow) ii = ii + ib
|
|
|
|
icurrow = mod (icurrow + 1, nprow)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Loop over remaining block of rows
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do i = in + 1, ia + m - 1, desca (mb_)
|
|
|
|
ib = min (desca (mb_), ia + m - i)
|
|
|
|
if (icurrow.eq.irprnt.and.icurcol.eq.icprnt) then
|
|
|
|
if (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
|
|
|
do k = 0, ib - 1
|
|
|
|
aout (i + k, ja + h) = a (ii + k + (jj + h - 1) * lda)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
if (myrow.eq.icurrow.and.mycol.eq.icurcol) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGESD2D (ictxt, ib, 1, a (ii + (jj + h - 1) * lda), &
|
|
|
|
lda, irprnt, icprnt)
|
2003-02-08 00:04:36 +08:00
|
|
|
elseif (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGERV2D (ictxt, ib, 1, work, desca (mb_), icurrow, &
|
|
|
|
icurcol)
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, ib
|
|
|
|
aout (i + k - 1, ja + h) = work (k)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (myrow.eq.icurrow) ii = ii + ib
|
|
|
|
icurrow = mod (icurrow + 1, nprow)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
ii = iia
|
|
|
|
icurrow = iarow
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
enddo
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (mycol.eq.icurcol) jj = jj + jb
|
|
|
|
icurcol = mod (icurcol + 1, npcol)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Loop over remaining column blocks
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do j = jn + 1, ja + n - 1, desca (nb_)
|
|
|
|
jb = min (desca (nb_), ja + n - j)
|
|
|
|
do h = 0, jb - 1
|
|
|
|
in = min (iceil (ia, desca (mb_) ) * desca (mb_), ia + m - 1)
|
|
|
|
ib = in - ia + 1
|
|
|
|
if (icurrow.eq.irprnt.and.icurcol.eq.icprnt) then
|
|
|
|
if (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
|
|
|
do k = 0, ib - 1
|
|
|
|
aout (ia + k, j + h) = a (ii + k + (jj + h - 1) * lda)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
if (myrow.eq.icurrow.and.mycol.eq.icurcol) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGESD2D (ictxt, ib, 1, a (ii + (jj + h - 1) * lda), &
|
|
|
|
lda, irprnt, icprnt)
|
2003-02-08 00:04:36 +08:00
|
|
|
elseif (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGERV2D (ictxt, ib, 1, work, desca (mb_), icurrow, &
|
|
|
|
icurcol)
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, ib
|
|
|
|
aout (ia + k - 1, j + h) = work (k)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (myrow.eq.icurrow) ii = ii + ib
|
|
|
|
icurrow = mod (icurrow + 1, nprow)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Loop over remaining block of rows
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do i = in + 1, ia + m - 1, desca (mb_)
|
|
|
|
ib = min (desca (mb_), ia + m - i)
|
|
|
|
if (icurrow.eq.irprnt.and.icurcol.eq.icprnt) then
|
|
|
|
if (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
|
|
|
do k = 0, ib - 1
|
|
|
|
aout (i + k, j + h) = a (ii + k + (jj + h - 1) * lda)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
if (myrow.eq.icurrow.and.mycol.eq.icurcol) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGESD2D (ictxt, ib, 1, a (ii + (jj + h - 1) * lda), &
|
|
|
|
lda, irprnt, icprnt)
|
2003-02-08 00:04:36 +08:00
|
|
|
elseif (myrow.eq.irprnt.and.mycol.eq.icprnt) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call CGERV2D (ictxt, ib, 1, work, desca (mb_), icurrow, &
|
|
|
|
icurcol)
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, ib
|
|
|
|
aout (i + k - 1, j + h) = work (k)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (myrow.eq.icurrow) ii = ii + ib
|
|
|
|
icurrow = mod (icurrow + 1, nprow)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
ii = iia
|
|
|
|
icurrow = iarow
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (mycol.eq.icurcol) jj = jj + jb
|
|
|
|
icurcol = mod (icurcol + 1, npcol)
|
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
enddo
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if ( (myrow.eq.0) .and. (mycol.eq.0) ) then
|
|
|
|
call CGEBS2D (ictxt, 'All', 'h', n, n, aout, ldaout)
|
|
|
|
else
|
|
|
|
call CGEBR2D (ictxt, 'All', 'h', n, n, aout, ldaout, 0, 0)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call blacs_barrier (ictxt, 'All')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
end subroutine eigen
|
|
|
|
#else
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine scaladummy
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine scaladummy
|
|
|
|
#endif
|