1      SUBROUTINE pslaqr2( 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      REAL               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 )
 
  217      PARAMETER          ( ZERO = 0.0, one = 1.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, slaset,
 
  237     $                   slaqr3, 
descinit, psgemm, psgemr2d, sgemm,
 
  238     $                   slamov, sgesd2d, sgerv2d, sgebs2d, sgebr2d,
 
  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 psgemr2d( 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 slaset( 
'All', dblk, dblk, zero, one, v, ldv )
 
  301         CALL slaqr3( .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 sgebs2d( contxt, 
'All', 
' ', dblk, dblk, v, ldv )
 
  306         CALL igebs2d( contxt, 
'All', 
' ', 1, 1, nd, 1 )
 
  308         CALL sgebr2d( contxt, 
'All', 
' ', dblk, dblk, v, ldv, ii, jj )
 
  309         CALL igebr2d( contxt, 
'All', 
' ', 1, 1, nd, 1, ii, jj )
 
  316         CALL psgemr2d( 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 sgemm( 
'T', 
'N', dblk, kln, dblk, one, v,
 
  340     $                    ldv, a( irow+(kkcol-1)*lda ), lda, zero, work,
 
  342                     CALL slamov( 
'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 sgemm( 
'N', 
'N', kln, dblk, dblk, one,
 
  359     $                 a( kkrow+(icol-1)*lda ), lda, v, ldv, zero, work,
 
  361                  CALL slamov( 
'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 sgemm( 
'N', 
'N', kln, dblk, dblk, one,
 
  378     $                    z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
 
  380                     CALL slamov( 
'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 sgemm( 
'T', 
'N', dblk, kln, dblk, one, v,
 
  408     $                       dblk, a( irow+(kkcol-1)*lda ), lda, zero,
 
  410                        CALL slamov( 
'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 sgemm( 
'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 sgesd2d( contxt, d2, kln, work( d1+1 ),
 
  423     $                       dblk, down, mycol )
 
  424                        CALL sgerv2d( contxt, d1, kln, work, dblk, down,
 
  426                        CALL sgemm( 
'T', 
'N', d1, kln, d1, one,
 
  427     $                       v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
 
  429                        CALL slamov( 
'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 sgemm( 
'T', 
'N', d1, kln, d2, one,
 
  437     $                       v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
 
  438     $                       lda, zero, work, dblk )
 
  439                        CALL sgesd2d( contxt, d1, kln, work, dblk, up,
 
  441                        CALL sgerv2d( contxt, d2, kln, work( d1+1 ),
 
  443                        CALL sgemm( 
'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 slamov( 
'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 sgemm( 
'N', 
'N', kln, dblk, dblk, one,
 
  466     $                    a( kkrow+(icol-1)*lda ), lda, v, ldv, zero,
 
  468                     CALL slamov( 
'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 sgemm( 
'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 sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
 
  484     $                    kln, myrow, right )
 
  485                     CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
 
  487                     CALL sgemm( 
'N', 
'N', kln, d1, d1, one,
 
  488     $                    a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
 
  490                     CALL slamov( 
'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 sgemm( 
'N', 
'N', kln, d1, d2, one,
 
  500     $                    a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
 
  501     $                    ldv, zero, work, kln )
 
  502                     CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
 
  504                     CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
 
  506                     CALL sgemm( 
'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 slamov( 
'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 sgemm( 
'N', 
'N', kln, dblk, dblk, one,
 
  528     $                       z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
 
  530                        CALL slamov( 
'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 sgemm( 
'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 sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
 
  546     $                       kln, myrow, right )
 
  547                        CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
 
  549                        CALL sgemm( 
'N', 
'N', kln, d1, d1, one,
 
  550     $                       z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
 
  552                        CALL slamov( 
'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 sgemm( 
'N', 
'N', kln, d1, d2, one,
 
  562     $                       z( kkrow+(icol-1)*ldz ), ldz,
 
  563     $                       v( d1+1, 1 ), ldv, zero, work, kln )
 
  564                        CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
 
  566                        CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
 
  568                        CALL sgemm( 
'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 slamov( 
'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 psgemm( 
'T', 
'N', dblk, kln, dblk, one, v, 1, 1,
 
  600     $                 descv, a, i-dblk+1, kkcol, desca, zero, work, 1,
 
  602                  CALL psgemr2d( 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 psgemm( 
'N', 
'N', kln, dblk, dblk, one, a, kkrow,
 
  616     $              i-dblk+1, desca, v, 1, 1, descv, zero, work, 1, 1,
 
  618               CALL psgemr2d( 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 psgemm( 
'N', 
'N', kln, dblk, dblk, one, z, kkrow,
 
  632     $                 i-dblk+1, descz, v, 1, 1, descv, zero, work, 1,
 
  634                  CALL psgemr2d( 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