Routine: PSLAEVSWP()  File: SRC\pslaevswp.f

 
 
# lines: 284
  # code: 284
  # comment: 0
  # blank:0
# Variables:47
# Callers:1
# Callings:0
# Words:88
# Keywords:54
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PSLAEVSWP moves the eigenvectors (potentially unsorted) from
  where they are computed, to a ScaLAPACK standard block cyclic
  array, sorted so that the corresponding eigenvalues are sorted.
  Notes
  =====
  Each global data object is described by an associated description
  vector.  This vector stores the information required to establish
  the mapping between an object element and its corresponding process
  and memory location.
  Let A be a generic term for any 2D block cyclicly distributed array.
  Such a global array has an associated description vector DESCA.
  In the following comments, the character _ should be read as
  "of the global array".
  NOTATION        STORED IN      EXPLANATION
  --------------- -------------- --------------------------------------
  DTYPE_A(global) DESCA( DTYPE_ )The descriptor type.  In this case,
                                 DTYPE_A = 1.
  CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
                                 the BLACS process grid A is distribu-
                                 ted over. The context itself is glo-
                                 bal, but the handle (the integer
                                 value) may vary.
  M_A    (global) DESCA( M_ )    The number of rows in the global
                                 array A.
  N_A    (global) DESCA( N_ )    The number of columns in the global
                                 array A.
  MB_A   (global) DESCA( MB_ )   The blocking factor used to distribute
                                 the rows of the array.
  NB_A   (global) DESCA( NB_ )   The blocking factor used to distribute
                                 the columns of the array.
  RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
                                 row of the array A is distributed.
  CSRC_A (global) DESCA( CSRC_ ) The process column over which the
                                 first column of the array A is
                                 distributed.
  LLD_A  (local)  DESCA( LLD_ )  The leading dimension of the local
                                 array.  LLD_A >= MAX(1,LOCr(M_A)).
  Let K be the number of rows or columns of a distributed matrix,
  and assume that its process grid has dimension p x q.
  LOCr( K ) denotes the number of elements of K that a process
  would receive if K were distributed over the p processes of its
  process column.
  Similarly, LOCc( K ) denotes the number of elements of K that a
  process would receive if K were distributed over the q processes of
  its process row.
  The values of LOCr() and LOCc() may be determined via a call to the
  ScaLAPACK tool function, NUMROC:
          LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
          LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
  An upper bound for these quantities may be computed by:
          LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
          LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
  Arguments
  =========
     NP = the number of rows local to a given process.
     NQ = the number of columns local to a given process.
  N       (global input) INTEGER
          The order of the matrix A.  N >= 0.
  ZIN     (local input) REAL array,
          dimension ( LDZI, NVS(iam) )
          The eigenvectors on input.  Each eigenvector resides entirely
          in one process.  Each process holds a contiguous set of
          NVS(iam) eigenvectors.  The first eigenvector which the
          process holds is:  sum for i=[0,iam-1) of NVS(i)
  LDZI    (locl input) INTEGER
          leading dimension of the ZIN array
  Z       (local output) REAL array
          global dimension (N, N), local dimension (DESCZ(DLEN_), NQ)
          The eigenvectors on output.  The eigenvectors are distributed
          in a block cyclic manner in both dimensions, with a
          block size of NB.
  IZ      (global input) INTEGER
          Z's global row index, which points to the beginning of the
          submatrix which is to be operated on.
  JZ      (global input) INTEGER
          Z's global column index, which points to the beginning of
          the submatrix which is to be operated on.
  DESCZ   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix Z.
  NVS     (global input) INTEGER array, dimension( nprocs+1 )
          nvs(i) = number of processes
          number of eigenvectors held by processes [0,i-1)
          nvs(1) = number of eigen vectors held by [0,1-1) == 0
          nvs(nprocs+1) = number of eigen vectors held by [0,nprocs) ==
            total number of eigenvectors
  KEY     (global input) INTEGER array, dimension( N )
          Indicates the actual index (after sorting) for each of the
          eigenvectors.
  WORK    (local workspace) REAL array, dimension (LWORK)
  LWORK   (local input) INTEGER dimension of WORK
     .. Parameters ..

 
