6
7
8
9
10
11
12
13 CHARACTER JOBZ, RANGE, UPLO
14 INTEGER IA, IB, IBTYPE, IL, INFO, IU, IZ, JA, JB, JZ,
15 $ LIWORK, LWORK, M, N, NZ
16 DOUBLE PRECISION ABSTOL, ORFAC, VL, VU
17
18
19
20 INTEGER DESCA( * ), DESCB( * ), DESCZ( * ),
21 $ ICLUSTR( * ), IFAIL( * ), IWORK( * )
22 DOUBLE PRECISION A( * ), B( * ), GAP( * ), W( * ), WORK( * ),
23 $ 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
490 $ MB_, NB_, RSRC_, CSRC_, LLD_
491 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
492 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
493 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
494 DOUBLE PRECISION ONE
495 parameter( one = 1.0d+0 )
496 DOUBLE PRECISION FIVE, ZERO
497 parameter( five = 5.0d+0, zero = 0.0d+0 )
498 INTEGER IERRNPD
499 parameter( ierrnpd = 16 )
500
501
502 LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
503 CHARACTER TRANS
504 INTEGER ANB, IACOL, IAROW, IBCOL, IBROW, ICOFFA,
505 $ ICOFFB, ICTXT, IROFFA, IROFFB, LIWMIN, LWMIN,
506 $ LWOPT, MQ0, MYCOL, , NB, NEIG, NN, NP0,
507 $ NPCOL, NPROW, NPS, NQ0, NSYGST_LWOPT,
508 $ NSYTRD_LWOPT, SQNPC
509 DOUBLE PRECISION EPS, SCALE
510
511
512 INTEGER IDUM1( 5 ), IDUM2( 5 )
513
514
515 LOGICAL LSAME
516 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
517 DOUBLE PRECISION PDLAMCH
519
520
523 $
524
525
526 INTRINSIC abs, dble, ichar, int,
max,
min, mod, sqrt
527
528
529
530 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
531 $ rsrc_.LT.0 )RETURN
532
533
534
535 ictxt = desca( ctxt_ )
537
538
539
540 info = 0
541 IF( nprow.EQ.-1 ) THEN
542 info = -( 900+ctxt_ )
543 ELSE IF( desca( ctxt_ ).NE.descb( ctxt_ ) ) THEN
544 info = -( 1300+ctxt_ )
545 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) ) THEN
546 info = -( 2600+ctxt_ )
547 ELSE
548
549
550
551 eps =
pdlamch( desca( ctxt_ ),
'Precision' )
552
553 wantz =
lsame( jobz,
'V' )
554 upper =
lsame( uplo,
'U' )
555 alleig =
lsame( range, 'a
' )
556 VALEIG = LSAME( RANGE, 'v' )
557 INDEIG = LSAME( RANGE, 'i' )
558 CALL CHK1MAT( N, 4, N, 4, IA, JA, DESCA, 9, INFO )
559 CALL CHK1MAT( N, 4, N, 4, IB, JB, DESCB, 13, INFO )
560 CALL CHK1MAT( N, 4, N, 4, IZ, JZ, DESCZ, 26, INFO )
561.EQ. IF( INFO0 ) THEN
562.EQ..AND..EQ. IF( MYROW0 MYCOL0 ) THEN
563 WORK( 1 ) = ABSTOL
564 IF( VALEIG ) THEN
565 WORK( 2 ) = VL
566 WORK( 3 ) = VU
567 ELSE
568 WORK( 2 ) = ZERO
569 WORK( 3 ) = ZERO
570 END IF
571 CALL DGEBS2D( DESCA( CTXT_ ), 'all', ' ', 3, 1, WORK, 3 )
572 ELSE
573 CALL DGEBR2D( DESCA( CTXT_ ), 'all', ' ', 3, 1, WORK, 3,
574 $ 0, 0 )
575 END IF
576 IAROW = INDXG2P( IA, DESCA( MB_ ), MYROW, DESCA( RSRC_ ),
577 $ NPROW )
578 IBROW = INDXG2P( IB, DESCB( MB_ ), MYROW, DESCB( RSRC_ ),
579 $ NPROW )
580 IACOL = INDXG2P( JA, DESCA( NB_ ), MYCOL, DESCA( CSRC_ ),
581 $ NPCOL )
582 IBCOL = INDXG2P( JB, DESCB( NB_ ), MYCOL, DESCB( CSRC_ ),
583 $ NPCOL )
584 IROFFA = MOD( IA-1, DESCA( MB_ ) )
585 ICOFFA = MOD( JA-1, DESCA( NB_ ) )
586 IROFFB = MOD( IB-1, DESCB( MB_ ) )
587 ICOFFB = MOD( JB-1, DESCB( NB_ ) )
588
589
590
591 LQUERY = .FALSE.
592.EQ..OR..EQ. IF( LWORK-1 LIWORK-1 )
593 $ LQUERY = .TRUE.
594
595 LIWMIN = 6*MAX( N, ( NPROW*NPCOL )+1, 4 )
596
597 NB = DESCA( MB_ )
598 NN = MAX( N, NB, 2 )
599 NP0 = NUMROC( NN, NB, 0, 0, NPROW )
600
601.NOT..OR..AND..NOT. IF( ( WANTZ ) ( VALEIG ( LQUERY ) ) )
602 $ THEN
603 LWMIN = 5*N + MAX( 5*NN, NB*( NP0+1 ) )
604 IF( WANTZ ) THEN
605 MQ0 = NUMROC( MAX( N, NB, 2 ), NB, 0, 0, NPCOL )
606 LWOPT = 5*N + MAX( 5*NN, NP0*MQ0+2*NB*NB )
607 ELSE
608 LWOPT = LWMIN
609 END IF
610 NEIG = 0
611 ELSE
612.OR. IF( ALLEIG VALEIG ) THEN
613 NEIG = N
614 ELSE IF( INDEIG ) THEN
615 NEIG = IU - IL + 1
616 END IF
617 MQ0 = NUMROC( MAX( NEIG, NB, 2 ), NB, 0, 0, NPCOL )
618 LWMIN = 5*N + MAX( 5*NN, NP0*MQ0+2*NB*NB ) +
619 $ ICEIL( NEIG, NPROW*NPCOL )*NN
620 LWOPT = LWMIN
621
622 END IF
623
624
625
626
627 ANB = PJLAENV( ICTXT, 3, 'pdsyttrd', 'l
', 0, 0, 0, 0 )
628 SQNPC = INT( SQRT( DBLE( NPROW*NPCOL ) ) )
629 NPS = MAX( NUMROC( N, 1, 0, 0, SQNPC ), 2*ANB )
630 NSYTRD_LWOPT = 2*( ANB+1 )*( 4*NPS+2 ) + ( NPS+4 )*NPS
631 NB = DESCA( MB_ )
632 NP0 = NUMROC( N, NB, 0, 0, NPROW )
633 NQ0 = NUMROC( N, NB, 0, 0, NPCOL )
634 NSYGST_LWOPT = 2*NP0*NB + NQ0*NB + NB*NB
635 LWOPT = MAX( LWOPT, N+NSYTRD_LWOPT, NSYGST_LWOPT )
636
637
638
639.LT..OR..GT. IF( IBTYPE1 IBTYPE3 ) THEN
640 INFO = -1
641.NOT..OR. ELSE IF( ( WANTZ LSAME( JOBZ, 'n' ) ) ) THEN
642 INFO = -2
643.NOT..OR..OR. ELSE IF( ( ALLEIG VALEIG INDEIG ) ) THEN
644 INFO = -3
645.NOT..AND..NOT. ELSE IF( UPPER LSAME( UPLO, 'l' ) ) THEN
646 INFO = -4
647.LT. ELSE IF( N0 ) THEN
648 INFO = -5
649.NE. ELSE IF( IROFFA0 ) THEN
650 INFO = -7
651.NE. ELSE IF( ICOFFA0 ) THEN
652 INFO = -8
653.NE. ELSE IF( DESCA( MB_ )DESCA( NB_ ) ) THEN
654 INFO = -( 900+NB_ )
655.NE. ELSE IF( DESCA( M_ )DESCB( M_ ) ) THEN
656 INFO = -( 1300+M_ )
657.NE. ELSE IF( DESCA( N_ )DESCB( N_ ) ) THEN
658 INFO = -( 1300+N_ )
659.NE. ELSE IF( DESCA( MB_ )DESCB( MB_ ) ) THEN
660 INFO = -( 1300+MB_ )
661.NE. ELSE IF( DESCA( NB_ )DESCB( NB_ ) ) THEN
662 INFO = -( 1300+NB_ )
663.NE. ELSE IF( DESCA( RSRC_ )DESCB( RSRC_ ) ) THEN
664 INFO = -( 1300+RSRC_ )
665.NE. ELSE IF( DESCA( CSRC_ )DESCB( CSRC_ ) ) THEN
666 INFO = -( 1300+CSRC_ )
667.NE. ELSE IF( DESCA( CTXT_ )DESCB( CTXT_ ) ) THEN
668 INFO = -( 1300+CTXT_ )
669.NE. ELSE IF( DESCA( M_ )DESCZ( M_ ) ) THEN
670 INFO = -( 2200+M_ )
671.NE. ELSE IF( DESCA( N_ )DESCZ( N_ ) ) THEN
672 INFO = -( 2200+N_ )
673.NE. ELSE IF( DESCA( MB_ )DESCZ( MB_ ) ) THEN
674 INFO = -( 2200+MB_ )
675.NE. ELSE IF( DESCA( NB_ )DESCZ( NB_ ) ) THEN
676 INFO = -( 2200+NB_ )
677.NE. ELSE IF( DESCA( RSRC_ )DESCZ( RSRC_ ) ) THEN
678 INFO = -( 2200+RSRC_ )
679.NE. ELSE IF( DESCA( CSRC_ )DESCZ( CSRC_ ) ) THEN
680 INFO = -( 2200+CSRC_ )
681.NE. ELSE IF( DESCA( CTXT_ )DESCZ( CTXT_ ) ) THEN
682 INFO = -( 2200+CTXT_ )
683.NE..OR..NE. ELSE IF( IROFFB0 IBROWIAROW ) THEN
684 INFO = -11
685.NE..OR..NE. ELSE IF( ICOFFB0 IBCOLIACOL ) THEN
686 INFO = -12
687.AND..GT..AND..LE. ELSE IF( VALEIG N0 VUVL ) THEN
688 INFO = -15
689.AND..LT..OR..GT. ELSE IF( INDEIG ( IL1 ILMAX( 1, N ) ) )
690 $ THEN
691 INFO = -16
692.AND..LT..OR..GT. ELSE IF( INDEIG ( IUMIN( N, IL ) IUN ) )
693 $ THEN
694 INFO = -17
695.AND..GT. ELSE IF( VALEIG ( ABS( WORK( 2 )-VL )FIVE*EPS*
696 $ ABS( VL ) ) ) THEN
697 INFO = -14
698.AND..GT. ELSE IF( VALEIG ( ABS( WORK( 3 )-VU )FIVE*EPS*
699 $ ABS( VU ) ) ) THEN
700 INFO = -15
701.GT. ELSE IF( ABS( WORK( 1 )-ABSTOL )FIVE*EPS*ABS( ABSTOL ) )
702 $ THEN
703 INFO = -18
704.LT..AND..NOT. ELSE IF( LWORKLWMIN LQUERY ) THEN
705 INFO = -28
706.LT..AND..NOT. ELSE IF( LIWORKLIWMIN LQUERY ) THEN
707 INFO = -30
708 END IF
709 END IF
710 IDUM1( 1 ) = IBTYPE
711 IDUM2( 1 ) = 1
712 IF( WANTZ ) THEN
713 IDUM1( 2 ) = ICHAR( 'v' )
714 ELSE
715 IDUM1( 2 ) = ICHAR( 'n' )
716 END IF
717 IDUM2( 2 ) = 2
718 IF( UPPER ) THEN
719 IDUM1( 3 ) = ICHAR( 'u' )
720 ELSE
721 IDUM1( 3 ) = ICHAR( 'l' )
722 END IF
723 IDUM2( 3 ) = 3
724 IF( ALLEIG ) THEN
725 IDUM1( 4 ) = ICHAR( 'a' )
726 ELSE IF( INDEIG ) THEN
727 IDUM1( 4 ) = ICHAR( 'i' )
728 ELSE
729 IDUM1( 4 ) = ICHAR( 'v' )
730 END IF
731 IDUM2( 4 ) = 4
732 IF( LQUERY ) THEN
733 IDUM1( 5 ) = -1
734 ELSE
735 IDUM1( 5 ) = 1
736 END IF
737 IDUM2( 5 ) = 5
738 CALL PCHK2MAT( N, 4, N, 4, IA, JA, DESCA, 9, N, 4, N, 4, IB,
739 $ JB, DESCB, 13, 5, IDUM1, IDUM2, INFO )
740 CALL PCHK1MAT( N, 4, N, 4, IZ, JZ, DESCZ, 26, 0, IDUM1, IDUM2,
741 $ INFO )
742 END IF
743
744 IWORK( 1 ) = LIWMIN
745 WORK( 1 ) = DBLE( LWOPT )
746
747.NE. IF( INFO0 ) THEN
748 CALL PXERBLA( ICTXT, 'pdsygvx ', -INFO )
749 RETURN
750 ELSE IF( LQUERY ) THEN
751 RETURN
752 END IF
753
754
755
756 CALL PDPOTRF( UPLO, N, B, IB, JB, DESCB, INFO )
757.NE. IF( INFO0 ) THEN
758 IWORK( 1 ) = LIWMIN
759 WORK( 1 ) = DBLE( LWOPT )
760 IFAIL( 1 ) = INFO
761 INFO = IERRNPD
762 RETURN
763 END IF
764
765
766
767 CALL PDSYNGST( IBTYPE, UPLO, N, A, IA, JA, DESCA, B, IB, JB,
768 $ DESCB, SCALE, WORK, LWORK, INFO )
769 CALL PDSYEVX( JOBZ, RANGE, UPLO, N, A, IA, JA, DESCA, VL, VU, IL,
770 $ IU, ABSTOL, M, NZ, W, ORFAC, Z, IZ, JZ, DESCZ, WORK,
771 $ LWORK, IWORK, LIWORK, IFAIL, ICLUSTR, GAP, INFO )
772
773 IF( WANTZ ) THEN
774
775
776
777 NEIG = M
778.EQ..OR..EQ. IF( IBTYPE1 IBTYPE2 ) THEN
779
780
781
782
783
784 IF( UPPER ) THEN
785 TRANS = 'n'
786 ELSE
787 TRANS = 't'
788 END IF
789
790 CALL PDTRSM( 'left', UPLO, TRANS, 'non-unit', N, NEIG, ONE,
791 $ B, IB, JB, DESCB, Z, IZ, JZ, DESCZ )
792
793.EQ. ELSE IF( IBTYPE3 ) THEN
794
795
796
797
798 IF( UPPER ) THEN
799 TRANS = 't'
800 ELSE
801 TRANS = 'n'
802 END IF
803
804 CALL PDTRMM( 'left', UPLO, TRANS, 'non-unit', N, NEIG, ONE,
805 $ B, IB, JB, DESCB, Z, IZ, JZ, DESCZ )
806 END IF
807 END IF
808
809.NE. IF( SCALEONE ) THEN
810 CALL DSCAL( N, SCALE, W, 1 )
811 END IF
812
813 IWORK( 1 ) = LIWMIN
814 WORK( 1 ) = DBLE( LWOPT )
815 RETURN
816
817
818
logical function lsame(ca, cb)
LSAME
subroutine dscal(n, da, dx, incx)
DSCAL
integer function iceil(inum, idenom)
subroutine dgebs2d(contxt, scope, top, m, n, a, lda)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine pxerbla(contxt, srname, info)
subroutine pdpotrf(uplo, n, a, ia, ja, desca, info)
subroutine dgebr2d(contxt, scope, top, m, n, a, lda)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pdtrsm(side, uplo, transa, diag, m, n, alpha, a, ia, ja, desca, b, ib, jb, descb)
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
double precision function pdlamch(ictxt, cmach)
subroutine pdsyevx(jobz, range, uplo, n, a, ia, ja, desca, vl, vu, il, iu, abstol, m, nz, w, orfac, z, iz, jz, descz, work, lwork, iwork, liwork, ifail, iclustr, gap, info)
subroutine pdsygvx(ibtype, jobz, range, uplo, n, a, ia, ja, desca, b, ib, jb, descb, vl, vu, il, iu, abstol, m, nz, w, orfac, z, iz, jz, descz, work, lwork, iwork, liwork, ifail, iclustr, gap, info)
subroutine pdsyngst(ibtype, uplo, n, a, ia, ja, desca, b, ib, jb, descb, scale, work, lwork, info)
subroutine pdsyttrd(uplo, n, a, ia, ja, desca, d, e, tau, work, lwork, info)
integer function pjlaenv(ictxt, ispec, name, opts, n1, n2, n3, n4)