7
8
9
10
11
12
13
14 LOGICAL WKNOWN
15 CHARACTER JOBZ, UPLO
16 INTEGER IA, IPOSTPAD, IPREPAD, JA, LWORK, LWORK1, N,
17 $ NOUT, RESULT
18 REAL ABSTOL, QTQNRM, THRESH, TSTNRM
19
20
21 INTEGER DESCA( * )
22 REAL A( * ), COPYA( * ), WIN( * ), WNEW( * ),
23 $ WORK( * ), Z( * )
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 INTEGER BLOCK_CYCLIC_2D, DLEN_, DT_, CTXT_, M_, N_,
147 $ MB_, NB_, RSRC_, CSRC_, LLD_
148 parameter( block_cyclic_2d = 1, dlen_ = 9, dt_ = 1,
149 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
150 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
151 REAL FIVE, NEGONE, PADVAL, ZERO
152 parameter( padval = 13.5285e+0, five = 5.0e+0,
153 $ negone = -1.0e+0, zero = 0.0e+0 )
154
155
156 INTEGER I, IAM, INFO, ISIZESUBTST, ISIZESYEVX,
157 $ ISIZETST, J, EIGS, MINSIZE, MQ, MYCOL, MYROW,
158 $ NP, NPCOL, NPROW, NQ, RESAQ, RESQTQ,
159 $ SIZECHK, SIZEMQRLEFT, SIZEMQRRIGHT, SIZEQRF,
160 $ SIZEQTQ, SIZESUBTST, SIZESYEV, SIZESYEVX,
161 $ SIZETMS, SIZETST, SIZESYEVD, ISIZESYEVD
162 REAL EPS, EPSNORMA, ERROR, MAXERROR, MINERROR,
163 $ NORMWIN, SAFMIN
164
165
166 INTEGER DESCZ( DLEN_ ), ITMP( 2 ),
167 $ IWORK( 2 )
168
169
170
171 LOGICAL LSAME
172 INTEGER NUMROC
173 REAL PSLAMCH, PSLANSY
175
176
177 EXTERNAL blacs_gridinfo,
descinit, igamn2d, igamx2d,
181
182
183 INTRINSIC abs,
max,
min, mod
184
185
186
187 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dt_*lld_*mb_*m_*nb_*n_*
188 $ rsrc_.LT.0 )RETURN
189 CALL pslasizesqp( desca, iprepad, ipostpad, sizemqrleft,
190 $ sizemqrright, sizeqrf, sizetms, sizeqtq,
191 $ sizechk, sizesyevx, isizesyevx, sizesyev,
192 $ sizesyevd, isizesyevd, sizesubtst, isizesubtst,
193 $ sizetst, isizetst )
194
195 tstnrm = negone
196 qtqnrm = negone
197 eps =
pslamch( desca( ctxt_ ),
'Eps' )
198 safmin =
pslamch( desca( ctxt_ ),
'Safe min' )
199
200 normwin = safmin / eps
201 IF( n.GE.1 )
202 $ normwin =
max( abs( win( 1+iprepad ) ),
203 $ abs( win( n+iprepad ) ), normwin )
204
205
206
207 DO 10 i = 1, lwork1, 1
208 work( i+iprepad ) = 14.3e+0
209 10 CONTINUE
210
211 DO 30 i = 1, n
212 wnew( i+iprepad ) = 3.14159e+0
213 30 CONTINUE
214
215 DO 40 i = 1, 2
216 iwork( i ) = 0
217 40 CONTINUE
218
219 IF(
lsame( jobz,
'N' ) )
THEN
220 eigs = 0
221 ELSE
222 eigs = n
223 END IF
224
225
226 CALL descinit( descz, desca( m_ ), desca( n_ ), desca( mb_ ),
227 $ desca( nb_ ), desca( rsrc_ ), desca( csrc_ ),
228 $ desca( ctxt_ ), desca( lld_ ), info )
229
230 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
231
232 iam = 1
233 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
234 $ iam = 0
235
236
237
238 result = -3
239 IF( myrow.GE.nprow .OR. myrow.LT.0 )
240 $ GO TO 150
241 result = 0
242
243 np =
numroc( n, desca( mb_ ), myrow, 0, nprow )
244 nq =
numroc( n, desca( nb_ ), mycol, 0, npcol )
245 mq =
numroc( eigs, desca( nb_ ), mycol, 0, npcol )
246
247
248
250
251 CALL slacpy( 'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
252 $ desca( lld_ ) )
253
254 CALL psfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
255 $ ipostpad, padval )
256
257 CALL psfillpad( descz( ctxt_ ), np, mq, z, descz( lld_ ), iprepad,
258 $ ipostpad, padval+1.0e+0 )
259
260 CALL psfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
261 $ padval+2.0e+0 )
262
263 CALL psfillpad( desca( ctxt_ ), lwork1, 1, work, lwork1, iprepad,
264 $ ipostpad, padval+4.0e+0 )
265
266
267
268
269 DO 60 i = 1, n, 1
270 DO 50 j = 1, eigs, 1
271 CALL pselset( z( 1+iprepad ), i, j, desca, 13.0e+0 )
272 50 CONTINUE
273 60 CONTINUE
274
278 CALL pssyev( jobz, uplo, n, a( 1+iprepad ), ia, ja, desca,
279 $ wnew( 1+iprepad ), z( 1+iprepad ), ia, ja, desca,
280 $ work( 1+iprepad ), lwork1, info )
283
284 IF( thresh.LE.0 ) THEN
285 result = 0
286 ELSE
287 CALL pschekpad( desca( ctxt_ ),
'PSSYEV-A', np, nq, a,
288 $ desca( lld_ ), iprepad, ipostpad, padval )
289
290 CALL pschekpad( descz( ctxt_ ),
'PSSYEV-Z', np, mq, z,
291 $ descz( lld_ ), iprepad, ipostpad,
292 $ padval+1.0e+0 )
293
294 CALL pschekpad( desca( ctxt_ ),
'PSSYEV-WNEW', n, 1, wnew, n,
295 $ iprepad, ipostpad, padval+2.0e+0 )
296
297 CALL pschekpad( desca( ctxt_ ),
'PSSYEV-WORK', lwork1, 1,
298 $ work, lwork1, iprepad, ipostpad,
299 $ padval+4.0e+0 )
300
301
302
303
304
305
306 itmp( 1 ) = info
307 itmp( 2 ) = info
308
309 CALL igamn2d( desca( ctxt_ ), 'a', ' ', 1, 1, itmp, 1, 1, 1,
310 $ -1, -1, 0 )
311 CALL igamx2d( desca( ctxt_ ), 'a', ' ', 1, 1, itmp( 2 ), 1, 1,
312 $ 1, -1, -1, 0 )
313
314
315 IF( itmp( 1 ).NE.itmp( 2 ) ) THEN
316 IF( iam.EQ.0 )
317 $ WRITE( nout, fmt = * )
318 $ 'Different processes return different INFO'
319 result = 1
320 ELSE IF( info.NE.0 ) THEN
321 IF( iam.EQ.0 ) THEN
322 WRITE( nout, fmt = 9999 )info
323 IF( info.EQ.(n+1) )
324 $ WRITE( nout, fmt = 9994 )
325 result = 1
326 END IF
327 ELSE IF( info.EQ.14 .AND. lwork1.GE.minsize ) THEN
328 IF( iam.EQ.0 )
329 $ WRITE( nout, fmt = 9996 )info
330 result = 1
331 END IF
332
333 IF( result.EQ.0 .OR. info.GT.n ) THEN
334
335
336
337
338 DO 70 i = 1, n
339 work( i ) = wnew( i+iprepad )
340 work( i+n ) = wnew( i+iprepad )
341 70 CONTINUE
342
343 CALL sgamn2d( desca( ctxt_ ), 'a', ' ', n, 1, work, n, 1,
344 $ 1, -1, -1, 0 )
345 CALL sgamx2d( desca( ctxt_ ), 'a', ' ', n, 1,
346 $ work( 1+n ), n, 1, 1, -1, -1, 0 )
347
348 DO 80 i = 1, n
349
350 IF( abs( work( i )-work( n+i ) ).GT.zero ) THEN
351 IF( iam.EQ.0 )
352 $ WRITE( nout, fmt = 9995 )
353 result = 1
354 GO TO 90
355 END IF
356 80 CONTINUE
357 90 CONTINUE
358 END IF
359
360 CALL igamx2d( desca( ctxt_ ), 'a', ' ', 1, 1, result, 1, 1, 1,
361 $ -1, -1, 0 )
362
363
364
365 IF( n.EQ.0 ) THEN
366 epsnorma = eps
367 ELSE
368 epsnorma =
pslansy(
'I', uplo, n, copya, ia, ja, desca,
369 $ work )*eps
370 END IF
371
372
373
374
375
376
377
378
379
380
381
382 IF(
lsame( jobz,
'V' ) )
THEN
383
384
385
386 CALL psfillpad( desca( ctxt_ ), sizechk, 1, work, sizechk,
387 $ iprepad, ipostpad, 4.3e+0 )
388
389 resaq = 0
390
391 CALL pssepchk( n, n, copya, ia, ja, desca,
392 $
max( abstol+epsnorma, safmin ), thresh,
393 $ z( 1+iprepad ), ia, ja, descz,
394 $ a( 1+iprepad ), ia, ja, desca,
395 $ wnew( 1+iprepad ), work( 1+iprepad ),
396 $ sizechk, tstnrm, resaq )
397
398 CALL pschekpad( desca( ctxt_ ),
'PSSEPCHK-WORK', sizechk, 1,
399 $ work, sizechk, iprepad, ipostpad, 4.3e+0 )
400
401 IF( resaq.NE.0 ) THEN
402 result = 1
403 WRITE( nout, fmt = 9993 )
404 END IF
405
406
407
408 CALL psfillpad( desca( ctxt_ ), sizeqtq, 1, work, sizeqtq,
409 $ iprepad, ipostpad, 4.3e+0 )
410
411 resqtq = 0
412
413 CALL pssepqtq( n, n, thresh, z( 1+iprepad ), ia, ja, descz,
414 $ a( 1+iprepad ), ia, ja, desca,
415 $ iwork( 1 ), iwork( 1 ), work( 1 ),
416 $ work( iprepad+1 ), sizeqtq, qtqnrm, info,
417 $ resqtq )
418
419 CALL pschekpad( desca( ctxt_ ),
'PSSEPQTQ-WORK', sizeqtq, 1,
420 $ work, sizeqtq, iprepad, ipostpad, 4.3e+0 )
421
422 IF( resqtq.NE.0 ) THEN
423 result = 1
424 WRITE( nout, fmt = 9992 )
425 END IF
426
427 IF( info.NE.0 ) THEN
428 IF( iam.EQ.0 )
429 $ WRITE( nout, fmt = 9998 )info
430 result = 1
431 END IF
432 END IF
433
434
435
436 IF( wknown .AND. n.GT.0 ) THEN
437
438
439
440
441 minerror = normwin
442 maxerror = 0
443
444 DO 140 i = 1, n
445 error = abs( win( i+iprepad )-wnew( i+iprepad ) )
446 maxerror =
max( maxerror, error )
447 140 CONTINUE
448 minerror =
min( maxerror, minerror )
449
450 IF( minerror.GT.normwin*five*thresh*eps ) THEN
451 IF( iam.EQ.0 )
452 $ WRITE( nout, fmt = 9997 )minerror, normwin
453 result = 1
454 END IF
455 END IF
456 END IF
457
458
459
460 CALL igamx2d( desca( ctxt_ ), 'a', ' ', 1, 1, result, 1, 1, 1, -1,
461 $ -1, 0 )
462
463 150 CONTINUE
464
465
466 RETURN
467
468 9999 FORMAT( 'PSSYEV returned INFO=', i7 )
469 9998 FORMAT( 'PSSEPQTQ in PSSQPSUBTST returned INFO=', i7 )
470 9997 FORMAT( 'PSSQPSUBTST minerror =', d11.2, ' normwin=', d11.2 )
471 9996 FORMAT( 'PSSYEV returned INFO=', i7,
472 $ ' despite adequate workspace' )
473 9995 FORMAT( 'Different processes return different eigenvalues' )
474 9994 FORMAT( 'Heterogeneity detected by PSSYEV' )
475 9993 FORMAT( 'PSSYEV failed the |AQ -QE| test' )
476 9992 FORMAT( 'PSSYEV failed the |QTQ -I| test' )
477
478
479
subroutine descinit(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld, info)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
real function pslamch(ictxt, cmach)
subroutine pschekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pselset(a, ia, ja, desca, alpha)
subroutine psfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
real function pslansy(norm, uplo, n, a, ia, ja, desca, work)
subroutine pslasizesqp(desca, iprepad, ipostpad, sizemqrleft, sizemqrright, sizeqrf, sizetms, sizeqtq, sizechk, sizesyevx, isizesyevx, sizesyev, sizesyevd, isizesyevd, sizesubtst, isizesubtst, sizetst, isizetst)
subroutine pslasizesyev(jobz, n, desca, minsize)
subroutine pssepchk(ms, nv, a, ia, ja, desca, epsnorma, thresh, q, iq, jq, descq, c, ic, jc, descc, w, work, lwork, tstnrm, result)
subroutine pssepqtq(ms, nv, thresh, q, iq, jq, descq, c, ic, jc, descc, procdist, iclustr, gap, work, lwork, qtqnrm, info, res)
subroutine pssyev(jobz, uplo, n, a, ia, ja, desca, w, z, iz, jz, descz, work, lwork, info)