Display dynamic version Find AutoScroll Reload FontSize: - + Hide Comments Hide Blanks Frame FullScreen MailPrint

 
001        SUBROUTINE PSLAEVSWP( N , ZIN , LDZI , Z , IZ , JZ , DESCZ , NVS , KEY ,
002       $WORK , LWORK )
003  
004  *     -- ScaLAPACK routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     April 15 , 1997
008  
009  *     .. Scalar Arguments ..
010        INTEGER IZ , JZ , LDZI , LWORK , N
011        INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
012       $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
013        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
014       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
015       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
016  *     ..
017  *     .. Local Scalars ..
018        INTEGER CYCLIC_I , CYCLIC_J , DIST , I , IAM , II , INCII , J ,
019       $MAXI , MAXII , MINI , MINII , MYCOL , MYROW , NB ,
020       $NBUFSIZE , NPCOL , NPROCS , NPROW , PCOL , RECVCOL ,
021       $RECVFROM , RECVROW , SENDCOL , SENDROW , SENDTO
022  *     ..
023  *     .. External Functions ..
024        INTEGER INDXG2L , INDXG2P
025        EXTERNAL INDXG2L , INDXG2P
026  *     ..
027  *     .. External Subroutines ..
028        EXTERNAL BLACS_GRIDINFO , SGERV2D , SGESD2D
029  *     ..
030  *     .. Intrinsic Functions ..
031        INTRINSIC MAX , MIN , MOD
032  *     ..
033  *     .. Executable Statements ..
034  *     This is just to keep ftnchek happy
035        IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
036       $    RSRC_.LT.0 )RETURN
037            CALL BLACS_GRIDINFO( DESCZ( CTXT_ ) , NPROW , NPCOL , MYROW , MYCOL )
038            IAM = MYROW + MYCOL*NPROW
039            IAM = MYROW*NPCOL + MYCOL
040  
041            NB = DESCZ( MB_ )
042  
043            NPROCS = NPROW*NPCOL
044  
045  *         If PxSTEIN operates on a sub - matrix of a global matrix , the
046  *         key[] that contains the indicies of the eigenvectors is refe -
047  *         renced to the dimensions of the sub - matrix and not the global
048  *         distrubited matrix. Because of this , PxLAEVSWP will incorrectly
049  *         map the eigenvectors to the global eigenvector matrix , Z , unless
050  *         the key[] elements are shifted as below.
051  
052            DO 10 J = DESCZ( N_ ) , 1 , - 1
053                KEY( J ) = KEY( J - JZ + 1 ) + ( JZ - 1 )
054     10     CONTINUE
055  
056            DO 110 DIST = 0 , NPROCS - 1
057  
058                SENDTO = MOD( IAM + DIST , NPROCS )
059                RECVFROM = MOD( NPROCS + IAM - DIST , NPROCS )
060  
061                SENDROW = MOD( SENDTO , NPROW )
062                SENDCOL = SENDTO / NPROW
063                RECVROW = MOD( RECVFROM , NPROW )
064                RECVCOL = RECVFROM / NPROW
065  
066                SENDROW = SENDTO / NPCOL
067                SENDCOL = MOD( SENDTO , NPCOL )
068                RECVROW = RECVFROM / NPCOL
069                RECVCOL = MOD( RECVFROM , NPCOL )
070  
071  *             Figure out what I have that process "sendto" wants
072  
073                NBUFSIZE = 0
074  
075  *             We are looping through the eigenvectors that I presently own.
076  
077                DO 40 J = NVS( 1 + IAM ) + JZ , NVS( 1 + IAM + 1 ) + JZ - 1
078                    PCOL = INDXG2P( KEY( J ) , DESCZ( NB_ ) , - 1 , DESCZ( CSRC_ ) ,
079       $            NPCOL )
080                    IF( SENDCOL.EQ.PCOL ) THEN
081                        MINII = MOD( SENDROW + DESCZ( RSRC_ ) , NPROW )*
082       $                DESCZ( MB_ ) + 1
083                        MAXII = DESCZ( M_ )
084                        INCII = DESCZ( MB_ )*NPROW
085                        DO 30 II = MINII , MAXII , INCII
086                            MINI = MAX( II , IZ )
087                            MAXI = MIN( II + DESCZ( MB_ ) - 1 , N + IZ - 1 )
088                            DO 20 I = MINI , MAXI , 1
089                                NBUFSIZE = NBUFSIZE + 1
090                                WORK( NBUFSIZE ) = ZIN( I + 1 - IZ ,
091       $                        J - NVS( 1 + IAM ) + 1 - JZ )
092     20                     CONTINUE
093     30                 CONTINUE
094                    END IF
095     40         CONTINUE
096  
097                IF( MYROW.NE.SENDROW .OR. MYCOL.NE.SENDCOL )
098       $            CALL SGESD2D( DESCZ( CTXT_ ) , NBUFSIZE , 1 , WORK , NBUFSIZE ,
099       $            SENDROW , SENDCOL )
100  
101  *                 Figure out what process "recvfrom" has that I want
102  
103                    NBUFSIZE = 0
104                    DO 70 J = NVS( 1 + RECVFROM ) + JZ ,
105       $                NVS( 1 + RECVFROM + 1 ) + JZ - 1 , 1
106                        PCOL = INDXG2P( KEY( J ) , DESCZ( NB_ ) , - 1 , DESCZ( CSRC_ ) ,
107       $                NPCOL )
108                        IF( MYCOL.EQ.PCOL ) THEN
109                            MINII = MOD( MYROW + DESCZ( RSRC_ ) , NPROW )*DESCZ( MB_ ) +
110       $                    1
111                            MAXII = DESCZ( M_ )
112                            INCII = DESCZ( MB_ )*NPROW
113                            DO 60 II = MINII , MAXII , INCII
114                                MINI = MAX( II , IZ )
115                                MAXI = MIN( II + NB - 1 , N + IZ - 1 )
116                                DO 50 I = MINI , MAXI , 1
117                                    NBUFSIZE = NBUFSIZE + 1
118     50                         CONTINUE
119     60                     CONTINUE
120                        END IF
121     70             CONTINUE
122  
123                    IF( MYROW.NE.RECVROW .OR. MYCOL.NE.RECVCOL )
124       $                CALL SGERV2D( DESCZ( CTXT_ ) , 1 , NBUFSIZE , WORK , 1 , RECVROW ,
125       $                RECVCOL )
126  
127                        NBUFSIZE = 0
128                        DO 100 J = NVS( 1 + RECVFROM ) + JZ ,
129       $                    NVS( 1 + RECVFROM + 1 ) + JZ - 1 , 1
130                            PCOL = INDXG2P( KEY( J ) , DESCZ( NB_ ) , - 1 , DESCZ( CSRC_ ) ,
131       $                    NPCOL )
132                            IF( MYCOL.EQ.PCOL ) THEN
133                                CYCLIC_J = INDXG2L( KEY( J ) , DESCZ( MB_ ) , - 1 , - 1 ,
134       $                        NPCOL )
135                                CYCLIC_I = 1
136                                MINII = MOD( MYROW + DESCZ( RSRC_ ) , NPROW )*DESCZ( MB_ ) +
137       $                        1
138                                MAXII = DESCZ( M_ )
139                                INCII = DESCZ( MB_ )*NPROW
140                                DO 90 II = MINII , MAXII , INCII
141                                    MINI = MAX( II , IZ )
142                                    CYCLIC_I = INDXG2L( MINI , DESCZ( MB_ ) , - 1 , - 1 ,
143       $                            NPROW )
144                                    MAXI = MIN( II + NB - 1 , N + IZ - 1 )
145                                    DO 80 I = MINI , MAXI , 1
146                                        NBUFSIZE = NBUFSIZE + 1
147                                        Z( CYCLIC_I + ( CYCLIC_J - 1 )*DESCZ( LLD_ ) )
148       $                                = WORK( NBUFSIZE )
149                                        CYCLIC_I = CYCLIC_I + 1
150     80                             CONTINUE
151     90                         CONTINUE
152                            END IF
153    100                 CONTINUE
154  
155    110     CONTINUE
156            RETURN
157  
158  *         End of PSLAEVSWP
159  
160        END