1 SUBROUTINE pdlaqr4( WANTT, WANTZ, N, ILO, IHI, A, DESCA, WR, WI,
2 $ ILOZ, IHIZ, Z, DESCZ, T, LDT, V, LDV, WORK,
16 INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDT, LDV, LWORK, N
19 INTEGER DESCA( * ), DESCZ( * )
20 DOUBLE PRECISION A( * ), T( LDT, * ), V( LDV, * ), ( * ),
21 $ work( * ), wr( * ), z
196 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
197 $ LLD_, MB_, M_, NB_, N_, RSRC_
198 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
199 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
200 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
201 DOUBLE PRECISION ZERO, ONE
202 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
205 INTEGER CONTXT, HBL, I, I1, I2, IAFIRST, ICOL, ICOL1,
206 $ ICOL2, II, IROW, IROW1, IROW2, ITMP1, ITMP2,
207 $ ierr, j, jafirst, jj, k, l, lda, ldz, lldtmp,
208 $ mycol, myrow, node, npcol, nprow, nh, nmin, nz,
209 $ hstep, vstep, kkrow, kkcol, kln, ltop, left,
210 $ right, up, down, d1, d2
213 INTEGER DESCT( 9 ), DESCV( 9 ), DESCWH( 9 ),
217 INTEGER NUMROC, ILAENV
223 $
dgemm, dlamov, dgesd2d, dgerv2d,
235 IF( n.EQ.0 .OR. nh.EQ.0 )
241 contxt = desca( ctxt_ )
243 iafirst = desca( rsrc_ )
244 jafirst = desca( csrc_ )
247 node = myrow*npcol + mycol
248 left = mod( mycol+npcol-1, npcol )
249 right = mod( mycol+1, npcol )
250 up = mod( myrow+nprow-1, nprow )
251 down = mod( myrow+1, nprow )
270 CALL infog2l( ilo, ilo, desca, nprow, npcol, myrow, mycol,
271 $ irow, icol, ii, jj )
272 IF ( myrow .EQ. ii )
THEN
273 CALL descinit( desct, nh, nh, nh, nh, ii, jj, contxt,
275 CALL descinit( descv, nh, nh, nh, nh, ii, jj, contxt,
278 CALL descinit( desct, nh, nh, nh, nh, ii, jj, contxt,
280 CALL descinit( descv, nh, nh, nh, nh, ii, jj, contxt,
283 CALL pdgemr2d( nh, nh, a, ilo, ilo, desca, t, 1, 1, desct,
285 IF ( myrow .EQ. ii .AND. mycol .EQ. jj )
THEN
286 CALL dlaset(
'All', nh, nh, zero, one, v, ldv )
287 nmin = ilaenv( 12,
'DLAQR3',
'SV', nh, 1, nh, lwork )
288 IF( nh .GT. nmin )
THEN
289 CALL dlaqr4( .true., .true., nh, 1, nh, t, ldt, wr( ilo ),
290 $ wi( ilo ), 1, nh, v, ldv, work, lwork, info )
292 CALL dlaset( 'l
', NH-2, NH-2, ZERO, ZERO, T( 3, 1 ), LDT )
294 CALL DLAHQR( .TRUE., .TRUE., NH, 1, NH, T, LDT, WR( ILO ),
295 $ WI( ILO ), 1, NH, V, LDV, INFO )
297 CALL DGEBS2D( CONTXT, 'all
', ' ', NH, NH, V, LDV )
298 CALL IGEBS2D( CONTXT, 'all
', '', 1, 1, INFO, 1 )
300 CALL DGEBR2D( CONTXT, 'all
', ' ', NH, NH, V, LDV, II, JJ )
301 CALL IGEBR2D( CONTXT, 'all
', ' ', 1, 1, INFO, 1, II, JJ )
303.NE.
IF( INFO 0 ) INFO = INFO+ILO-1
307 CALL PDGEMR2D( NH, NH, T, 1, 1, DESCT, A, ILO, ILO, DESCA,
312.LE.
IF( MOD( ILO-1, HBL )+NH HBL ) THEN
324 CALL INFOG2L( ILO, I+1, DESCA, NPROW, NPCOL, MYROW,
325 $ MYCOL, IROW, ICOL, II, JJ )
326.EQ.
IF( MYROW II ) THEN
327 ICOL1 = NUMROC( N, HBL, MYCOL, JAFIRST, NPCOL )
328 DO 10 KKCOL = ICOL, ICOL1, HSTEP
329 KLN = MIN( HSTEP, ICOL1-KKCOL+1 )
330 CALL DGEMM( 't
', 'n
', NH, KLN, NH, ONE, V,
331 $ LDV, A( IROW+(KKCOL-1)*LDA ), LDA, ZERO, WORK,
333 CALL DLAMOV( 'a
', NH, KLN, WORK, NH,
334 $ A( IROW+(KKCOL-1)*LDA ), LDA )
340 CALL INFOG2L( LTOP, ILO, DESCA, NPROW, NPCOL, MYROW,
341 $ MYCOL, IROW, ICOL, II, JJ )
342.EQ.
IF( MYCOL JJ ) THEN
343 CALL INFOG2L( ILO-1, ILO, DESCA, NPROW, NPCOL,
344 $ MYROW, MYCOL, IROW1, ICOL1, ITMP1, ITMP2 )
345.NE.
IF( MYROW ITMP1 ) IROW1 = IROW1-1
346 DO 20 KKROW = IROW, IROW1, VSTEP
347 KLN = MIN( VSTEP, IROW1-KKROW+1 )
348 CALL DGEMM( 'n
', 'n
', KLN, NH, NH, ONE,
349 $ A( KKROW+(ICOL-1)*LDA ), LDA, V, LDV, ZERO,
351 CALL DLAMOV( 'a
', KLN, NH, WORK, KLN,
352 $ A( KKROW+(ICOL-1)*LDA ), LDA )
360 CALL INFOG2L( ILOZ, ILO, DESCZ, NPROW, NPCOL, MYROW,
361 $ MYCOL, IROW, ICOL, II, JJ )
362.EQ.
IF( MYCOL JJ ) THEN
363 CALL INFOG2L( IHIZ, ILO, DESCZ, NPROW, NPCOL,
364 $ MYROW, MYCOL, IROW1, ICOL1, ITMP1, ITMP2 )
365.NE.
IF( MYROW ITMP1 ) IROW1 = IROW1-1
366 DO 30 KKROW = IROW, IROW1, VSTEP
367 KLN = MIN( VSTEP, IROW1-KKROW+1 )
368 CALL DGEMM( 'n
', 'n
', KLN, NH, NH, ONE,
369 $ Z( KKROW+(ICOL-1)*LDZ ), LDZ, V, LDV, ZERO,
371 CALL DLAMOV( 'a
', KLN, NH, WORK, KLN,
372 $ Z( KKROW+(ICOL-1)*LDZ ), LDZ )
377.LE.
ELSE IF( MOD( ILO-1, HBL )+NH 2*HBL ) THEN
383 D1 = HBL - MOD( ILO-1, HBL )
392 CALL INFOG2L( ILO, I+1, DESCA, NPROW, NPCOL, MYROW,
393 $ MYCOL, IROW, ICOL, II, JJ )
394.EQ.
IF( MYROW UP ) THEN
395.EQ.
IF( MYROW II ) THEN
396 ICOL1 = NUMROC( N, HBL, MYCOL, JAFIRST, NPCOL )
397 DO 40 KKCOL = ICOL, ICOL1, HSTEP
398 KLN = MIN( HSTEP, ICOL1-KKCOL+1 )
399 CALL DGEMM( 't
', 'n
', NH, KLN, NH, ONE, V,
400 $ NH, A( IROW+(KKCOL-1)*LDA ), LDA, ZERO,
402 CALL DLAMOV( 'a
', NH, KLN, WORK, NH,
403 $ A( IROW+(KKCOL-1)*LDA ), LDA )
407.EQ.
IF( MYROW II ) THEN
408 ICOL1 = NUMROC( N, HBL, MYCOL, JAFIRST, NPCOL )
409 DO 50 KKCOL = ICOL, ICOL1, HSTEP
410 KLN = MIN( HSTEP, ICOL1-KKCOL+1 )
411 CALL DGEMM( 't
', 'n
', D2, KLN, D1, ONE,
412 $ V( 1, D1+1 ), LDV, A( IROW+(KKCOL-1)*LDA ),
413 $ LDA, ZERO, WORK( D1+1 ), NH )
414 CALL DGESD2D( CONTXT, D2, KLN, WORK( D1+1 ),
416 CALL DGERV2D( CONTXT, D1, KLN, WORK, NH, DOWN,
418 CALL DGEMM( 't',
'N', d1, kln, d1, one,
419 $ v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
421 CALL dlamov(
'A', d1, kln, work, nh,
422 $ a( irow+(kkcol-1)*lda ), lda
424 ELSE IF( up .EQ. ii )
THEN
425 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
426 DO 60 kkcol = icol, icol1, hstep
427 kln =
min( hstep, icol1-kkcol+1 )
428 CALL dgemm(
'T',
'N', d1, kln, d2, one,
429 $ v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
430 $ lda, zero, work, nh )
431 CALL dgesd2d( contxt, d1, kln, work, nh, up,
433 CALL dgerv2d( contxt, d2, kln, work( d1+1 ),
435 CALL dgemm(
'T',
'N', d2, kln, d2, one,
436 $ v( d1+1, d1+1 ), ldv,
439 CALL dlamov(
'A', d2, kln, work( d1+1 ), nh,
440 $ a( irow+(kkcol-1)*lda ), lda )
447 CALL infog2l( ltop, ilo, desca, nprow, npcol, myrow,
448 $ mycol, irow, icol, ii, jj )
449 IF( mycol .EQ. left )
THEN
450 IF( mycol .EQ. jj )
THEN
451 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
452 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
454 DO 70 kkrow = irow, irow1, vstep
455 kln =
min( vstep, irow1-kkrow+1 )
456 CALL dgemm(
'N',
'N', kln, nh, nh, one,
457 $ a( kkrow+(icol-1)*lda ), lda, v, ldv,
459 CALL dlamov(
'A', kln, nh, work, kln,
460 $ a( kkrow+(icol-1)*lda ), lda )
464 IF( mycol .EQ. jj )
THEN
465 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
466 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
467 IF( myrow .NE. itmp1 ) irow1 = irow1-1
468 DO 80 kkrow = irow, irow1, vstep
469 kln =
min( vstep, irow1-kkrow+1 )
470 CALL dgemm(
'N',
'N', kln, d2, d1, one,
471 $ a( kkrow+(icol-1)*lda ), lda, v( 1, d1+1 ),
472 $ ldv, zero, work( 1+d1*kln ), kln )
473 CALL dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
474 $ kln, myrow, right )
475 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
477 CALL dgemm(
'N',
'N', kln, d1, d1, one,
478 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
480 CALL dlamov(
'A', kln, d1, work, kln,
481 $ a( kkrow+(icol-1)*lda ), lda )
483 ELSE IF ( left .EQ. jj )
THEN
484 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
485 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
486 IF( myrow .NE. itmp1 ) irow1 = irow1-1
487 DO 90 kkrow = irow, irow1, vstep
488 kln =
min( vstep, irow1-kkrow+1 )
489 CALL dgemm(
'N',
'N', kln, d1, d2, one,
490 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
491 $ ldv, zero, work, kln )
492 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
494 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
496 CALL dgemm(
'N',
'N', kln, d2, d2, one,
497 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, d1+1 ),
498 $ ldv, one, work( 1+d1*kln ), kln )
499 CALL dlamov(
'A', kln, d2, work( 1+d1*kln ), kln,
500 $ a( kkrow+(icol-1)*lda ), lda )
509 CALL infog2l( iloz, ilo, descz, nprow, npcol, myrow,
510 $ mycol, irow, icol, ii, jj )
511 IF( mycol .EQ. left )
THEN
512 IF( mycol .EQ. jj )
THEN
513 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
514 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
515 IF( myrow .NE. itmp1 ) irow1 = irow1-1
516 DO 100 kkrow = irow, irow1, vstep
517 kln =
min( vstep, irow1-kkrow+1 )
518 CALL dgemm(
'N',
'N', kln, nh, nh, one,
519 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
521 CALL dlamov(
'A', kln, nh, work, kln,
522 $ z( kkrow+(icol-1)*ldz ), ldz )
526 IF( mycol .EQ. jj )
THEN
527 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
528 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
529 IF( myrow .NE. itmp1 ) irow1 = irow1-1
530 DO 110 kkrow = irow, irow1, vstep
531 kln =
min( vstep, irow1
532 CALL dgemm(
'N',
'N', kln, d2, d1, one,
533 $ z( kkrow+(icol-1)*ldz ), ldz, v( 1, d1+1 ),
534 $ ldv, zero, work( 1+d1*kln ), kln )
535 CALL dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
536 $ kln, myrow, right )
537 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
539 CALL dgemm(
'N',
'N', kln, d1, d1, one,
540 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
542 CALL dlamov(
'A', kln, d1, work, kln,
543 $ z( kkrow+(icol-1)*ldz ), ldz )
545 ELSE IF( left .EQ. jj )
THEN
546 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
547 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
548 IF( myrow .NE. itmp1 ) irow1 = irow1-1
549 DO 120 kkrow = irow, irow1, vstep
550 kln =
min( vstep, irow1-kkrow+1 )
551 CALL dgemm(
'N',
'N', kln, d1, d2, one,
552 $ z( kkrow+(icol-1)*ldz ), ldz, v( d1+1, 1 ),
553 $ ldv, zero, work, kln )
554 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
556 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
558 CALL dgemm(
'N',
'N', kln, d2, d2, one,
559 $ z( kkrow+(icol-1)*ldz ), ldz,
560 $ v( d1+1, d1+1 ), ldv, one, work( 1+d1*kln ),
562 CALL dlamov(
'A', kln, d2, work( 1+d1*kln ),
563 $ kln, z( kkrow+(icol-1)*ldz ), ldz )
575 hstep = lwork / nh * npcol
576 vstep = lwork / nh * nprow
577 lldtmp = numroc( nh, nh, myrow, 0, nprow )
578 lldtmp =
max( 1, lldtmp )
579 CALL descinit( descv, nh, nh, nh, nh, 0, 0, contxt,
581 CALL descinit( descwh, nh, hstep, nh, lwork / nh, 0, 0,
582 $ contxt, lldtmp, ierr )
588 DO 130 kkcol = i+1, n, hstep
589 kln =
min( hstep, n-kkcol+1 )
590 CALL pdgemm(
'T',
'N', nh, kln, nh, one, v, 1, 1,
591 $ descv, a, ilo, kkcol, desca, zero, work, 1, 1,
593 CALL pdgemr2d( nh, kln, work, 1, 1, descwh, a,
594 $ ilo, kkcol, desca, contxt )
599 DO 140 kkrow = ltop, ilo-1, vstep
600 kln =
min( vstep, ilo-kkrow )
601 lldtmp = numroc( kln, lwork / nh, myrow, 0, nprow )
602 lldtmp =
max( 1, lldtmp )
603 CALL descinit( descwv, kln, nh, lwork / nh, nh, 0, 0,
604 $ contxt, lldtmp, ierr )
605 CALL pdgemm(
'N',
'N', kln, nh, nh, one, a, kkrow,
606 $ ilo, desca, v, 1, 1, descv, zero, work, 1, 1,
608 CALL pdgemr2d( kln, nh, work, 1, 1, descwv, a, kkrow,
609 $ ilo, desca, contxt )
616 DO 150 kkrow = iloz, ihiz, vstep
617 kln =
min( vstep, ihiz-kkrow+1 )
618 lldtmp = numroc( kln, lwork / nh, myrow, 0, nprow )
619 lldtmp =
max( 1, lldtmp )
620 CALL descinit( descwv, kln, nh, lwork / nh, nh, 0, 0,
621 $ contxt, lldtmp, ierr )
622 CALL pdgemm(
'N',
'N', kln, nh, nh, one, z, kkrow,
623 $ ilo, descz, v, 1, 1, descv, zero, work, 1, 1,
625 CALL pdgemr2d( kln, nh, work, 1, 1, descwv, z,
626 $ kkrow, ilo, descz, contxt )