|
|
| |
| # lines: |
267 | | # code: |
267 | | # comment: | 0 | |
# blank: | 0 |
| # Variables: | 46 |
| # Callers: | 2 |
| # Callings: | 2 |
| # Words: | 169 |
| # Keywords: | 113 |
|
|
|
|
|
..
.. Array Arguments ..
..
Purpose
=======
PSSTEDC computes all eigenvalues and eigenvectors of a
symmetric tridiagonal matrix in parallel, using the divide and
conquer algorithm.
This code makes very mild assumptions about floating point
arithmetic. It will work on machines with a guard digit in
add/subtract, or on those binary machines without guard digits
which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.
It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none. See SLAED3 for details.
Arguments
=========
COMPZ (input) CHARACTER*1
= 'N': Compute eigenvalues only. (NOT IMPLEMENTED YET)
= 'I': Compute eigenvectors of tridiagonal matrix also.
= 'V': Compute eigenvectors of original dense symmetric
matrix also. On entry, Z contains the orthogonal
matrix used to reduce the original matrix to
tridiagonal form. (NOT IMPLEMENTED YET)
N (global input) INTEGER
The order of the tridiagonal matrix T. N >= 0.
D (global input/output) REAL array, dimension (N)
On entry, the diagonal elements of the tridiagonal matrix.
On exit, if INFO = 0, the eigenvalues in descending order.
E (global input/output) REAL array, dimension (N-1)
On entry, the subdiagonal elements of the tridiagonal matrix.
On exit, E has been destroyed.
Q (local output) REAL array,
local dimension ( LLD_Q, LOCc(JQ+N-1))
Q contains the orthonormal eigenvectors of the symmetric
tridiagonal matrix.
On output, Q is distributed across the P processes in block
cyclic format.
IQ (global input) INTEGER
Q's global row index, which points to the beginning of the
submatrix which is to be operated on.
JQ (global input) INTEGER
Q's global column index, which points to the beginning of
the submatrix which is to be operated on.
DESCQ (global and local input) INTEGER array of dimension DLEN_.
The array descriptor for the distributed matrix Z.
WORK (local workspace/output) REAL array,
dimension (LWORK)
On output, WORK(1) returns the workspace needed.
LWORK (local input/output) INTEGER,
the dimension of the array WORK.
LWORK = 6*N + 2*NP*NQ
NP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW )
NQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL )
If LWORK = -1, the LWORK is global input and a workspace
query is assumed; the routine only calculates the minimum
size for the WORK array. The required workspace is returned
as the first element of WORK and no error message is issued
by PXERBLA.
IWORK (local workspace/output) INTEGER array, dimension (LIWORK)
On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.
LIWORK (input) INTEGER
The dimension of the array IWORK.
LIWORK = 2 + 7*N + 8*NPCOL
INFO (global output) INTEGER
= 0: successful exit
< 0: If the i-th argument is an array and the j-entry had
an illegal value, then INFO = -(i*100+j), if the i-th
argument is a scalar and had an illegal value, then
INFO = -i.
> 0: The algorithm failed to compute the INFO/(N+1) th
eigenvalue while working on the submatrix lying in
global rows and columns mod(INFO,N+1).
Further Details
======= =======
Contributed by Francoise Tisseur, University of Manchester.
Reference: F. Tisseur and J. Dongarra, "A Parallel Divide and
Conquer Algorithm for the Symmetric Eigenvalue Problem
on Distributed Memory Architectures",
SIAM J. Sci. Comput., 6:20 (1999), pp. 2223--2236.
(see also LAPACK Working Note 132)
http://www.netlib.org/lapack/lawns/lawn132.ps
=====================================================================
.. Parameters ..
|
|
|
|
001 SUBROUTINE PSSTEDC( COMPZ , N , D , E , Q , IQ , JQ , DESCQ , WORK , LWORK ,
002 $IWORK , LIWORK , INFO )
003
004 * -- ScaLAPACK routine(version 1.7) --
005 * University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006 * and University of California , Berkeley.
007 * March 13 , 2000
008
009 * .. Scalar Arguments ..
010 CHARACTER COMPZ
011 INTEGER INFO , IQ , JQ , LIWORK , LWORK , N
012 INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
013 $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
014 PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
015 $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
016 $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
017 REAL ZERO , ONE
018 PARAMETER( ZERO = 0.0E + 0 , ONE = 1.0E + 0 )
019 * ..
020 * .. Local Scalars ..
021 LOGICAL LQUERY
022 INTEGER ICOFFQ , IIQ , IPQ , IQCOL , IQROW , IROFFQ , JJQ ,
023 $LDQ , LIWMIN , LWMIN , MYCOL , MYROW , NB , NP ,
024 $NPCOL , NPROW , NQ
025 REAL ORGNRM
026 * ..
027 * .. External Functions ..
028 LOGICAL LSAME
029 INTEGER INDXG2P , NUMROC
030 REAL SLANST
031 EXTERNAL INDXG2P , LSAME , NUMROC , SLANST
032 * ..
033 * .. External Subroutines ..
034 EXTERNAL BLACS_GRIDINFO , CHK1MAT , INFOG2L , PSLAED0 ,
035 $PSLASRT , PXERBLA , SLASCL , SSTEDC
036 * ..
037 * .. Intrinsic Functions ..
038 INTRINSIC MOD , REAL
039 * ..
040 * .. Executable Statements ..
041
042 * This is just to keep ftnchek and toolpack / 1 happy
043 IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
043
044 $ RSRC_.LT.0 )RETURN
045
046 * Test the input parameters.
047
048 CALL BLACS_GRIDINFO( DESCQ( CTXT_ ) , NPROW , NPCOL , MYROW , MYCOL )
049 LDQ = DESCQ( LLD_ )
050 NB = DESCQ( NB_ )
051 NP = NUMROC( N , NB , MYROW , DESCQ( RSRC_ ) , NPROW )
052 NQ = NUMROC( N , NB , MYCOL , DESCQ( CSRC_ ) , NPCOL )
053 INFO = 0
054 IF( NPROW.EQ. - 1 ) THEN
054
055 INFO = - ( 600 + CTXT_ )
056 ELSE
056
057 CALL CHK1MAT( N , 2 , N , 2 , IQ , JQ , DESCQ , 8 , INFO )
058 IF( INFO.EQ.0 ) THEN
058
059 NB = DESCQ( NB_ )
060 IROFFQ = MOD( IQ - 1 , DESCQ( MB_ ) )
061 ICOFFQ = MOD( JQ - 1 , DESCQ( NB_ ) )
062 IQROW = INDXG2P( IQ , NB , MYROW , DESCQ( RSRC_ ) , NPROW )
063 IQCOL = INDXG2P( JQ , NB , MYCOL , DESCQ( CSRC_ ) , NPCOL )
064 LWMIN = 6*N + 2*NP*NQ
065 LIWMIN = 2 + 7*N + 8*NPCOL
066 WORK( 1 ) = REAL( LWMIN )
067 IWORK( 1 ) = LIWMIN
068 LQUERY =( LWORK.EQ. - 1 .OR. LIWORK.EQ. - 1 )
069 IF( .NOT.LSAME( COMPZ , 'I' ) ) THEN
069
070 INFO = - 1
071 ELSE IF( N.LT.0 ) THEN
071
072 INFO = - 2
073 ELSE IF( IROFFQ.NE.ICOFFQ .OR. ICOFFQ.NE.0 ) THEN
073
074 INFO = - 5
075 ELSE IF( DESCQ( MB_ ).NE.DESCQ( NB_ ) ) THEN
075
076 INFO = - ( 700 + NB_ )
077 ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
077
078 INFO = - 10
079 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
079
080 INFO = - 12
081 END IF
082 END IF
083 END IF
084 IF( INFO.NE.0 ) THEN
084
085 CALL PXERBLA( DESCQ( CTXT_ ) , 'PSSTEDC' , - INFO )
086 RETURN
087 ELSE IF( LQUERY ) THEN
087
088 RETURN
089 END IF
090
091 * Quick return
092
093 IF( N.EQ.0 )
093
094 $ GO TO 10
095 CALL INFOG2L( IQ , JQ , DESCQ , NPROW , NPCOL , MYROW , MYCOL , IIQ , JJQ ,
096 $ IQROW , IQCOL )
097 IF( N.EQ.1 ) THEN
097
098 IF( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL )
098
099 $ Q( 1 ) = ONE
100 GO TO 10
101 END IF
102
103 * If N is smaller than the minimum divide size NB , then
104 * solve the problem with the serial divide and conquer
105 * code locally.
106
107 IF( N.LE.NB ) THEN
107
108 IF(( MYROW.EQ.IQROW ) .AND.( MYCOL.EQ.IQCOL ) ) THEN
108
109 IPQ = IIQ + ( JJQ - 1 )*LDQ
110 CALL SSTEDC( 'I' , N , D , E , Q( IPQ ) , LDQ , WORK , LWORK ,
111 $ IWORK , LIWORK , INFO )
112 IF( INFO.NE.0 ) THEN
112
113 INFO =( N + 1 ) + N
114 GO TO 10
115 END IF
116 END IF
117 GO TO 10
118 END IF
119
120 * If P = NPROW*NPCOL = 1 , solve the problem with SSTEDC.
121
122 IF( NPCOL*NPROW.EQ.1 ) THEN
122
123 IPQ = IIQ + ( JJQ - 1 )*LDQ
124 CALL SSTEDC( 'I' , N , D , E , Q( IPQ ) , LDQ , WORK , LWORK , IWORK ,
125 $ LIWORK , INFO )
126 GO TO 10
127 END IF
128
129 * Scale matrix to allowable range , if necessary.
130
131 ORGNRM = SLANST( 'M' , N , D , E )
132 IF( ORGNRM.NE.ZERO ) THEN
132
133 CALL SLASCL( 'G' , 0 , 0 , ORGNRM , ONE , N , 1 , D , N , INFO )
134 CALL SLASCL( 'G' , 0 , 0 , ORGNRM , ONE , N - 1 , 1 , E , N - 1 , INFO )
135 END IF
136
137 CALL PSLAED0 ( N , D , E , Q , IQ , JQ , DESCQ , WORK , IWORK , INFO )
138
139 * Sort eigenvalues and corresponding eigenvectors
140
141 CALL PSLASRT ( 'I' , N , D , Q , IQ , JQ , DESCQ , WORK , LWORK , IWORK ,
142 $ LIWORK , INFO )
143
144 * Scale back.
145
146 IF( ORGNRM.NE.ZERO )
146
147 $ CALL SLASCL( 'G' , 0 , 0 , ONE , ORGNRM , N , 1 , D , N , INFO )
148
149 10 CONTINUE
150
151 IF( LWORK.GT.0 )
151
152 $ WORK( 1 ) = REAL( LWMIN )
153 IF( LIWORK.GT.0 )
153
154 $ IWORK( 1 ) = LIWMIN
155 RETURN
156
157 * End of PSSTEDC
158
159 END22
23
|
|
Variables in Routine PSSTEDC()
| Summary Report |
| Data Type | Quantity | Size(byte) |
| CHARACTER | 1 | 1 |
| INTEGER | 37 | 148 |
| LOGICAL | 2 | 2 |
| REAL | 6 | 24 |
| TOTAL | 46 | 175 |
List of Variables
CHARACTER
INTEGER
| BLOCK_CYCLIC_2D | CSRC_ | CTXT_ | DLEN_ | DTYPE_ |
| ICOFFQ | IIQ | INDXG2P | INFO | IPQ |
| IQ | IQCOL | IQROW | IROFFQ | IWORK |
| JJQ | JQ | LDQ | LIWMIN | LIWORK |
| LLD_ | LWMIN | LWORK | M_ | MB_ |
| MYCOL | MYROW | N | N_ | NB |
| NB_ | NP | NPCOL | NPROW | NQ |
| NUMROC | RSRC_ | | | |
LOGICAL
REAL
| ONE | ORGNRM | Q | SLANST | WORK |
| ZERO | | | | |
Variables Dependence Graph Put the mouse over a right hand side variable to display the corresponding line of the dependence | | - | | - | - | | ICOFFQ | <--- | JQICOFFQ = MOD( JQ-1, DESCQ( NB_ ) ), NB_ICOFFQ = MOD( JQ-1, DESCQ( NB_ ) ) |
| INFO | <--- | NINFO = ( N+1 ) + N, NB_INFO = -( 700+NB_ ), CTXT_INFO = -( 600+CTXT_ ) |
| IPQ | <--- | JJQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ}, LDQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ}, IIQIPQ = IIQ + ( JJQ-1 )*LDQ{2IPQ = IIQ + ( JJQ-1 )*LDQ} |
| IQCOL | <--- | JQIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), MYCOLIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), CSRC_IQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NBIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NPCOLIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), INDXG2PIQCOL = INDXG2P( JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ) |
| IQROW | <--- | IQIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), MYROWIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NBIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NPROWIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), RSRC_IQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ), INDXG2PIQROW = INDXG2P( IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW ) |
| IROFFQ | <--- | IQIROFFQ = MOD( IQ-1, DESCQ( MB_ ) ), MB_IROFFQ = MOD( IQ-1, DESCQ( MB_ ) ) |
| IWORK | <--- | LIWMINIWORK( 1 ) = LIWMIN |
| LDQ | <--- | LLD_LDQ = DESCQ( LLD_ ) |
| LIWMIN | <--- | NLIWMIN = 2 + 7*N + 8*NPCOL, NPCOLLIWMIN = 2 + 7*N + 8*NPCOL |
| LWMIN | <--- | NLWMIN = 6*N + 2*NP*NQ, NPLWMIN = 6*N + 2*NP*NQ, NQLWMIN = 6*N + 2*NP*NQ |
| NB | <--- | NB_NB = DESCQ( NB_ ){2NB = DESCQ( NB_ )} |
| NP | <--- | MYROWNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NBNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NPROWNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), NUMROCNP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ), RSRC_NP = NUMROC( N, NB, MYROW, DESCQ( RSRC_ ), NPROW ) |
| NQ | <--- | MYCOLNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), CSRC_NQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NBNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NPCOLNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ), NUMROCNQ = NUMROC( N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL ) |
| ORGNRM | <--- | NORGNRM = SLANST( 'M', N, D, E ), SLANSTORGNRM = SLANST( 'M', N, D, E ) |
| WORK | <--- | LWMINWORK( 1 ) = REAL( LWMIN ) |
|
|
Analysis elements of the routine PSSTEDC() Put the mouse over each element to display detailed matching information
Assigned variables |
| | | BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ , ICOFFQ , INFO , IPQ , IQCOL , IQROW , IROFFQ , IWORK , LDQ , LIWMIN , LLD_ , LQUERY , LWMIN , M_ , MB_ , N_ , NB , NB_ , NP , NPCOL , NQ , ONE , ORGNRM , Q , RSRC_ , WORK , ZERO |
|
Active variables |
| | | BLOCK_CYCLIC_2D , COMPZ , CSRC_ , CTXT_ , D , DESCQ , DLEN_ , DTYPE_ , E , ICOFFQ , IIQ , INDXG2P , INFO , IPQ , IQ , IQCOL , IQROW , IROFFQ , IWORK , JJQ , JQ , LDQ , LIWMIN , LIWORK , LLD_ , LQUERY , LSAME , LWMIN , LWORK , M_ , MB_ , MYCOL , MYROW , N , N_ , NB , NB_ , NP , NPCOL , NPROW , NQ , NUMROC , ONE , ORGNRM , Q , RSRC_ , SLANST , WORK , ZERO |
|
Accessed arrays [ array name : associated index ] |
| | DESCQ | : CSRC_ , CSRC_ , CTXT_ , CTXT_ , LLD_ , MB_ , MB_ , NB_ , NB_ , NB_ , NB_ , RSRC_ , RSRC_ |
| | INDXG2P | : IQ, NB, MYROW, DESCQ( RSRC_ ), NPROW , JQ, NB, MYCOL, DESCQ( CSRC_ ), NPCOL |
| | IWORK | : 1 , 1 |
| | LSAME | : COMPZ, 'I' |
| | NUMROC | : N, NB, MYCOL, DESCQ( CSRC_ ), NPCOL , N, NB, MYROW, DESCQ( RSRC_ ), NPROW |
| | Q | : 1 , IPQ , IPQ |
| | SLANST | : 'M', N, D, E |
| | WORK | : 1 , 1 |
|
Conditional statements [ statement : associated predicate ] |
| | if | : ( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_* ) , ( NPROW.EQ. - 1 ) , ( INFO.EQ.0 ) , ( (.NOT.LSAME( COMPZ , 'I' ) ) ) , ( N.LT.0 ) , ( IROFFQ.NE.ICOFFQ .OR. ICOFFQ.NE.0 ) , ( (DESCQ( MB_ ).NE.DESCQ( NB_ ) ) ) , ( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) , ( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) , ( INFO.NE.0 ) , ( LQUERY ) , ( N.EQ.0 ) , ( N.EQ.1 ) , ( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL ) , ( N is smaller than the minimum divide size NB , ) , ( N.LE.NB ) , ( (( MYROW.EQ.IQROW ) .AND. ( MYCOL.EQ.IQCOL ) ) ) , ( INFO.NE.0 ) , ( P=NPROW*NPCOL = 1 , solve the problem with SSTEDC. ) , ( NPCOL*NPROW.EQ.1 ) , ( necessary. ) , ( ORGNRM.NE.ZERO ) , ( ORGNRM.NE.ZERO ) , ( LWORK.GT.0 ) , ( LIWORK.GT.0 ) |
|
| List of variables | BLOCK_CYCLIC_2D COMPZ CSRC_ CTXT_ DLEN_ DTYPE_ ICOFFQ
| IIQ INDXG2P INFO IPQ IQ IQCOL IQROW IROFFQ
| IWORK JJQ JQ LDQ LIWMIN LIWORK LLD_ LQUERY
| LSAME LWMIN LWORK M_ MB_ MYCOL MYROW N
| N_ NB NB_ NP NPCOL NPROW NQ NUMROC
| ONE ORGNRM Q RSRC_ SLANST WORK ZERO | | close
| |
BLOCK_CYCLIC_2D
COMPZ
CSRC_
CTXT_
DLEN_
DTYPE_
ICOFFQ
IIQ
INDXG2P
INFO
IPQ
IQ
IQCOL
IQROW
IROFFQ
IWORK
JJQ
JQ
LDQ
LIWMIN
LIWORK
LLD_
LQUERY
LSAME
LWMIN
LWORK
M_
MB_
MYCOL
MYROW
N
N_
NB
NB_
NP
NPCOL
NPROW
NQ
NUMROC
ONE
ORGNRM
Q
RSRC_
SLANST
WORK
ZERO
361#393
| |