1 SUBROUTINE pdlaqr2( WANTT, WANTZ, N, KTOP, KBOT, NW, A, DESCA,
2 $ ILOZ, IHIZ, Z, DESCZ, NS, ND, SR, SI, T, LDT,
3 $ V, LDV, WR, WI, WORK, LWORK )
15 INTEGER IHIZ, ILOZ, KBOT, KTOP, LDT, LDV, LWORK, N, ND,
20 INTEGER DESCA( * ), DESCZ( * )
21 DOUBLE PRECISION A( * ), SI( KBOT ), SR( KBOT ), T( LDT, * ),
22 $ v( ldv, * ), work( * ), wi( * ), wr( * ),
211 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
212 $ LLD_, MB_, M_, NB_, N_, RSRC_
213 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
214 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
215 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
216 DOUBLE PRECISION ZERO, ONE
217 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
220 INTEGER CONTXT, HBL, I, I1, I2, IAFIRST, ICOL, ICOL1,
221 $ ICOL2, INFO, II, IROW, IROW1, IROW2, ITMP1,
222 $ itmp2, j, jafirst, jj, k, l, lda, ldz, lldtmp,
223 $ mycol, myrow, node, npcol, nprow, dblk,
224 $ hstep, vstep, kkrow, kkcol, kln, ltop, left,
225 $ right, up, down, d1, d2
228 INTEGER DESCT( 9 ), DESCV( 9 ), DESCWH( 9 ),
236 EXTERNAL blacs_gridinfo,
infog2l, dlaset,
237 $ dlaqr3,
descinit, pdgemm, pdgemr2d, dgemm,
238 $ dlamov, dgesd2d, dgerv2d, dgebs2d, dgebr2d,
254 contxt = desca( ctxt_ )
256 iafirst = desca( rsrc_ )
257 jafirst = desca( csrc_ )
259 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
260 node = myrow*npcol + mycol
261 left = mod( mycol+npcol-1, npcol )
262 right = mod( mycol+1, npcol )
263 up = mod( myrow+nprow-1, nprow )
264 down = mod( myrow+1, nprow )
284 CALL infog2l( i-dblk+1, i-dblk+1, desca, nprow, npcol, myrow,
285 $ mycol, irow, icol, ii, jj )
286 IF ( myrow .EQ. ii )
THEN
287 CALL descinit( desct, dblk, dblk, dblk, dblk, ii, jj, contxt,
289 CALL descinit( descv, dblk, dblk, dblk, dblk, ii, jj, contxt,
292 CALL descinit( desct, dblk, dblk, dblk, dblk, ii, jj, contxt,
294 CALL descinit( descv, dblk, dblk, dblk, dblk, ii, jj, contxt,
297 CALL pdgemr2d( dblk, dblk, a, i-dblk+1, i-dblk+1, desca, t, 1, 1,
299 IF ( myrow .EQ. ii .AND. mycol .EQ. jj )
THEN
300 CALL dlaset(
'All', dblk, dblk, zero, one, v, ldv )
301 CALL dlaqr3( .true., .true., dblk, 1, dblk, dblk-1, t, ldt, 1,
302 $ dblk, v, ldv, ns, nd, wr, wi, work, dblk, dblk,
303 $ work( dblk*dblk+1 ), dblk, dblk, work( 2*dblk*dblk+1 ),
304 $ dblk, work( 3*dblk*dblk+1 ), lwork-3*dblk*dblk )
305 CALL dgebs2d( contxt,
'All',
' ', dblk, dblk, v, ldv )
306 CALL igebs2d( contxt,
'All',
' ', 1, 1, nd, 1 )
308 CALL dgebr2d( contxt,
'All',
' ', dblk, dblk, v, ldv, ii, jj )
309 CALL igebr2d( contxt,
'All',
' ', 1, 1, nd, 1, ii, jj )
316 CALL pdgemr2d( dblk, dblk, t, 1, 1, desct, a, i-dblk+1,
317 $ i-dblk+1, desca, contxt )
321 IF( mod( i-dblk, hbl )+dblk .LE. hbl )
THEN
333 CALL infog2l( i-dblk+1, i+1, desca, nprow, npcol, myrow,
334 $ mycol, irow, icol, ii, jj )
335 IF( myrow .EQ. ii )
THEN
336 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
337 DO 10 kkcol = icol, icol1, hstep
338 kln =
min( hstep, icol1-kkcol+1 )
339 CALL dgemm(
'T',
'N', dblk, kln, dblk, one, v,
340 $ ldv, a( irow+(kkcol-1)*lda ), lda, zero, work,
342 CALL dlamov(
'A', dblk, kln, work, dblk,
343 $ a( irow+(kkcol-1)*lda ), lda )
350 CALL infog2l( ltop, i-dblk+1, desca, nprow, npcol, myrow,
351 $ mycol, irow, icol, ii, jj )
352 IF( mycol .EQ. jj )
THEN
353 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
354 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
355 IF( myrow .NE. itmp1 ) irow1 = irow1-1
356 DO 20 kkrow = irow, irow1, vstep
357 kln =
min( vstep, irow1-kkrow+1 )
358 CALL dgemm(
'N',
'N', kln, dblk, dblk, one,
359 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero, work,
361 CALL dlamov(
'A', kln, dblk, work, kln,
362 $ a( kkrow+(icol-1)*lda ), lda )
369 CALL infog2l( iloz, i-dblk+1, descz, nprow, npcol, myrow,
370 $ mycol, irow, icol, ii, jj )
371 IF( mycol .EQ. jj )
THEN
372 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
373 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
374 IF( myrow .NE. itmp1 ) irow1 = irow1-1
375 DO 30 kkrow = irow, irow1, vstep
376 kln =
min( vstep, irow1-kkrow+1 )
377 CALL dgemm(
'N',
'N', kln, dblk, dblk, one,
378 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
380 CALL dlamov(
'A', kln, dblk, work, kln,
381 $ z( kkrow+(icol-1)*ldz ), ldz )
386 ELSE IF( mod( i-dblk, hbl )+dblk .LE. 2*hbl )
THEN
392 d1 = hbl - mod( i-dblk, hbl )
400 CALL infog2l( i-dblk+1, i+1, desca, nprow, npcol, myrow,
401 $ mycol, irow, icol, ii, jj )
402 IF( myrow .EQ. up )
THEN
403 IF( myrow .EQ. ii )
THEN
404 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
405 DO 40 kkcol = icol, icol1, hstep
406 kln =
min( hstep, icol1-kkcol+1 )
407 CALL dgemm(
'T',
'N', dblk, kln, dblk, one, v,
408 $ dblk, a( irow+(kkcol-1)*lda ), lda, zero,
410 CALL dlamov(
'A', dblk, kln, work, dblk,
411 $ a( irow+(kkcol-1)*lda ), lda )
415 IF( myrow .EQ. ii )
THEN
416 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
417 DO 50 kkcol = icol, icol1, hstep
418 kln =
min( hstep, icol1-kkcol+1 )
419 CALL dgemm(
'T',
'N', d2, kln, d1, one,
420 $ v( 1, d1+1 ), ldv, a( irow+(kkcol-1)*lda ),
421 $ lda, zero, work( d1+1 ), dblk )
422 CALL dgesd2d( contxt, d2, kln, work( d1+1 ),
423 $ dblk, down, mycol )
424 CALL dgerv2d( contxt, d1, kln, work, dblk, down,
426 CALL dgemm(
'T',
'N', d1, kln, d1, one,
427 $ v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
429 CALL dlamov(
'A', d1, kln, work, dblk,
430 $ a( irow+(kkcol-1)*lda ), lda )
432 ELSE IF( up .EQ. ii )
THEN
433 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
434 DO 60 kkcol = icol, icol1, hstep
435 kln =
min( hstep, icol1-kkcol+1 )
436 CALL dgemm(
'T',
'N', d1, kln, d2, one,
437 $ v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
438 $ lda, zero, work, dblk )
439 CALL dgesd2d( contxt, d1, kln, work, dblk, up,
441 CALL dgerv2d( contxt, d2, kln, work( d1+1 ),
443 CALL dgemm(
'T',
'N', d2, kln, d2, one,
444 $ v( d1+1, d1+1 ), ldv,
445 $ a( irow+(kkcol-1)*lda ), lda, one,
446 $ work( d1+1 ), dblk )
447 CALL dlamov(
'A', d2, kln, work( d1+1 ), dblk,
448 $ a( irow+(kkcol-1)*lda ), lda )
456 CALL infog2l( ltop, i-dblk+1, desca, nprow, npcol, myrow,
457 $ mycol, irow, icol, ii, jj )
458 IF( mycol .EQ. left )
THEN
459 IF( mycol .EQ. jj )
THEN
460 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
461 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
462 IF( myrow .NE. itmp1 ) irow1 = irow1-1
463 DO 70 kkrow = irow, irow1, vstep
464 kln =
min( vstep, irow1-kkrow+1 )
465 CALL dgemm(
'N',
'N', kln, dblk, dblk, one,
466 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero,
468 CALL dlamov(
'A', kln, dblk, work, kln,
469 $ a( kkrow+(icol-1)*lda ), lda )
473 IF( mycol .EQ. jj )
THEN
474 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
475 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
476 IF( myrow .NE. itmp1 ) irow1 = irow1-1
477 DO 80 kkrow = irow, irow1, vstep
478 kln =
min( vstep, irow1-kkrow+1 )
479 CALL dgemm(
'N',
'N', kln, d2, d1, one,
480 $ a( kkrow+(icol-1)*lda ), lda,
481 $ v( 1, d1+1 ), ldv, zero, work( 1+d1*kln ),
483 CALL dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
484 $ kln, myrow, right )
485 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
487 CALL dgemm(
'N',
'N', kln, d1, d1, one,
488 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
490 CALL dlamov(
'A', kln, d1, work, kln,
491 $ a( kkrow+(icol-1)*lda ), lda )
493 ELSE IF ( left .EQ. jj )
THEN
494 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
495 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
496 IF( myrow .NE. itmp1 ) irow1 = irow1-1
497 DO 90 kkrow = irow, irow1, vstep
498 kln =
min( vstep, irow1-kkrow+1 )
499 CALL dgemm(
'N',
'N', kln, d1, d2, one,
500 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
501 $ ldv, zero, work, kln )
502 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
504 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
506 CALL dgemm(
'N',
'N', kln, d2, d2, one,
507 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, d1+1 ),
508 $ ldv, one, work( 1+d1*kln ), kln )
509 CALL dlamov(
'A', kln, d2, work( 1+d1*kln ), kln,
510 $ a( kkrow+(icol-1)*lda ), lda )
518 CALL infog2l( iloz, i-dblk+1, descz, nprow, npcol, myrow,
519 $ mycol, irow, icol, ii, jj )
520 IF( mycol .EQ. left )
THEN
521 IF( mycol .EQ. jj )
THEN
522 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
523 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
524 IF( myrow .NE. itmp1 ) irow1 = irow1-1
525 DO 100 kkrow = irow, irow1, vstep
526 kln =
min( vstep, irow1-kkrow+1 )
527 CALL dgemm(
'N',
'N', kln, dblk, dblk, one,
528 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
530 CALL dlamov(
'A', kln, dblk, work, kln,
531 $ z( kkrow+(icol-1)*ldz ), ldz )
535 IF( mycol .EQ. jj )
THEN
536 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
537 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
538 IF( myrow .NE. itmp1 ) irow1 = irow1-1
539 DO 110 kkrow = irow, irow1, vstep
540 kln =
min( vstep, irow1-kkrow+1 )
541 CALL dgemm(
'N',
'N', kln, d2, d1, one,
542 $ z( kkrow+(icol-1)*ldz ), ldz,
543 $ v( 1, d1+1 ), ldv, zero, work( 1+d1*kln ),
545 CALL dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
546 $ kln, myrow, right )
547 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
549 CALL dgemm(
'N',
'N', kln, d1, d1, one,
550 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
552 CALL dlamov(
'A', kln, d1, work, kln,
553 $ z( kkrow+(icol-1)*ldz ), ldz )
555 ELSE IF( left .EQ. jj )
THEN
556 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
557 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
558 IF( myrow .NE. itmp1 ) irow1 = irow1-1
559 DO 120 kkrow = irow, irow1, vstep
560 kln =
min( vstep, irow1-kkrow+1 )
561 CALL dgemm(
'N',
'N', kln, d1, d2, one,
562 $ z( kkrow+(icol-1)*ldz ), ldz,
563 $ v( d1+1, 1 ), ldv, zero, work, kln )
564 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
566 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
568 CALL dgemm(
'N',
'N', kln, d2, d2, one,
569 $ z( kkrow+(icol-1)*ldz ), ldz,
570 $ v( d1+1, d1+1 ), ldv, one,
571 $ work( 1+d1*kln ), kln )
572 CALL dlamov(
'A', kln, d2, work( 1+d1*kln ),
573 $ kln, z( kkrow+(icol-1)*ldz ), ldz )
585 hstep = lwork / dblk * npcol
586 vstep = lwork / dblk * nprow
587 lldtmp = numroc( dblk, dblk, myrow, 0, nprow )
588 lldtmp =
max( 1, lldtmp )
589 CALL descinit( descv, dblk, dblk, dblk, dblk, 0, 0, contxt,
591 CALL descinit( descwh, dblk, hstep, dblk, lwork / dblk, 0,
592 $ 0, contxt, lldtmp, info )
597 DO 130 kkcol = i+1, n, hstep
598 kln =
min( hstep, n-kkcol+1 )
599 CALL pdgemm(
'T',
'N', dblk, kln, dblk, one, v, 1, 1,
600 $ descv, a, i-dblk+1, kkcol, desca, zero, work, 1,
602 CALL pdgemr2d( dblk, kln, work, 1, 1, descwh, a,
603 $ i-dblk+1, kkcol, desca, contxt )
609 DO 140 kkrow = ltop, i-dblk, vstep
610 kln =
min( vstep, i-dblk-kkrow+1 )
611 lldtmp = numroc( kln, lwork / dblk, myrow, 0, nprow )
612 lldtmp =
max( 1, lldtmp )
613 CALL descinit( descwv, kln, dblk, lwork / dblk, dblk, 0,
614 $ 0, contxt, lldtmp, info )
615 CALL pdgemm(
'N',
'N', kln, dblk, dblk, one, a, kkrow,
616 $ i-dblk+1, desca, v, 1, 1, descv, zero, work, 1, 1,
618 CALL pdgemr2d( kln, dblk, work, 1, 1, descwv, a, kkrow,
619 $ i-dblk+1, desca, contxt )
625 DO 150 kkrow = iloz, ihiz, vstep
626 kln =
min( vstep, ihiz-kkrow+1 )
627 lldtmp = numroc( kln, lwork / dblk, myrow, 0, nprow )
628 lldtmp =
max( 1, lldtmp )
629 CALL descinit( descwv, kln, dblk, lwork / dblk, dblk,
630 $ 0, 0, contxt, lldtmp, info )
631 CALL pdgemm(
'N',
'N', kln, dblk, dblk, one, z, kkrow,
632 $ i-dblk+1, descz, v, 1, 1, descv, zero, work, 1,
634 CALL pdgemr2d( kln, dblk, work, 1, 1, descwv, z,
635 $ kkrow, i-dblk+1, descz, contxt )
644 IF( ii .EQ. nd-1 .OR. wi( dblk-ii ) .EQ. zero )
THEN
645 IF( node .EQ. 0 )
THEN
646 sr( i-ii ) = wr( dblk-ii )
653 IF( node .EQ. 0 )
THEN
654 sr( i-ii-1 ) = wr( dblk-ii-1 )
655 sr( i-ii ) = wr( dblk-ii )
656 si( i-ii-1 ) = wi( dblk-ii-1 )
657 si( i-ii ) = wi( dblk-ii )
666 IF( ii .LT. nd )
GOTO 160