3
4
5
6
7
8
9
10 CHARACTER JOBZ, UPLO
11 INTEGER IA, INFO, IZ, JA, JZ, LIWORK, LWORK, N
12
13
14 INTEGER DESCA( * ), DESCZ( * ), IWORK( * )
15 REAL A( * ), W( * ), WORK( * ), Z( * )
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
156 $ MB_, NB_, RSRC_, CSRC_, LLD_
157 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
158 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
159 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
160 REAL ZERO, ONE
161 parameter( zero = 0.0e+0, one = 1.0e+0 )
162
163
164 LOGICAL LQUERY, UPPER
165 INTEGER IACOL, IAROW, ICOFFA, ICOFFZ, ICTXT, IINFO,
166 $ INDD, INDE, INDE2, INDTAU, INDWORK, INDWORK2,
167 $ IROFFA, IROFFZ, ISCALE, LIWMIN, LLWORK,
168 $ LLWORK2, LWMIN, MYCOL, MYROW, NB, NP, NPCOL,
169 $ NPROW, NQ, OFFSET, TRILWMIN
170 REAL ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
171 $ SMLNUM
172
173
174 INTEGER IDUM1( 2 ), IDUM2( 2 )
175
176
177 LOGICAL LSAME
178 INTEGER INDXG2P, NUMROC
179 REAL PSLAMCH, PSLANSY
181
182
186
187
188 INTRINSIC ichar,
max,
min, mod, real, sqrt
189
190
191
192 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
193 $ rsrc_.LT.0 )RETURN
194
195
196
197 IF( n.EQ.0 )
198 $ RETURN
199
200
201
202 ictxt = descz( ctxt_ )
203 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
204
205 info = 0
206 IF( nprow.EQ.-1 ) THEN
207 info = -( 600+ctxt_ )
208 ELSE
209 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
210 CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
211 IF( info.EQ.0 ) THEN
212 upper =
lsame( uplo,
'U' )
213 nb = desca( nb_ )
214 iroffa = mod( ia-1, desca( mb_ ) )
215 icoffa = mod( ja-1, desca( nb_ ) )
216 iroffz = mod( iz-1, descz( mb_ ) )
217 icoffz = mod( jz-1, descz( nb_ ) )
218 iarow =
indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
219 iacol =
indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
220 np =
numroc( n, nb, myrow, iarow, nprow )
221 nq =
numroc( n, nb, mycol, iacol, npcol )
222
223 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
224 trilwmin = 3*n +
max( nb*( np+1 ), 3*nb )
225 lwmin =
max( 1+6*n+2*np*nq, trilwmin ) + 2*n
226 liwmin = 7*n + 8*npcol + 2
227 work( 1 ) = real( lwmin )
228 iwork( 1 ) = liwmin
229 IF( .NOT.
lsame( jobz,
'V' ) )
THEN
230 info = -1
231 ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
232 info = -2
233 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 ) THEN
234 info = -6
235 ELSE IF( iroffa.NE.iroffz .OR. icoffa.NE.icoffz ) THEN
236 info = -10
237 ELSE IF( desca( m_ ).NE.descz( m_ ) ) THEN
238 info = -( 1200+m_ )
239 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
240 info = -( 700+nb_ )
241 ELSE IF( descz( mb_ ).NE.descz( nb_ ) ) THEN
242 info = -( 1200+nb_ )
243 ELSE IF( desca( mb_ ).NE.descz( mb_ ) ) THEN
244 info = -( 1200+mb_ )
245 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) ) THEN
246 info = -( 1200+ctxt_ )
247 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) ) THEN
248 info = -( 1200+rsrc_ )
249 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) ) THEN
250 info = -( 1200+csrc_ )
251 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
252 info = -14
253 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
254 info = -16
255 END IF
256 END IF
257 IF( upper ) THEN
258 idum1( 1 ) = ichar( 'U' )
259 ELSE
260 idum1( 1 ) = ichar( 'L' )
261 END IF
262 idum2( 1 ) = 2
263 IF( lwork.EQ.-1 ) THEN
264 idum1( 2 ) = -1
265 ELSE
266 idum1( 2 ) = 1
267 END IF
268 idum2( 2 ) = 14
269 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 2, idum1, idum2,
270 $ info )
271 END IF
272 IF( info.NE.0 ) THEN
273 CALL pxerbla( ictxt,
'PSSYEVD', -info )
274 RETURN
275 ELSE IF( lquery ) THEN
276 RETURN
277 END IF
278
279
280
281 indtau = 1
282 inde = indtau + n
283 indd = inde + n
284 inde2 = indd + n
285 indwork = inde2 + n
286 llwork = lwork - indwork + 1
287 indwork2 = indd
288 llwork2 = lwork - indwork2 + 1
289
290
291
292 iscale = 0
293 safmin =
pslamch( desca( ctxt_ ),
'Safe minimum' )
294 eps =
pslamch( desca( ctxt_ ),
'Precision' )
295 smlnum = safmin / eps
296 bignum = one / smlnum
297 rmin = sqrt( smlnum )
298 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
299 anrm =
pslansy(
'M', uplo, n, a, ia, ja, desca, work( indwork ) )
300
301 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
302 iscale = 1
303 sigma = rmin / anrm
304 ELSE IF( anrm.GT.rmax ) THEN
305 iscale = 1
306 sigma = rmax / anrm
307 END IF
308
309 IF( iscale.EQ.1 ) THEN
310 CALL pslascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
311 END IF
312
313
314
315
316 CALL pssytrd( uplo, n, a, ia, ja, desca, work( indd ),
317 $ work( inde2 ), work( indtau ), work( indwork ),
318 $ llwork, iinfo )
319
320
321
322 CALL pslared1d( n, ia, ja, desca, work( indd ), w,
323 $ work( indwork ), llwork )
324
325 CALL pslared1d( n, ia, ja, desca, work( inde2 ), work( inde ),
326 $ work( indwork ), llwork )
327
328 CALL pslaset(
'Full', n, n, zero, one, z, 1, 1, descz )
329
330 IF( upper ) THEN
331 offset = 1
332 ELSE
333 offset = 0
334 END IF
335 CALL psstedc(
'I', n, w, work( inde+offset ), z, iz, jz, descz,
336 $ work( indwork2 ), llwork2, iwork, liwork, info )
337
338 CALL psormtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
339 $ work( indtau ), z, iz, jz, descz, work( indwork2 ),
340 $ llwork2, iinfo )
341
342
343
344 IF( iscale.EQ.1 ) THEN
345 CALL sscal( n, one / sigma, w, 1 )
346 END IF
347
348 RETURN
349
350
351
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
real function pslamch(ictxt, cmach)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
real function pslansy(norm, uplo, n, a, ia, ja, desca, work)
subroutine pslared1d(n, ia, ja, desc, bycol, byall, work, lwork)
subroutine pslascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
subroutine psormtr(side, uplo, trans, m, n, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine psstedc(compz, n, d, e, q, iq, jq, descq, work, lwork, iwork, liwork, info)
subroutine pssytrd(uplo, n, a, ia, ja, desca, d, e, tau, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)