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 DOUBLE PRECISION ABSTOL, QTQNRM, THRESH, TSTNRM
18
19
20 INTEGER DESCA( * ), IWORK( * )
21 DOUBLE PRECISION RWORK( * ), WIN( * ), WNEW( * )
22 COMPLEX*16 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 DOUBLE PRECISION PADVAL, FIVE, NEGONE
162 parameter( padval = 13.5285d+0, five = 5.0d+0,
163 $ negone = -1.0d+0 )
164 COMPLEX*16 CPADVAL
165 parameter( cpadval = ( 13.989d+0, 1.93d+0 ) )
166 INTEGER IPADVAL
167 parameter( ipadval = 927 )
168 COMPLEX*16 CZERO, CONE, CNEGONE
169 parameter( czero = 0.0d+0, cone = 1.0d+0,
170 $ cnegone = -1.0d+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 DOUBLE PRECISION EPS, EPSNORMA, ERROR, MAXERROR, MINERROR, NORM,
181 $ NORMWIN, SAFMIN, ULP
182
183
184 INTEGER ITMP( 2 )
185
186
187
188 INTEGER NUMROC
189 DOUBLE PRECISION PZLANGE, PZLANHE, PDLAMCH
191
192
193 EXTERNAL blacs_gridinfo, zlacpy, igamn2d, igamx2d,
197
198
199 INTRINSIC abs,
max,
min, dble
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 pzlasizesep( 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 =
pdlamch( desca( ctxt_ ),
'Eps' )
216 safmin =
pdlamch( 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.3d+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.63d+0, 1.1d+0 )
231 30 CONTINUE
232
233 DO 40 i = 1, n
234 wnew( i+iprepad ) = 3.14159d+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 zlacpy( 'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
254 $ desca( lld_ ) )
255
256 CALL pzfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
257 $ ipostpad, cpadval )
258
259 CALL pzfillpad( desca( ctxt_ ), np, nq, z, desca( lld_ ), iprepad,
260 $ ipostpad, cpadval+1.0d+0 )
261
262 CALL pdfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
263 $ padval+2.0d+0 )
264
265 CALL pdfillpad( desca( ctxt_ ), lwork1, 1, rwork, lwork1, iprepad,
266 $ ipostpad, padval+4.0d+0 )
267
268 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
269 $ ipostpad, ipadval )
270
271 CALL pzfillpad( desca( ctxt_ ), lwork, 1, work, lwork, iprepad,
272 $ ipostpad, cpadval+4.1d+0 )
273
277
278 CALL pzheevd(
'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 pzchekpad( desca( ctxt_ ),
'PZHEEVD-A', np, nq, a,
289 $ desca( lld_ ), iprepad, ipostpad, cpadval )
290
291 CALL pzchekpad( desca( ctxt_ ),
'PZHEEVD-Z', np, nq, z,
292 $ desca( lld_ ), iprepad, ipostpad,
293 $ cpadval+1.0d+0 )
294
295 CALL pdchekpad( desca( ctxt_ ),
'PZHEEVD-WNEW', n, 1, wnew, n,
296 $ iprepad, ipostpad, padval+2.0d+0 )
297
298 CALL pdchekpad( desca( ctxt_ ),
'PZHEEVD-rWORK', lwork1, 1,
299 $ rwork, lwork1, iprepad, ipostpad,
300 $ padval+4.0d+0 )
301
302 CALL pzchekpad( desca( ctxt_ ),
'PZHEEVD-WORK', lwork, 1, work,
303 $ lwork, iprepad, ipostpad, cpadval+4.1d+0 )
304
305 CALL pichekpad( desca( ctxt_ ),
'PZHEEVD-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 =
pzlanhe(
'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 pdfillpad( desca( ctxt_ ), rsizechk, 1, rwork, rsizechk,
353 $ iprepad, ipostpad, 4.3d+0 )
354
355 CALL pzsepchk( 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 pdchekpad( desca( ctxt_ ),
'PZSDPCHK-rWORK', rsizechk, 1,
362 $ rwork, rsizechk, iprepad, ipostpad, 4.3d+0 )
363
364 IF( res.NE.0 ) THEN
365 result = 1
366 WRITE( nout, fmt = 9995 )
367 END IF
368
369
370
371 CALL pdfillpad( desca( ctxt_ ), rsizeqtq, 1, rwork, rsizeqtq,
372 $ iprepad, ipostpad, 4.3d+0 )
373
374
375 res = 0
376 ulp =
pdlamch( desca( ctxt_ ),
'P' )
377 CALL pzlaset(
'A', n, n, czero, cone, a( 1+iprepad ), ia, ja,
378 $ desca )
379 CALL pzgemm( '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 =
pzlange(
'1', n, n, a( 1+iprepad ), ia, ja, desca,
383 $ work( 1+iprepad ) )
384 qtqnrm = norm / ( dble(
max( n, 1 ) )*ulp )
385 IF( qtqnrm.GT.thresh ) THEN
386 res = 1
387 END IF
388 CALL pdchekpad( desca( ctxt_ ),
'PZSEPQTQ-rWORK', rsizeqtq, 1,
389 $ rwork, rsizeqtq, iprepad, ipostpad, 4.3d+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.0d+00
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( 'PZHEEVD returned INFO=', i7 )
443 9998 FORMAT( 'PZSEPQTQ returned INFO=', i7 )
444 9997 FORMAT( 'PZSDPSUBTST minerror =', d11.2, ' normwin=', d11.2 )
445 9996 FORMAT( 'PZHEEVD returned INFO=', i7,
446 $ ' despite adequate workspace' )
447 9995 FORMAT( 'PZHEEVD failed the |AQ -QE| test' )
448 9994 FORMAT( 'PZHEEVD failed the |QTQ -I| test' )
449
450
451
integer function numroc(n, nb, iproc, isrcproc, nprocs)
double precision function pdlamch(ictxt, cmach)
subroutine pdchekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pdfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
subroutine pichekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pifillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
subroutine pzlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pzchekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
subroutine pzfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
subroutine pzheevd(jobz, uplo, n, a, ia, ja, desca, w, z, iz, jz, descz, work, lwork, rwork, lrwork, iwork, liwork, info)
double precision function pzlange(norm, m, n, a, ia, ja, desca, work)
double precision function pzlanhe(norm, uplo, n, a, ia, ja, desca, work)
subroutine pzlasizesep(desca, iprepad, ipostpad, sizemqrleft, sizemqrright, sizeqrf, sizetms, rsizeqtq, rsizechk, sizeheevx, rsizeheevx, isizeheevx, sizeheevd, rsizeheevd, isizeheevd, sizesubtst, rsizesubtst, isizesubtst, sizetst, rsizetst, isizetst)
subroutine pzsepchk(ms, nv, a, ia, ja, desca, epsnorma, thresh, q, iq, jq, descq, c, ic, jc, descc, w, work, lwork, tstnrm, result)