6
7
8
9
10
11
12
13 LOGICAL WKNOWN
14 CHARACTER UPLO
15 INTEGER IA, IPOSTPAD, IPREPAD, JA, LIWORK, LRWORK,
16 $ LWORK, LWORK1, N, NOUT, RESULT
17 REAL ABSTOL, QTQNRM, THRESH, TSTNRM
18
19
20 INTEGER DESCA( * ), IWORK( * )
21 REAL RWORK( * ), WIN( * ), WNEW( * )
22 COMPLEX A( * ), COPYA( * ), WORK( * ), Z( * )
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
156 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
157 $ MB_, NB_, RSRC_, CSRC_, LLD_
158 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
159 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
160 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
161 REAL PADVAL, FIVE, NEGONE
162 parameter( padval = 13.5285e+0, five = 5.0e+0,
163 $ negone = -1.0e+0 )
164 COMPLEX CPADVAL
165 parameter( cpadval = ( 13.989e+0, 1.93e+0 ) )
166 INTEGER IPADVAL
167 parameter( ipadval = 927 )
168 COMPLEX CZERO, CONE, CNEGONE
169 parameter( czero = 0.0e+0, cone = 1.0e+0,
170 $ cnegone = -1.0e+0 )
171
172
173 INTEGER I, IAM, INFO, ISIZEHEEVD, ISIZEHEEVX,
174 $ ISIZESUBTST, ISIZETST, MYCOL, MYROW, NP, NPCOL,
175 $ NPROW, NQ, RES, RSIZECHK, RSIZEHEEVD,
176 $ RSIZEHEEVX, RSIZEQTQ, RSIZESUBTST, RSIZETST,
177 $ SIZEHEEVD, SIZEHEEVX, SIZEMQRLEFT,
178 $ SIZEMQRRIGHT, SIZEQRF, SIZESUBTST, SIZETMS,
179 $ SIZETST
180 REAL EPS, EPSNORMA, ERROR, MAXERROR, MINERROR, NORM,
181 $ NORMWIN, SAFMIN, ULP
182
183
184 INTEGER ITMP( 2 )
185
186
187
188 INTEGER NUMROC
189 REAL PCLANGE, PCLANHE, PSLAMCH
191
192
193 EXTERNAL blacs_gridinfo, clacpy, igamn2d, igamx2d,
197
198
199 INTRINSIC abs,
max,
min, real
200
201
202
203 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
204 $ rsrc_.LT.0 )RETURN
205
206 CALL pclasizesep( desca, iprepad, ipostpad, sizemqrleft,
207 $ sizemqrright, sizeqrf, sizetms, rsizeqtq,
208 $ rsizechk, sizeheevx, rsizeheevx, isizeheevx,
209 $ sizeheevd, rsizeheevd, isizeheevd, sizesubtst,
210 $ rsizesubtst, isizesubtst, sizetst, rsizetst,
211 $ isizetst )
212
213 tstnrm = negone
214 qtqnrm = negone
215 eps =
pslamch( desca( ctxt_ ),
'Eps' )
216 safmin =
pslamch( desca( ctxt_ ),
'Safe min' )
217
218 normwin = safmin / eps
219 IF( n.GE.1 )
220 $ normwin =
max( abs( win( 1+iprepad ) ),
221 $ abs( win( n+iprepad ) ), normwin )
222
223 DO 10 i = 1, lwork1, 1
224 rwork( i+iprepad ) = 14.3e+0
225 10 CONTINUE
226 DO 20 i = 1, liwork, 1
227 iwork( i ) = 14
228 20 CONTINUE
229 DO 30 i = 1, lwork, 1
230 work( i+iprepad ) = ( 15.63e+0, 1.1e+0 )
231 30 CONTINUE
232
233 DO 40 i = 1, n
234 wnew( i+iprepad ) = 3.14159e+0
235 40 CONTINUE
236
237 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
238
239 iam = 1
240 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
241 $ iam = 0
242
243
244
245 result = -3
246 IF( myrow.GE.nprow .OR. myrow.LT.0 )
247 $ GO TO 60
248 result = 0
249
250 np =
numroc( n, desca( mb_ ), myrow, 0, nprow )
251 nq =
numroc( n, desca( nb_ ), mycol, 0, npcol )
252
253 CALL clacpy( 'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
254 $ desca( lld_ ) )
255
256 CALL pcfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
257 $ ipostpad, cpadval )
258
259 CALL pcfillpad( desca( ctxt_ ), np, nq, z, desca( lld_ ), iprepad,
260 $ ipostpad, cpadval+1.0e+0 )
261
262 CALL psfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
263 $ padval+2.0e+0 )
264
265 CALL psfillpad( desca( ctxt_ ), lwork1, 1, rwork, lwork1, iprepad,
266 $ ipostpad, padval+4.0e+0 )
267
268 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
269 $ ipostpad, ipadval )
270
271 CALL pcfillpad( desca( ctxt_ ), lwork, 1, work, lwork, iprepad,
272 $ ipostpad, cpadval+4.1e+0 )
273
277
278 CALL pcheevd(
'V', uplo, n, a( 1+iprepad ), ia, ja, desca,
279 $ wnew( 1+iprepad ), z( 1+iprepad ), ia, ja, desca,
280 $ work( 1+iprepad ), sizeheevd, rwork( 1+iprepad ),
281 $ lwork1, iwork( 1+iprepad ), liwork, info )
284
285 IF( thresh.LE.0 ) THEN
286 result = 0
287 ELSE
288 CALL pcchekpad( desca( ctxt_ ),
'PCHEEVD-A', np, nq, a,
289 $ desca( lld_ ), iprepad, ipostpad, cpadval )
290
291 CALL pcchekpad( desca( ctxt_ ),
'PCHEEVD-Z', np, nq, z,
292 $ desca( lld_ ), iprepad, ipostpad,
293 $ cpadval+1.0e+0 )
294
295 CALL pschekpad( desca( ctxt_ ),
'PCHEEVD-WNEW', n, 1, wnew, n,
296 $ iprepad, ipostpad, padval+2.0e+0 )
297
298 CALL pschekpad( desca( ctxt_ ),
'PCHEEVD-rWORK', lwork1, 1,
299 $ rwork, lwork1, iprepad, ipostpad,
300 $ padval+4.0e+0 )
301
302 CALL pcchekpad( desca( ctxt_ ),
'PCHEEVD-WORK', lwork, 1, work,
303 $ lwork, iprepad, ipostpad, cpadval+4.1e+0 )
304
305 CALL pichekpad( desca( ctxt_ ),
'PCHEEVD-IWORK', liwork, 1,
306 $ iwork, liwork, iprepad, ipostpad, ipadval )
307
308
309
310
311
312 itmp( 1 ) = info
313 itmp( 2 ) = info
314
315 CALL igamn2d( desca( ctxt_ ), 'a', ' ', 1, 1, itmp, 1, 1, 1,
316 $ -1, -1, 0 )
317 CALL igamx2d( desca( ctxt_ ), 'a', ' ', 1, 1, itmp( 2 ), 1, 1,
318 $ 1, -1, -1, 0 )
319
320
321 IF( itmp( 1 ).NE.itmp( 2 ) ) THEN
322 IF( iam.EQ.0 )
323 $ WRITE( nout, fmt = * )
324 $ 'Different processes return different INFO'
325 result = 1
326 ELSE IF( info.NE.0 ) THEN
327 IF( iam.EQ.0 )
328 $ WRITE( nout, fmt = 9996 )info
329 result = 1
330 END IF
331
332
333
334 IF( n.EQ.0 ) THEN
335 epsnorma = eps
336 ELSE
337 epsnorma =
pclanhe(
'I', uplo, n, copya, ia, ja, desca,
338 $ rwork )*eps
339 END IF
340
341
342
343
344
345
346
347
348
349
350
351
352 CALL psfillpad( desca( ctxt_ ), rsizechk, 1, rwork, rsizechk,
353 $ iprepad, ipostpad, 4.3e+0 )
354
355 CALL pcsepchk( n, n, copya, ia, ja, desca,
356 $
max( abstol+epsnorma, safmin ), thresh,
357 $ z( 1+iprepad ), ia, ja, desca, a( 1+iprepad ),
358 $ ia, ja, desca, wnew( 1+iprepad ),
359 $ rwork( 1+iprepad ), rsizechk, tstnrm, res )
360
361 CALL pschekpad( desca( ctxt_ ),
'PCSDPCHK-rWORK', rsizechk, 1,
362 $ rwork, rsizechk, iprepad, ipostpad, 4.3e+0 )
363
364 IF( res.NE.0 ) THEN
365 result = 1
366 WRITE( nout, fmt = 9995 )
367 END IF
368
369
370
371 CALL psfillpad( desca( ctxt_ ), rsizeqtq, 1, rwork, rsizeqtq,
372 $ iprepad, ipostpad, 4.3e+0 )
373
374
375 res = 0
376 ulp =
pslamch( desca( ctxt_ ),
'P' )
377 CALL pclaset(
'A', n, n, czero, cone, a( 1+iprepad ), ia, ja,
378 $ desca )
379 CALL pcgemm( 'Conjugate transpose', 'N', n, n, n, cnegone,
380 $ z( 1+iprepad ), ia, ja, desca, z( 1+iprepad ), ia,
381 $ ja, desca, cone, a( 1+iprepad ), ia, ja, desca )
382 norm =
pclange(
'1', n, n, a( 1+iprepad ), ia, ja, desca,
383 $ work( 1+iprepad ) )
384 qtqnrm = norm / ( real(
max( n, 1 ) )*ulp )
385 IF( qtqnrm.GT.thresh ) THEN
386 res = 1
387 END IF
388 CALL pschekpad( desca( ctxt_ ),
'PCSEPQTQ-rWORK', rsizeqtq, 1,
389 $ rwork, rsizeqtq, iprepad, ipostpad, 4.3e+0 )
390
391 IF( res.NE.0 ) THEN
392 result = 1
393 WRITE( nout, fmt = 9994 )
394 END IF
395
396 IF( info.NE.0 ) THEN
397 IF( iam.EQ.0 )
398 $ WRITE( nout, fmt = 9998 )info
399 result = 1
400 END IF
401
402 IF( info.NE.0 ) THEN
403 IF( iam.EQ.0 )
404 $ WRITE( nout, fmt = 9998 )info
405 result = 1
406 END IF
407 END IF
408
409
410
411 IF( wknown .AND. n.GT.0 ) THEN
412
413
414
415
416 minerror = normwin
417 maxerror = 0.0
418
419 DO 50 i = 1, n
420 error = abs( win( i+iprepad )-wnew( i+iprepad ) )
421 maxerror =
max( maxerror, error )
422 50 CONTINUE
423 minerror =
min( maxerror, minerror )
424
425 IF( minerror.GT.normwin*five*thresh*eps ) THEN
426 IF( iam.EQ.0 )
427 $ WRITE( nout, fmt = 9997 )minerror, normwin
428 result = 1
429 END IF
430 END IF
431
432
433
434
435 CALL igamx2d( desca( ctxt_ ), 'a', ' ', 1, 1, result, 1, 1, 1, -1,
436 $ -1, 0 )
437
438 60 CONTINUE
439
440 RETURN
441
442 9999 FORMAT( 'PCHEEVD returned INFO=', i7 )
443 9998 FORMAT( 'PCSEPQTQ returned INFO=', i7 )
444 9997 FORMAT( 'PCSDPSUBTST minerror =', d11.2, ' normwin=', d11.2 )
445 9996 FORMAT( 'PCHEEVD returned INFO=', i7,
446 $ ' despite adequate workspace' )
447 9995 FORMAT( 'PCHEEVD failed the |AQ -QE| test' )
448 9994 FORMAT( 'PCHEEVD failed the |QTQ -I| test' )
449
450
451
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pclaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
real function pslamch(ictxt, cmach)
subroutine pcchekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pcfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
subroutine pcheevd(jobz, uplo, n, a, ia, ja, desca, w, z, iz, jz, descz, work, lwork, rwork, lrwork, iwork, liwork, info)
real function pclange(norm, m, n, a, ia, ja, desca, work)
real function pclanhe(norm, uplo, n, a, ia, ja, desca, work)
subroutine pclasizesep(desca, iprepad, ipostpad, sizemqrleft, sizemqrright, sizeqrf, sizetms, rsizeqtq, rsizechk, sizeheevx, rsizeheevx, isizeheevx, sizeheevd, rsizeheevd, isizeheevd, sizesubtst, rsizesubtst, isizesubtst, sizetst, rsizetst, isizetst)
subroutine pcsepchk(ms, nv, a, ia, ja, desca, epsnorma, thresh, q, iq, jq, descq, c, ic, jc, descc, w, work, lwork, tstnrm, result)
subroutine pichekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pifillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
subroutine pschekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine psfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)