3
4
5
6
7
8
9
10
11
12 IMPLICIT NONE
13
14
15 INTEGER IHI, ILO, INFO, LWORK, LIWORK, N
16 CHARACTER COMPZ, JOB
17
18
19 INTEGER DESCH( * ) , DESCZ( * ), IWORK( * )
20 DOUBLE PRECISION H( * ), WI( N ), WORK( * ), WR( N ), Z( * )
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
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
240 $ LLD_, MB_, M_, NB_, N_, RSRC_
241 LOGICAL CRSOVER
242 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
243 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
244 $ rsrc_ = 7, csrc_ = 8, lld_ = 9,
245 $ crsover = .true. )
246 INTEGER NTINY
247 parameter( ntiny = 11 )
248 INTEGER NL
249 parameter( nl = 49 )
250 DOUBLE PRECISION ZERO, ONE
251 parameter( zero = 0.0d0, one = 1.0d0 )
252
253
254 INTEGER I, KBOT, NMIN, LLDH, LLDZ, ICTXT, NPROW, NPCOL,
255 $ MYROW, MYCOL, HROWS, HCOLS, IPW, NH, NB,
256 $ II, JJ, HRSRC, HCSRC, NPROCS, ILOC1, JLOC1,
257 $ HRSRC1, HCSRC1, K, ILOC2, JLOC2, ILOC3, JLOC3,
258 $ ILOC4, JLOC4, HRSRC2, HCSRC2, HRSRC3, HCSRC3,
259 $ HRSRC4, HCSRC4, LIWKOPT
260 LOGICAL INITZ, LQUERY, WANTT, WANTZ, PAIR, BORDER
261 DOUBLE PRECISION TMP1, TMP2, TMP3, TMP4, DUM1, DUM2, DUM3,
262 $ DUM4, ELEM1, ELEM4,
263 $ CS, SN, ELEM5, TMP, LWKOPT
264
265
266 INTEGER DESCH2( DLEN_ )
267 DOUBLE PRECISION ELEM2( 1 ), ELEM3( 1 )
268
269
270 INTEGER PILAENVX, NUMROC, ICEIL
271 LOGICAL LSAME
273
274
276
277
279
280
281
282
283
284 info = 0
285 ictxt = desch( ctxt_ )
286 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
287 nprocs = nprow*npcol
288 IF( nprow.EQ.-1 ) info = -(600+ctxt_)
289 IF( info.EQ.0 ) THEN
290 wantt =
lsame( job,
'S' )
291 initz =
lsame( compz,
'I' )
292 wantz = initz .OR.
lsame( compz,
'V' )
293 lldh = desch( lld_ )
294 lldz = descz( lld_ )
295 nb = desch( mb_ )
296 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
297
298 IF( .NOT.
lsame( job,
'E' ) .AND. .NOT.wantt )
THEN
299 info = -1
300 ELSE IF( .NOT.
lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
301 info = -2
302 ELSE IF( n.LT.0 ) THEN
303 info = -3
304 ELSE IF( ilo.LT.1 .OR. ilo.GT.
max( 1, n ) )
THEN
305 info = -4
306 ELSE IF( ihi.LT.
min( ilo, n ) .OR. ihi.GT.n )
THEN
307 info = -5
308 ELSEIF( descz( ctxt_ ).NE.desch( ctxt_ ) ) THEN
309 info = -( 1000+ctxt_ )
310 ELSEIF( desch( mb_ ).NE.desch( nb_ ) ) THEN
311 info = -( 700+nb_ )
312 ELSEIF( descz( mb_ ).NE.descz( nb_ ) ) THEN
313 info = -( 1000+nb_ )
314 ELSEIF( desch( mb_ ).NE.descz( mb_ ) ) THEN
315 info = -( 1000+mb_ )
316 ELSEIF( desch( mb_ ).LT.6 ) THEN
317 info = -( 700+nb_ )
318 ELSEIF( descz( mb_ ).LT.6 ) THEN
319 info = -( 1000+mb_ )
320 ELSE
321 CALL chk1mat( n, 3, n, 3, 1, 1, desch, 7, info )
322 IF( info.EQ.0 )
323 $
CALL chk1mat( n, 3, n, 3, 1, 1, descz, 11, info )
324 IF( info.EQ.0 )
325 $
CALL pchk2mat( n, 3, n, 3, 1, 1, desch, 7, n, 3, n, 3,
326 $ 1, 1, descz, 11, 0, iwork, iwork, info )
327 END IF
328 END IF
329
330
331
332 CALL pdlaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
333 $ ilo, ihi, z, descz, work, -1, iwork, -1, info )
334 lwkopt = work(1)
335 liwkopt = iwork(1)
336 CALL pdlaqr0( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
337 $ ilo, ihi, z, descz, work, -1, iwork, -1, info, 0 )
338 IF( n.LT.nl ) THEN
339 hrows =
numroc( nl, nb, myrow, desch(rsrc_), nprow )
340 hcols =
numroc( nl, nb, mycol, desch(csrc_), npcol )
341 work(1) = work(1) + dble(2*hrows*hcols)
342 END IF
343 lwkopt =
max( lwkopt, work(1) )
344 liwkopt =
max( liwkopt, iwork(1) )
345 work(1) = lwkopt
346 iwork(1) = liwkopt
347
348 IF( .NOT.lquery .AND. lwork.LT.int(lwkopt) ) THEN
349 info = -13
350 ELSEIF( .NOT.lquery .AND. liwork.LT.liwkopt ) THEN
351 info = -15
352 END IF
353
354 IF( info.NE.0 ) THEN
355
356
357
358 CALL pxerbla( ictxt,
'PDHSEQR', -info )
359 RETURN
360
361 ELSE IF( n.EQ.0 ) THEN
362
363
364
365 RETURN
366
367 ELSE IF( lquery ) THEN
368
369
370
371 RETURN
372
373 ELSE
374
375
376
377 DO 10 i = 1, ilo - 1
378 CALL infog2l( i, i, desch, nprow, npcol, myrow, mycol, ii,
379 $ jj, hrsrc, hcsrc )
380 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc ) THEN
381 wr( i ) = h( (jj-1)*lldh + ii )
382 ELSE
383 wr( i ) = zero
384 END IF
385 wi( i ) = zero
386 10 CONTINUE
387 IF( ilo.GT.1 )
388 $ CALL dgsum2d( ictxt, 'All', '1-Tree', ilo-1, 1, wr, n, -1,
389 $ -1 )
390 DO 20 i = ihi + 1, n
391 CALL infog2l( i, i, desch, nprow, npcol, myrow, mycol, ii,
392 $ jj, hrsrc, hcsrc )
393 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc ) THEN
394 wr( i ) = h( (jj-1)*lldh + ii )
395 ELSE
396 wr( i ) = zero
397 END IF
398 wi( i ) = zero
399 20 CONTINUE
400 IF( ihi.LT.n )
401 $ CALL dgsum2d( ictxt, 'All', '1-Tree', n-ihi, 1, wr(ihi+1),
402 $ n, -1, -1 )
403
404
405
406 IF( initz )
407 $
CALL pdlaset(
'A', n, n, zero, one, z, 1, 1, descz )
408
409
410
411 nprocs = nprow*npcol
412 IF( ilo.EQ.ihi ) THEN
413 CALL infog2l( ilo, ilo, desch, nprow, npcol, myrow,
414 $ mycol, ii, jj, hrsrc, hcsrc )
415 IF( myrow.EQ.hrsrc .AND. mycol.EQ.hcsrc ) THEN
416 wr( ilo ) = h( (jj-1)*lldh + ii )
417 IF( nprocs.GT.1 )
418 $ CALL dgebs2d( ictxt, 'All', '1-Tree', 1, 1, wr(ilo),
419 $ 1 )
420 ELSE
421 CALL dgebr2d( ictxt, 'All', '1-Tree', 1, 1, wr(ilo),
422 $ 1, hrsrc, hcsrc )
423 END IF
424 wi( ilo ) = zero
425 RETURN
426 END IF
427
428
429
430 nh = ihi-ilo+1
431 nmin =
pilaenvx( ictxt, 12,
'PDHSEQR',
432 $ job( : 1 ) // compz( : 1 ), n, ilo, ihi, lwork )
433 nmin =
max( ntiny, nmin )
434
435
436
437 IF( (.NOT. crsover .AND. nh.GT.ntiny) .OR. nh.GT.nmin .OR.
438 $ desch(rsrc_).NE.0 .OR. desch(csrc_).NE.0 ) THEN
439 CALL pdlaqr0( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
440 $ ilo, ihi, z, descz, work, lwork, iwork, liwork, info,
441 $ 0 )
442 IF( info.GT.0 .AND. ( desch(rsrc_).NE.0 .OR.
443 $ desch(csrc_).NE.0 ) ) THEN
444
445
446
447
448 kbot = info
449 CALL pdlaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr,
450 $ wi, ilo, ihi, z, descz, work, lwork, iwork,
451 $ liwork, info )
452 info = -7777
453 END IF
454 ELSE
455
456
457
458 CALL pdlaqr1( wantt, wantz, n, ilo, ihi, h, desch, wr, wi,
459 $ ilo, ihi, z, descz, work, lwork, iwork, liwork, info )
460
461 IF( info.GT.0 ) THEN
462
463
464
465
466 kbot = info
467
468 IF( n.GE.nl ) THEN
469
470
471
472
473 CALL pdlaqr0( wantt, wantz, n, ilo, kbot, h, desch,
474 $ wr, wi, ilo, ihi, z, descz, work, lwork,
475 $ iwork, liwork, info, 0 )
476 ELSE
477
478
479
480
481
482
483 hrows =
numroc( nl, nb, myrow, desch(rsrc_), nprow )
484 hcols =
numroc( nl, nb, mycol, desch(csrc_), npcol )
485 CALL descinit( desch2, nl, nl, nb, nb, desch(rsrc_),
486 $ desch(csrc_), ictxt,
max(1, hrows), info )
487 CALL pdlacpy(
'All', n, n, h, 1, 1, desch, work, 1,
488 $ 1, desch2 )
489 CALL pdelset( work, n+1, n, desch2, zero )
490 CALL pdlaset(
'All', nl, nl-n, zero, zero, work, 1,
491 $ n+1, desch2 )
492 ipw = 1 + desch2(lld_)*hcols
493 CALL pdlaqr0( wantt, wantz, nl, ilo, kbot, work,
494 $ desch2, wr, wi, ilo, ihi, z, descz,
495 $ work(ipw), lwork-ipw+1, iwork,
496 $ liwork, info, 0 )
497 IF( wantt .OR. info.NE.0 )
498 $
CALL pdlacpy(
'All', n, n, work, 1, 1, desch2,
499 $ h, 1, 1, desch )
500 END IF
501 info = -8888
502 END IF
503 END IF
504
505
506
507 IF( ( wantt .OR. info.NE.0 ) .AND. n.GT.2 )
508 $
CALL pdlaset(
'L', n-2, n-2, zero, zero, h, 3, 1, desch )
509
510
511
512
513 DO 30 i = ilo, ihi-1
514 CALL pdelget(
'All',
' ', tmp3, h, i+1, i, desch )
515 IF( tmp3.NE.0.0d+00 ) THEN
516 CALL pdelget(
'All',
' ', tmp1, h, i, i, desch )
517 CALL pdelget(
'All',
' ', tmp2, h, i, i+1, desch )
518 CALL pdelget(
'All',
' ', tmp4, h, i+1, i+1, desch )
519 CALL dlanv2( tmp1, tmp2, tmp3, tmp4, dum1, dum2, dum3,
520 $ dum4, cs, sn )
521 IF( tmp3.EQ.0.0d+00 ) THEN
522 IF( wantt ) THEN
523 IF( i+2.LE.n )
524 $
CALL pdrot( n-i-1, h, i, i+2, desch,
525 $ desch(m_), h, i+1, i+2, desch, desch(m_),
526 $ cs, sn, work, lwork, info )
527 CALL pdrot( i-1, h, 1, i, desch, 1, h, 1, i+1,
528 $ desch, 1, cs, sn, work, lwork, info )
529 END IF
530 IF( wantz ) THEN
531 CALL pdrot( n, z, 1, i, descz, 1, z, 1, i+1, descz,
532 $ 1, cs, sn, work, lwork, info )
533 END IF
534 CALL pdelset( h, i, i, desch, tmp1 )
535 CALL pdelset( h, i, i+1, desch, tmp2 )
536 CALL pdelset( h, i+1, i, desch, tmp3 )
537 CALL pdelset( h, i+1, i+1, desch, tmp4 )
538 END IF
539 END IF
540 30 CONTINUE
541
542
543
544
545
546
547
548
549 DO 40 k = ilo, ihi
550 wr( k ) = zero
551 wi( k ) = zero
552 40 CONTINUE
553 nb = desch( mb_ )
554
555
556
557
558
559 pair = .false.
560 DO 50 k = ilo, ihi
561 IF( .NOT. pair ) THEN
562 border = mod( k, nb ).EQ.0 .OR. ( k.NE.1 .AND.
563 $ mod( k, nb ).EQ.1 )
564 IF( .NOT. border ) THEN
565 CALL infog2l( k, k, desch, nprow, npcol, myrow,
566 $ mycol, iloc1, jloc1, hrsrc1, hcsrc1 )
567 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 ) THEN
568 elem1 = h((jloc1-1)*lldh+iloc1)
569 IF( k.LT.n ) THEN
570 elem3( 1 ) = h((jloc1-1)*lldh+iloc1+1)
571 ELSE
572 elem3( 1 ) = zero
573 END IF
574 IF( elem3( 1 ).NE.zero ) THEN
575 elem2( 1 ) = h((jloc1)*lldh+iloc1)
576 elem4 = h((jloc1)*lldh+iloc1+1)
577 CALL dlanv2( elem1, elem2( 1 ), elem3( 1 ),
578 $ elem4, wr( k ), wi( k ), wr( k+1 ),
579 $ wi( k+1 ), sn, cs )
580 pair = .true.
581 ELSE
582 IF( k.GT.1 ) THEN
583 tmp = h((jloc1-2)*lldh+iloc1)
584 IF( tmp.NE.zero ) THEN
585 elem1 = h((jloc1-2)*lldh+iloc1-1)
586 elem2( 1 ) = h((jloc1-1)*lldh+iloc1-1)
587 elem3( 1 ) = h((jloc1-2)*lldh+iloc1)
588 elem4 = h((jloc1-1)*lldh+iloc1)
589 CALL dlanv2( elem1, elem2( 1 ),
590 $ elem3( 1 ), elem4, wr( k-1 ),
591 $ wi( k-1 ), wr( k ), wi( k ), sn, cs )
592 ELSE
593 wr( k ) = elem1
594 END IF
595 ELSE
596 wr( k ) = elem1
597 END IF
598 END IF
599 END IF
600 END IF
601 ELSE
602 pair = .false.
603 END IF
604 50 CONTINUE
605
606
607
608
609
610
611
612
613
614 DO 60 k =
iceil(ilo,nb)*nb, ihi-1, nb
615 CALL infog2l( k, k, desch, nprow, npcol, myrow, mycol,
616 $ iloc1, jloc1, hrsrc1, hcsrc1 )
617 CALL infog2l( k, k+1, desch, nprow, npcol, myrow, mycol,
618 $ iloc2, jloc2, hrsrc2, hcsrc2 )
619 CALL infog2l( k+1, k, desch, nprow, npcol, myrow, mycol,
620 $ iloc3, jloc3, hrsrc3, hcsrc3 )
621 CALL infog2l( k+1, k+1, desch, nprow, npcol, myrow, mycol,
622 $ iloc4, jloc4, hrsrc4, hcsrc4 )
623 IF( myrow.EQ.hrsrc2 .AND. mycol.EQ.hcsrc2 ) THEN
624 elem2( 1 ) = h((jloc2-1)*lldh+iloc2)
625 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
626 $ CALL dgesd2d( ictxt, 1, 1, elem2, 1, hrsrc1, hcsrc1)
627 END IF
628 IF( myrow.EQ.hrsrc3 .AND. mycol.EQ.hcsrc3 ) THEN
629 elem3( 1 ) = h((jloc3-1)*lldh+iloc3)
630 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
631 $ CALL dgesd2d( ictxt, 1, 1, elem3, 1, hrsrc1, hcsrc1)
632 END IF
633 IF( myrow.EQ.hrsrc4 .AND. mycol.EQ.hcsrc4 ) THEN
634 work(1) = h((jloc4-1)*lldh+iloc4)
635 IF( k+1.LT.n ) THEN
636 work(2) = h((jloc4-1)*lldh+iloc4+1)
637 ELSE
638 work(2) = zero
639 END IF
640 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
641 $ CALL dgesd2d( ictxt, 2, 1, work, 2, hrsrc1, hcsrc1 )
642 END IF
643 IF( myrow.EQ.hrsrc1 .AND. mycol.EQ.hcsrc1 ) THEN
644 elem1 = h((jloc1-1)*lldh+iloc1)
645 IF( hrsrc1.NE.hrsrc2 .OR. hcsrc1.NE.hcsrc2 )
646 $ CALL dgerv2d( ictxt, 1, 1, elem2, 1, hrsrc2, hcsrc2)
647 IF( hrsrc1.NE.hrsrc3 .OR. hcsrc1.NE.hcsrc3 )
648 $ CALL dgerv2d( ictxt, 1, 1, elem3, 1, hrsrc3, hcsrc3)
649 IF( hrsrc1.NE.hrsrc4 .OR. hcsrc1.NE.hcsrc4 )
650 $ CALL dgerv2d( ictxt, 2, 1, work, 2, hrsrc4, hcsrc4 )
651 elem4 = work(1)
652 elem5 = work(2)
653 IF( elem5.EQ.zero ) THEN
654 IF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero ) THEN
655 CALL dlanv2( elem1, elem2( 1 ), elem3( 1 ), elem4,
656 $ wr( k ), wi( k ), wr( k+1 ), wi( k+1 ), sn,
657 $ cs )
658 ELSEIF( wr( k+1 ).EQ.zero .AND. wi( k+1 ).EQ.zero )
659 $ THEN
660 wr( k+1 ) = elem4
661 END IF
662 ELSEIF( wr( k ).EQ.zero .AND. wi( k ).EQ.zero )
663 $ THEN
664 wr( k ) = elem1
665 END IF
666 END IF
667 60 CONTINUE
668
669 IF( nprocs.GT.1 ) THEN
670 CALL dgsum2d( ictxt, 'All', ' ', ihi-ilo+1, 1, wr(ilo), n,
671 $ -1, -1 )
672 CALL dgsum2d( ictxt, 'All', ' ', ihi-ilo+1, 1, wi(ilo), n,
673 $ -1, -1 )
674 END IF
675
676 END IF
677
678 work(1) = lwkopt
679 iwork(1) = liwkopt
680 RETURN
681
682
683
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descinit(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld, info)
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pdelget(scope, top, alpha, a, ia, ja, desca)
subroutine pdelset(a, ia, ja, desca, alpha)
subroutine pdlacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
recursive subroutine pdlaqr0(wantt, wantz, n, ilo, ihi, h, desch, wr, wi, iloz, ihiz, z, descz, work, lwork, iwork, liwork, info, reclevel)
recursive subroutine pdlaqr1(wantt, wantz, n, ilo, ihi, a, desca, wr, wi, iloz, ihiz, z, descz, work, lwork, iwork, ilwork, info)
subroutine pdrot(n, x, ix, jx, descx, incx, y, iy, jy, descy, incy, cs, sn, work, lwork, info)
integer function pilaenvx(ictxt, ispec, name, opts, n1, n2, n3, n4)
subroutine pxerbla(ictxt, srname, info)