1      SUBROUTINE pbztrnv( ICONTXT, XDIST, TRANS, N, NB, NZ, X, INCX,
 
    2     $                    BETA, Y, INCY, IXROW, IXCOL, IYROW, IYCOL,
 
   14      CHARACTER*1        TRANS, XDIST
 
   15      INTEGER            ICONTXT, INCX, INCY, IXCOL, IXROW, IYCOL,
 
   20      COMPLEX*16         WORK( * ), X( * ), Y( * )
 
  170      PARAMETER          ( ONE  = ( 1.0d+0, 0.0d+0 ),
 
  171     $                   zero = ( 0.0d+0, 0.0d+0 ) )
 
  174      LOGICAL            COLFORM, ROWFORM
 
  175      INTEGER            I, IDEX, IGD, INFO, JDEX, JYCOL, JYROW, JZ, KZ,
 
  176     $                   lcm, lcmp, lcmq, mccol, mcrow, mrcol, mrrow,
 
  177     $                   mycol, myrow, nn, np, np0, np1, npcol, nprow,
 
  183      INTEGER            ILCM, ICEIL, NUMROC
 
  184      EXTERNAL           lsame, ilcm, iceil, numroc
 
  200      CALL blacs_gridinfo( icontxt, nprow, npcol, myrow, mycol )
 
  202      colform = lsame( xdist, 
'C' )
 
  203      rowform = lsame( xdist, 
'R' )
 
  208      IF( ( .NOT.colform ) .AND. ( .NOT.rowform ) ) 
THEN 
  210      ELSE IF( n   .LT.0                          ) 
THEN 
  212      ELSE IF( nb  .LT.1                          ) 
THEN 
  214      ELSE IF( nz  .LT.0 .OR. nz.GE.nb            ) 
THEN 
  216      ELSE IF( incx.EQ.0                          ) 
THEN 
  218      ELSE IF( incy.EQ.0                          ) 
THEN 
  220      ELSE IF( ixrow.LT.-1 .OR. ixrow.GE.nprow .OR.
 
  221     $       ( ixrow.EQ.-1 .AND. colform )        ) 
THEN 
  223      ELSE IF( ixcol.LT.-1 .OR. ixcol.GE.npcol .OR.
 
  224     $       ( ixcol.EQ.-1 .AND. rowform )        ) 
THEN 
  226      ELSE IF( iyrow.LT.-1 .OR. iyrow.GE.nprow .OR.
 
  227     $       ( iyrow.EQ.-1 .AND. rowform )        ) 
THEN 
  229      ELSE IF( iycol.LT.-1 .OR. iycol.GE.npcol .OR.
 
  230     $       ( iycol.EQ.-1 .AND. colform )        ) 
THEN 
  236         CALL pxerbla( icontxt, 
'PBZTRNV ', info )
 
  244      lcm  = ilcm( nprow, npcol )
 
  264        IF(      ixrow.LT.0  .OR. ixrow.GE.nprow ) 
THEN 
  266        ELSE IF( ixcol.LT.-1 .OR. ixcol.GE.npcol ) 
THEN 
  268        ELSE IF( iyrow.LT.-1 .OR. iyrow.GE.nprow ) 
THEN 
  270        ELSE IF( iycol.LT.0  .OR. iycol.GE.npcol ) 
THEN 
  273        IF( info.NE.0 ) 
GO TO 10
 
  278        mrrow = mod( nprow+myrow-ixrow, nprow )
 
  279        mrcol = mod( npcol+mycol-iycol, npcol )
 
  281        IF( iyrow.EQ.-1 ) jyrow = ixrow
 
  283        np  = numroc( nn, nb, myrow, ixrow, nprow )
 
  284        IF( mrrow.EQ.0 ) np = np - nz
 
  285        nq  = numroc( nn, nb, mycol, iycol, npcol )
 
  286        IF( mrcol.EQ.0 ) nq = nq - nz
 
  287        nq0 = numroc( numroc(nn, nb, 0, 0, npcol), nb, 0, 0, lcmq )
 
  291        IF( ixcol .GE. 0 ) 
THEN 
  293          IF( myrow.EQ.jyrow ) tbeta = beta
 
  296          DO 20 i = 0, 
min( lcm, iceil(nn,nb) ) - 1
 
  297            mcrow = mod( mod(i, nprow) + ixrow, nprow )
 
  298            mccol = mod( mod(i, npcol) + iycol, npcol )
 
  299            IF( lcmq.EQ.1 )  nq0 = numroc( nn, nb, i, 0, npcol )
 
  300            jdex  = (i/npcol) * nb
 
  301            IF( mrcol.EQ.0 ) jdex = 
max(0, jdex-nz)
 
  305            IF( myrow.EQ.mcrow .AND. mycol.EQ.ixcol ) 
THEN 
  309              idex = (i/nprow) * nb
 
  310              IF( mrrow.EQ.0 ) idex = 
max( 0, idex-nz )
 
  311              IF( myrow.EQ.jyrow .AND. mycol.EQ.mccol ) 
THEN 
  312                CALL pbztr2b1( icontxt, trans, np-idex, nb, kz,
 
  313     $                          x(idex*incx+1), incx, tbeta,
 
  314     $                          y(jdex*incy+1), incy, lcmp, lcmq )
 
  319                CALL pbztr2b1( icontxt, trans, np-idex, nb, kz,
 
  320     $                         x(idex*incx+1), incx, zero, work, 1,
 
  322                CALL zgesd2d( icontxt, 1, nq0-kz, work, 1,
 
  328            ELSE IF( myrow.EQ.jyrow .AND. mycol.EQ.mccol ) 
THEN 
  329              IF( lcmq.EQ.1 .AND. tbeta.EQ.zero ) 
THEN 
  330                CALL zgerv2d( icontxt, 1, nq0-kz, y, incy,
 
  333                CALL zgerv2d( icontxt, 1, nq0-kz, work, 1,
 
  335                CALL pbztr2a1( icontxt, nq-jdex, nb, kz, work, 1, tbeta,
 
  336     $                         y(jdex*incy+1), incy, lcmq*nb )
 
  344          IF( iyrow.EQ.-1 ) 
THEN 
  345            IF( myrow.EQ.jyrow ) 
THEN 
  346              CALL zgebs2d( icontxt, 
'Col', 
'1-tree', 1, nq, y, incy )
 
  348              CALL zgebr2d( icontxt, 
'Col', 
'1-tree', 1, nq, y, incy,
 
  356          IF( lcmq.EQ.1 ) nq0 = nq
 
  362          IF( mrrow.EQ.0 ) kz = nz
 
  364          IF( mrrow.EQ.0 .AND. mycol.EQ.iycol ) jz = nz
 
  366          DO 30 i = 0, lcmp - 1
 
  367            IF( mrcol.EQ.mod(nprow*i+mrrow, npcol) ) 
THEN 
  368              idex = 
max( 0, i*nb-kz )
 
  369              IF( lcmq.EQ.1 .AND. (iyrow.EQ.-1.OR.iyrow.EQ.myrow) ) 
THEN 
  370                 CALL pbztr2b1( icontxt, trans, np-idex, nb, jz,
 
  371     $                          x(idex*incx+1), incx, beta, y, incy,
 
  374                 CALL pbztr2b1( icontxt, trans, np-idex, nb, jz,
 
  375     $                          x(idex*incx+1), incx, zero, work, 1,
 
  383          mcrow = mod( mod(mrcol, nprow) + ixrow, nprow )
 
  385            mccol = mod( npcol+mycol-iycol, npcol )
 
  386            CALL pbztrget( icontxt, 
'Row', 1, nq0, iceil( nn, nb ),
 
  387     $                     work, 1, mcrow, mccol, igd, myrow, mycol,
 
  393          IF( iyrow.EQ.-1 ) 
THEN 
  394            IF( myrow.EQ.mcrow ) 
THEN 
  397                IF( mycol.EQ.iycol ) kz = nz
 
  398                CALL pbztrst1( icontxt, 
'Row', nq, nb, kz, work, 1,
 
  399     $                         beta, y, incy, lcmp, lcmq, nq0 )
 
  401              CALL zgebs2d( icontxt, 
'Col', 
'1-tree', 1, nq, y, incy )
 
  403              CALL zgebr2d( icontxt, 
'Col', 
'1-tree', 1, nq, y, incy,
 
  411              IF( myrow.EQ.mcrow ) 
THEN 
  413     $            
CALL zgesd2d( icontxt, 1, nq0, work, 1, iyrow, mycol )
 
  414              ELSE IF( myrow.EQ.iyrow ) 
THEN 
  415                IF( beta.EQ.zero ) 
THEN 
  416                  CALL zgerv2d( icontxt, 1, nq0, y, incy, mcrow, mycol )
 
  418                  CALL zgerv2d( icontxt, 1, nq0, work, 1, mcrow, mycol )
 
  419                  CALL pbzvecadd( icontxt, 
'G', nq0, one, work, 1,
 
  425              nq1 = nq0 * 
min( lcmq, 
max( 0, iceil(nn,nb)-mccol ) )
 
  426              IF( myrow.EQ.mcrow ) 
THEN 
  428     $            
CALL zgesd2d( icontxt, 1, nq1, work, 1, iyrow, mycol )
 
  429              ELSE IF( myrow.EQ.iyrow ) 
THEN 
  430                CALL zgerv2d( icontxt, 1, nq1, work, 1, mcrow, mycol )
 
  433              IF( myrow.EQ.iyrow ) 
THEN 
  435                IF( mycol.EQ.iycol ) kz = nz
 
  436                CALL pbztrst1( icontxt, 
'Row', nq, nb, kz, work, 1,
 
  437     $                         beta, y, incy, lcmp, lcmq, nq0 )
 
  457        IF(      ixrow.LT.-1 .OR. ixrow.GE.nprow ) 
THEN 
  459        ELSE IF( ixcol.LT.0  .OR. ixcol.GE.npcol ) 
THEN 
  461        ELSE IF( iyrow.LT.0  .OR. iyrow.GE.nprow ) 
THEN 
  463        ELSE IF( iycol.LT.-1 .OR. iycol.GE.npcol ) 
THEN 
  466        IF( info.NE.0 ) 
GO TO 10
 
  471        mrrow = mod( nprow+myrow-iyrow, nprow )
 
  472        mrcol = mod( npcol+mycol-ixcol, npcol )
 
  474        IF( iycol.EQ.-1 ) jycol = ixcol
 
  476        np  = numroc( nn, nb, myrow, iyrow, nprow )
 
  477        IF( mrrow.EQ.0 ) np = np - nz
 
  478        nq  = numroc( nn, nb, mycol, ixcol, npcol )
 
  479        IF( mrcol.EQ.0 ) nq = nq - nz
 
  480        np0 = numroc( numroc(nn, nb, 0, 0, nprow), nb, 0, 0, lcmp )
 
  484        IF( ixrow .GE. 0 ) 
THEN 
  486          IF( mycol.EQ.jycol ) tbeta = beta
 
  489          DO 40 i = 0, 
min( lcm, iceil(nn,nb) ) - 1
 
  490            mcrow = mod( mod(i, nprow) + iyrow, nprow )
 
  491            mccol = mod( mod(i, npcol) + ixcol, npcol )
 
  492            IF( lcmp.EQ.1 ) np0 = numroc( nn, nb, i, 0, nprow )
 
  493            jdex  = (i/nprow) * nb
 
  494            IF( mrrow.EQ.0 ) jdex = 
max(0, jdex-nz)
 
  498            IF( myrow.EQ.ixrow .AND. mycol.EQ.mccol ) 
THEN 
  502              idex = (i/npcol) * nb
 
  503              IF( mrcol.EQ.0 ) idex = 
max( 0, idex-nz )
 
  504              IF( myrow.EQ.mcrow .AND. mycol.EQ.jycol ) 
THEN 
  505                CALL pbztr2b1( icontxt, trans, nq-idex, nb, kz,
 
  506     $                         x(idex*incx+1), incx, tbeta,
 
  507     $                         y(jdex*incy+1), incy, lcmq, lcmp )
 
  512                CALL pbztr2b1( icontxt, trans, nq-idex, nb, kz,
 
  513     $                         x(idex*incx+1), incx, zero, work, 1,
 
  515                CALL zgesd2d( icontxt, 1, np0-kz, work, 1,
 
  521            ELSE IF( myrow.EQ.mcrow .AND. mycol.EQ.jycol ) 
THEN 
  522              IF( lcmp.EQ.1 .AND. tbeta.EQ.zero ) 
THEN 
  523                CALL zgerv2d( icontxt, 1, np0-kz, y, incy,
 
  526                CALL zgerv2d( icontxt, 1, np0-kz, work, 1,
 
  528                CALL pbztr2a1( icontxt, np-jdex, nb, kz, work, 1, tbeta,
 
  529     $                         y(jdex*incy+1), incy, lcmp*nb )
 
  537          IF( iycol.EQ.-1 ) 
THEN 
  538            IF( mycol.EQ.jycol ) 
THEN 
  539              CALL zgebs2d( icontxt, 
'Row', 
'1-tree', 1, np, y, incy )
 
  541              CALL zgebr2d( icontxt, 
'Row', 
'1-tree', 1, np, y, incy,
 
  549          IF( lcmp.EQ.1 ) np0 = np
 
  555          IF( mrcol.EQ.0 ) kz = nz
 
  557          IF( mrcol.EQ.0 .AND. myrow.EQ.iyrow ) jz = nz
 
  560            IF( mrrow.EQ.mod(npcol*i+mrcol, nprow) ) 
THEN 
  561              idex = 
max( 0, i*nb-kz )
 
  562              IF( lcmp.EQ.1 .AND. (iycol.EQ.-1.OR.iycol.EQ.mycol) ) 
THEN 
  563                CALL pbztr2b1( icontxt, trans, nq-idex, nb, jz,
 
  564     $                          x(idex*incx+1), incx, beta, y, incy,
 
  567                CALL pbztr2b1( icontxt, trans, nq-idex, nb, jz,
 
  568     $                         x(idex*incx+1), incx, zero, work, 1,
 
  576          mccol = mod( mod(mrrow, npcol) + ixcol, npcol )
 
  578            mcrow = mod( nprow+myrow-iyrow, nprow )
 
  579            CALL pbztrget( icontxt, 
'Col', 1, np0, iceil( nn, nb ),
 
  580     $                     work, 1, mcrow, mccol, igd, myrow, mycol,
 
  586          IF( iycol.EQ.-1 ) 
THEN 
  587            IF( mycol.EQ.mccol ) 
THEN 
  590                IF( myrow.EQ.iyrow ) kz = nz
 
  591                CALL pbztrst1( icontxt, 
'Col', np, nb, kz, work, 1,
 
  592     $                         beta, y, incy, lcmp, lcmq, np0 )
 
  594              CALL zgebs2d( icontxt, 
'Row', 
'1-tree', 1, np, y, incy )
 
  596              CALL zgebr2d( icontxt, 
'Row', 
'1-tree', 1, np, y, incy,
 
  604              IF( mycol.EQ.mccol ) 
THEN 
  606     $            
CALL zgesd2d( icontxt, 1, np, work, 1, myrow, iycol )
 
  607              ELSE IF( mycol.EQ.iycol ) 
THEN 
  608                IF( beta.EQ.zero ) 
THEN 
  609                  CALL zgerv2d( icontxt, 1, np, y, incy, myrow, mccol )
 
  611                  CALL zgerv2d( icontxt, 1, np, work, 1, myrow, mccol )
 
  612                  CALL pbzvecadd( icontxt, 
'G', np, one, work, 1, beta,
 
  618              np1 = np0 * 
min( lcmp, 
max( 0, iceil(nn,nb)-mcrow ) )
 
  619              IF( mycol.EQ.mccol ) 
THEN 
  621     $            
CALL zgesd2d( icontxt, 1, np1, work, 1, myrow, iycol )
 
  622              ELSE IF( mycol.EQ.iycol ) 
THEN 
  623                CALL zgerv2d( icontxt, 1, np1, work, 1, myrow, mccol )
 
  626              IF( mycol.EQ.iycol ) 
THEN 
  628                IF( myrow.EQ.iyrow ) kz = nz
 
  629                CALL pbztrst1( icontxt, 
'Col', np, nb, kz, work, 1,
 
  630     $                         beta, y, incy, lcmp, lcmq, np0 )