Routine: PDLAHQR()  File: SRC\pdlahqr.f

 
 
# lines: 2132
  # code: 2132
  # comment: 0
  # blank:0
# Variables:77
# Callers:0
# Callings:2
# Words:2244
# Keywords:917
 

 

..
     .. Local Scalars ..
     ..
     .. Local Arrays ..
     ..
     .. External Functions ..
     ..
     .. External Subroutines ..
     ..
     .. Intrinsic Functions ..
     ..
     .. Executable Statements ..
     ITERMAX = 0
     NODE (IAFIRST,JAFIRST) OWNS A(1,1)
     Determine the number of columns we have so we can check workspace
     Set work array indices
     Find a value for ROTN
     Set machine-dependent constants for the stopping criterion.
     If NORM(H) <= SQRT(OVFL), overflow should not occur.
     I1 and I2 are the indices of the first row and last column of H
     to which transformations must be applied. If eigenvalues only are
     being computed, I1 and I2 are set inside the main loop.
     ITN is the total number of QR iterations allowed.
     The main loop begins here. I is the loop index and decreases from
     IHI to ILO in steps of our schur block size (<=2*IBLK). Each
     iteration of the loop works  with the active submatrix in rows
     and columns L to I.   Eigenvalues I+1 to IHI have already
     converged. Either L = ILO or the global A(L,L-1) is negligible
     so that the matrix splits.
     Perform QR iterations on rows and columns ILO to I until a
     submatrix of order 1 or 2 splits off at the bottom because a
     subdiagonal element has become negligible.
        Look for a single small subdiagonal element.
           H(L,L-1) is negligible
        Exit from loop if a submatrix of order 1 or 2 has split off.
        IF ( L .GE. I - (2*IBLK-1) )
         IF ( L .GE. I - MAX(2*IBLK-1,HBL) )
        Now the active submatrix is in rows and columns L to I. If
        eigenvalues only are being computed, only the active submatrix
        need be transformed.
        Copy submatrix of size 2*JBLK and prepare to do generalized
           Wilkinson shift or an exceptional shift
           Make sure it's divisible by LCM (we want even workloads!)
           Exceptional shift.
           Prepare to use Wilkinson's double shift
                 Real roots: Use Wilkinson's shift twice
        Look for two consecutive small subdiagonal elements:
           PDLACONSB is the routine that does this.
        Skip small submatrices
        IF ( M .GE. I - 5 )
    $      GO TO 80
        Double-shift QR step
        NBULGE is the number of bulges that will be attempted
        Do not exceed maximum determined.
           Make sure it's divisible by LCM (we want even workloads!)
           sort the eigenpairs so that they are in twos for double
           shifts.  only call if several need sorting
        IBULGE is the number of bulges going so far
        "A" row defs : main row transforms from LOCALK to LOCALI2
        "A" col defs : main col transforms from LOCALI1 to LOCALM
        Which row & column will start the bulges
        Set all values for bulges.  All bulges are stored in
          intermediate steps as loops over KI.  Their current "task"
          over the global M to I-1 values is always K1(KI) to K2(KI).
          However, because there are many bulges, K1(KI) & K2(KI) might
          go past that range while later bulges (KI+1,KI+2,etc..) are
          finishing up.
        Rules:
              If MOD(K1(KI)-1,HBL) < HBL-2 then MOD(K2(KI)-1,HBL)<HBL-2
              If MOD(K1(KI)-1,HBL) = HBL-2 then MOD(K2(KI)-1,HBL)=HBL-2
              If MOD(K1(KI)-1,HBL) = HBL-1 then MOD(K2(KI)-1,HBL)=HBL-1
              K2(KI)-K1(KI) <= ROTN
        We first hit a border when MOD(K1(KI)-1,HBL)=HBL-2 and we hit
        it again when MOD(K1(KI)-1,HBL)=HBL-1.
        Get first transform on node who owns M+2,M+2
        When we hit a border, there are row and column transforms that
          overlap over several processors and the code gets very
          "congested."  As a remedy, when we first hit a border, a 6x6
          *local* matrix is generated on one node (called SMALLA) and
          work is done on that.  At the end of the border, the data is
          passed back and everything stays a lot simpler.
                 Copy 6 elements from global A(K-1:K+4,K-1:K+4)
                 Copy 6 elements from global A(K-2:K+3,K-2:K+3)
           DLAHQR used to have a single row application and a single
              column application to H.  Here we do something a little
              more clever.  We break each transformation down into 3
              parts:
                  1.) The minimum amount of work it takes to determine
                        a group of ROTN transformations (this is on
                        the critical path.) (Loops 130-180)
                  2.) The small work it takes so that each of the rows
                        and columns is at the same place.  For example,
                        all ROTN row transforms are all complete
                        through some column TMP.  (Loops within 190)
                  3.) The majority of the row and column transforms
                        are then applied in a block fashion.
                        (Loops 290 on.)
           Each of these three parts are further subdivided into 3
           parts:
               A.) Work at the start of a border when
                       MOD(ISTART-1,HBL) = HBL-2
               B.) Work at the end of a border when
                       MOD(ISTART-1,HBL) = HBL-1
               C.) Work in the middle of the block when
                       MOD(ISTART-1,HBL) < HBL-2
                 Set a subdiagonal to zero now if it's possible
                 H11 = SMALLA(1,1,KI)
                 H10 = SMALLA(2,1,KI)
                 H22 = SMALLA(2,2,KI)
                 IF ( ABS(H10) .LE. MAX(ULP*(ABS(H11)+ABS(H22)),
    $                                    SMLNUM) ) THEN
                    SMALLA(2,1,KI) = ZERO
     WORK(ISUB+K-2) = ZERO
                 END IF
              (IROW1,ICOL1) is (I,J)-coordinates of H(ISTART,ISTART)
           (IROW1,ICOL1) is (I,J)-coordinates of H(ISTART,ISTART)
              Create and do these transforms
                    Set a subdiagonal to zero now if it's possible
                    IF ( (IROW1.GT.2) .AND. (ICOL1.GT.2) .AND.
    $                    (MOD(K-1,HBL) .GT. 1) ) THEN
                       H11 = A((ICOL1-3)*LDA+IROW1-2)
                       H10 = A((ICOL1-3)*LDA+IROW1-1)
                       H22 = A((ICOL1-2)*LDA+IROW1-1)
                       IF ( ABS(H10).LE.MAX(ULP*(ABS(H11)+ABS(H22)),
    $                                       SMLNUM) ) THEN
                           A((ICOL1-3)*LDA+IROW1-1) = ZERO
                       END IF
                    END IF

 
Display dynamic version Find AutoScroll Reload FontSize: - + Hide Comments Hide Blanks Frame FullScreen MailPrint

 
0001        SUBROUTINE PDLAHQR( WANTT , WANTZ , N , ILO , IHI , A , DESCA , WR , WI ,
0002       $ILOZ , IHIZ , Z , DESCZ , WORK , LWORK , IWORK ,
0003       $ILWORK , INFO )
0004  
0005  *     -- ScaLAPACK routine(version 1.7.3) --
0006  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
0007  *     and University of California , Berkeley.
0008  *     1.7.3 : March 22 , 2006
0009  *     modification suggested by Mark Fahey and Greg Henry
0010  *     1.7.1 : January 30 , 2006
0011  *     1.7.0 : December 31 , 1998
0012  
0013  *     .. Scalar Arguments ..
0014        LOGICAL WANTT , WANTZ
0015        INTEGER IHI , IHIZ , ILO , ILOZ , ILWORK , INFO , LWORK , N
0016  *     ..
0017  *     .. Array Arguments ..
0018        INTEGER DESCA( * ) , DESCZ( * ) , IWORK( * )
0019        DOUBLE PRECISION A( * ) , WI( * ) , WORK( * ) , WR( * ) , Z( * )
0020  *     ..
0021  
0022  *     Purpose
0023  *     === ====
0024  
0025  *     PDLAHQR is an auxiliary routine used to find the Schur decomposition
0026  *     and or eigenvalues of a matrix already in Hessenberg form from
0027  *     cols ILO to IHI.
0028  
0029  *     Notes
0030  *     === ==
0031  
0032  *     Each global data object is described by an associated description
0033  *     vector. This vector stores the information required to establish
0034  *     the mapping between an object element and its corresponding process
0035  *     and memory location.
0036  
0037  *     Let A be a generic term for any 2D block cyclicly distributed array.
0038  *     Such a global array has an associated description vector DESCA.
0039  *     In the following comments , the character _ should be read as
0040  *     "of the global array".
0041  
0042  *     NOTATION STORED IN EXPLANATION
0043  *     --- ------------ -------------- --------------------------------------
0044  *     DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case ,
0045  *     DTYPE_A = 1.
0046  *     CTXT_A(global) DESCA( CTXT_ ) The BLACS context handle , indicating
0047  *     the BLACS process grid A is distribu -
0048  *     ted over. The context itself is glo -
0049  *     bal , but the handle(the integer
0050  *     value) may vary.
0051  *     M_A(global) DESCA( M_ ) The number of rows in the global
0052  *     array A.
0053  *     N_A(global) DESCA( N_ ) The number of columns in the global
0054  *     array A.
0055  *     MB_A(global) DESCA( MB_ ) The blocking factor used to distribute
0056  *     the rows of the array.
0057  *     NB_A(global) DESCA( NB_ ) The blocking factor used to distribute
0058  *     the columns of the array.
0059  *     RSRC_A(global) DESCA( RSRC_ ) The process row over which the first
0060  *     row of the array A is distributed.
0061  *     CSRC_A(global) DESCA( CSRC_ ) The process column over which the
0062  *     first column of the array A is
0063  *     distributed.
0064  *     LLD_A(local) DESCA( LLD_ ) The leading dimension of the local
0065  *     array. LLD_A >= MAX(1 , LOCr(M_A)).
0066  
0067  *     Let K be the number of rows or columns of a distributed matrix ,
0068  *     and assume that its process grid has dimension p x q.
0069  *     LOCr( K ) denotes the number of elements of K that a process
0070  *     would receive if K were distributed over the p processes of its
0071  *     process column.
0072  *     Similarly , LOCc( K ) denotes the number of elements of K that a
0073  *     process would receive if K were distributed over the q processes of
0074  *     its process row.
0075  *     The values of LOCr() and LOCc() may be determined via a call to the
0076  *     ScaLAPACK tool function , NUMROC :
0077  *     LOCr( M ) = NUMROC( M , MB_A , MYROW , RSRC_A , NPROW ) ,
0078  *     LOCc( N ) = NUMROC( N , NB_A , MYCOL , CSRC_A , NPCOL ).
0079  *     An upper bound for these quantities may be computed by :
0080  *     LOCr( M ) <= ceil( ceil(M / MB_A) / NPROW )*MB_A
0081  *     LOCc( N ) <= ceil( ceil(N / NB_A) / NPCOL )*NB_A
0082  
0083  *     Arguments
0084  *     === ======
0085  
0086  *     WANTT(global input) LOGICAL
0087  *     = .TRUE. : the full Schur form T is required ;
0088  *     = .FALSE. : only eigenvalues are required.
0089  
0090  *     WANTZ(global input) LOGICAL
0091  *     = .TRUE. : the matrix of Schur vectors Z is required ;
0092  *     = .FALSE. : Schur vectors are not required.
0093  
0094  *     N(global input) INTEGER
0095  *     The order of the Hessenberg matrix A(and Z if WANTZ).
0096  *     N >= 0.
0097  
0098  *     ILO(global input) INTEGER
0099  *     IHI(global input) INTEGER
0100  *     It is assumed that A is already upper quasi - triangular in
0101  *     rows and columns IHI + 1 : N , and that A(ILO , ILO - 1) = 0(unless
0102  *     ILO = 1). PDLAHQR works primarily with the Hessenberg
0103  *     submatrix in rows and columns ILO to IHI , but applies
0104  *     transformations to all of H if WANTT is .TRUE..
0105  *     1 <= ILO <= max(1 , IHI) ; IHI <= N.
0106  
0107  *     A(global input / output) DOUBLE PRECISION array , dimension
0108  *     (DESCA(LLD_) ,*)
0109  *     On entry , the upper Hessenberg matrix A.
0110  *     On exit , if WANTT is .TRUE. , A is upper quasi - triangular in
0111  *     rows and columns ILO : IHI , with any 2 - by - 2 or larger diagonal
0112  *     blocks not yet in standard form. If WANTT is .FALSE. , the
0113  *     contents of A are unspecified on exit.
0114  
0115  *     DESCA(global and local input) INTEGER array of dimension DLEN_.
0116  *     The array descriptor for the distributed matrix A.
0117  
0118  *     WR(global replicated output) DOUBLE PRECISION array ,
0119  *     dimension(N)
0120  *     WI(global replicated output) DOUBLE PRECISION array ,
0121  *     dimension(N)
0122  *     The real and imaginary parts , respectively , of the computed
0123  *     eigenvalues ILO to IHI are stored in the corresponding
0124  *     elements of WR and WI. If two eigenvalues are computed as a
0125  *     complex conjugate pair , they are stored in consecutive
0126  *     elements of WR and WI , say the i - th and(i + 1)th , with
0127  *     WI(i) > 0 and WI(i + 1) < 0. If WANTT is .TRUE. , the
0128  *     eigenvalues are stored in the same order as on the diagonal
0129  *     of the Schur form returned in A. A may be returned with
0130  *     larger diagonal blocks until the next release.
0131  
0132  *     ILOZ(global input) INTEGER
0133  *     IHIZ(global input) INTEGER
0134  *     Specify the rows of Z to which transformations must be
0135  *     applied if WANTZ is .TRUE..
0136  *     1 <= ILOZ <= ILO ; IHI <= IHIZ <= N.
0137  
0138  *     Z(global input / output) DOUBLE PRECISION array.
0139  *     If WANTZ is .TRUE. , on entry Z must contain the current
0140  *     matrix Z of transformations accumulated by PDHSEQR , and on
0141  *     exit Z has been updated ; transformations are applied only to
0142  *     the submatrix Z(ILOZ : IHIZ , ILO : IHI).
0143  *     If WANTZ is .FALSE. , Z is not referenced.
0144  
0145  *     DESCZ(global and local input) INTEGER array of dimension DLEN_.
0146  *     The array descriptor for the distributed matrix Z.
0147  
0148  *     WORK(local output) DOUBLE PRECISION array of size LWORK
0149  
0150  *     LWORK(local input) INTEGER
0151  *     WORK(LWORK) is a local array and LWORK is assumed big enough
0152  *     so that LWORK >= 3*N +
0153  *     MAX( 2*MAX(DESCZ(LLD_) , DESCA(LLD_)) + 2*LOCc(N) ,
0154  *     7*Ceil(N / HBL) / LCM(NPROW , NPCOL)) )
0155  
0156  *     IWORK(global and local input) INTEGER array of size ILWORK
0157  
0158  *     ILWORK(local input) INTEGER
0159  *     This holds the some of the IBLK integer arrays. This is held
0160  *     as a place holder for the next release.
0161  
0162  *     INFO(global output) INTEGER
0163  *     < 0 : parameter number - INFO incorrect or inconsistent
0164  *     = 0 : successful exit
0165  *     > 0 : PDLAHQR failed to compute all the eigenvalues ILO to IHI
0166  *     in a total of 30*(IHI - ILO + 1) iterations ; if INFO = i ,
0167  *     elements i + 1 : ihi of WR and WI contain those eigenvalues
0168  *     which have been successfully computed.
0169  
0170  *     Logic :
0171  *     This algorithm is very similar to _LAHQR. Unlike _LAHQR ,
0172  *     instead of sending one double shift through the largest
0173  *     unreduced submatrix , this algorithm sends multiple double shifts
0174  *     and spaces them apart so that there can be parallelism across
0175  *     several processor row / columns. Another critical difference is
0176  *     that this algorithm aggregrates multiple transforms together in
0177  *     order to apply them in a block fashion.
0178  
0179  *     Important Local Variables :
0180  *     IBLK = The maximum number of bulges that can be computed.
0181  *     Currently fixed. Future releases this won't be fixed.
0182  *     HBL = The square block size(HBL = DESCA(MB_) = DESCA(NB_))
0183  *     ROTN = The number of transforms to block together
0184  *     NBULGE = The number of bulges that will be attempted on the
0185  *     current submatrix.
0186  *     IBULGE = The current number of bulges started.
0187  *     K1(*) , K2(*) = The current bulge loops from K1(*) to K2(*).
0188  
0189  *     Subroutines :
0190  *     This routine calls :
0191  *     PDLACONSB -> To determine where to start each iteration
0192  *     PDLAWIL -> Given the shift , get the transformation
0193  *     DLASORTE -> Pair up eigenvalues so that reals are paired.
0194  *     PDLACP3 -> Parallel array to local replicated array copy &
0195  *     back.
0196  *     DLAREF -> Row / column reflector applier. Core routine
0197  *     here.
0198  *     PDLASMSUB -> Finds negligible subdiagonal elements.
0199  
0200  *     Current Notes and / or Restrictions :
0201  *     1.) This code requires the distributed block size to be square
0202  *     and at least six(6) ; unlike simpler codes like LU , this
0203  *     algorithm is extremely sensitive to block size. Unwise
0204  *     choices of too small a block size can lead to bad
0205  *     performance.
0206  *     2.) This code requires A and Z to be distributed identically
0207  *     and have identical contxts.
0208  *     3.) This release currently does not have a routine for
0209  *     resolving the Schur blocks into regular 2x2 form after
0210  *     this code is completed. Because of this , a significant
0211  *     performance impact is required while the deflation is done
0212  *     by sometimes a single column of processors.
0213  *     4.) This code does not currently block the initial transforms
0214  *     so that none of the rows or columns for any bulge are
0215  *     completed until all are started. To offset pipeline
0216  *     start - up it is recommended that at least 2*LCM(NPROW , NPCOL)
0217  *     bulges are used(if possible)
0218  *     5.) The maximum number of bulges currently supported is fixed at
0219  *     32. In future versions this will be limited only by the
0220  *     incoming WORK array.
0221  *     6.) The matrix A must be in upper Hessenberg form. If elements
0222  *     below the subdiagonal are nonzero , the resulting transforms
0223  *     may be nonsimilar. This is also true with the LAPACK
0224  *     routine.
0225  *     7.) For this release , it is assumed RSRC_ = CSRC_ = 0
0226  *     8.) Currently , all the eigenvalues are distributed to all the
0227  *     nodes. Future releases will probably distribute the
0228  *     eigenvalues by the column partitioning.
0229  *     9.) The internals of this routine are subject to change.
0230  
0231  *     Implemented by : G. Henry , November 17 , 1996
0232  
0233  *     === ==================================================================
0234  
0235  *     .. Parameters ..
0236        INTEGER BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ ,
0237       $LLD_ , MB_ , M_ , NB_ , N_ , RSRC_
0238        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
0239       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
0240       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
0241        DOUBLE PRECISION ZERO , ONE , HALF
0242        PARAMETER( ZERO = 0.0D + 0 , ONE = 1.0D + 0 , HALF = 0.5D + 0 )
0243        DOUBLE PRECISION CONST
0244        PARAMETER( CONST = 1.50D + 0 )
0245        INTEGER IBLK
0246        PARAMETER( IBLK = 32 )
0247        END IF
0248        ELSE IF( M.GT.L ) THEN
0249            IF( MOD( K - 1 , HBL ).GT.0 ) THEN
0250                A(( ICOL1 - 2 )*LDA + IROW1 ) = - A(( ICOL1 - 2 )*
0251       $        LDA + IROW1 )
0252            END IF
0253        END IF
0254        V2 = VCOPY( 2 )
0255        T2 = T1COPY*V2
0256        WORK( VECSIDX + ( K - 1 )*3 + 1 ) = VCOPY( 2 )
0257        WORK( VECSIDX + ( K - 1 )*3 + 2 ) = VCOPY( 3 )
0258        WORK( VECSIDX + ( K - 1 )*3 + 3 ) = T1COPY
0259        T1 = T1COPY
0260        IF( K.LT.ISTOP ) THEN
0261  
0262  *         Do some work so next step is ready...
0263  
0264            V3 = VCOPY( 3 )
0265            T3 = T1*V3
0266            DO 50 J = ICOL1 , MIN( K2( KI ) + 1 , I - 1 ) +
0267       $        ICOL1 - K
0268                SUM = A(( J - 1 )*LDA + IROW1 ) +
0269       $        V2*A(( J - 1 )*LDA + IROW1 + 1 ) +
0270       $        V3*A(( J - 1 )*LDA + IROW1 + 2 )
0271                A(( J - 1 )*LDA + IROW1 ) = A(( J - 1 )*LDA +
0272       $        IROW1 ) - SUM*T1
0273                A(( J - 1 )*LDA + IROW1 + 1 ) = A(( J - 1 )*LDA +
0274       $        IROW1 + 1 ) - SUM*T2
0275                A(( J - 1 )*LDA + IROW1 + 2 ) = A(( J - 1 )*LDA +
0276       $        IROW1 + 2 ) - SUM*T3
0277     50     CONTINUE
0278            ITMP1 = LOCALK2( KI )
0279            DO 60 J = IROW1 + 1 , IROW1 + 3
0280                SUM = A(( ICOL1 - 1 )*LDA + J ) +
0281       $        V2*A( ICOL1*LDA + J ) +
0282       $        V3*A(( ICOL1 + 1 )*LDA + J )
0283                A(( ICOL1 - 1 )*LDA + J ) = A(( ICOL1 - 1 )*LDA +
0284       $        J ) - SUM*T1
0285                A( ICOL1*LDA + J ) = A( ICOL1*LDA + J ) - SUM*T2
0286                A(( ICOL1 + 1 )*LDA + J ) = A(( ICOL1 + 1 )*LDA +
0287       $        J ) - SUM*T3
0288     60     CONTINUE
0289        END IF
0290        IROW1 = IROW1 + 1
0291        ICOL1 = ICOL1 + 1
0292     70 CONTINUE
0293        END IF
0294  
0295        IF( MODKM1.EQ.HBL - 2 ) THEN
0296            IF(( DOWN.EQ.ICURROW( KI ) ) .AND.
0297       $( RIGHT.EQ.ICURCOL( KI ) ) .AND.( NUM.GT.1 ) )
0298       $    THEN
0299            CALL DGERV2D( CONTXT , 3 , 1 ,
0300       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) , 3 ,
0301       $    DOWN , RIGHT )
0302        END IF
0303        IF(( MYROW.EQ.ICURROW( KI ) ) .AND.
0304       $( MYCOL.EQ.ICURCOL( KI ) ) .AND.( NUM.GT.1 ) )
0305       $THEN
0306        CALL DGESD2D( CONTXT , 3 , 1 ,
0307       $WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) , 3 ,
0308       $UP , LEFT )
0309        END IF
0310        IF(( DOWN.EQ.ICURROW( KI ) ) .AND.
0311       $( NPCOL.GT.1 ) .AND.( ISTART.LE.ISTOP ) ) THEN
0312        JJ = MOD( ICURCOL( KI ) + NPCOL - 1 , NPCOL )
0313        IF( MYCOL.NE.JJ ) THEN
0314            CALL DGEBR2D( CONTXT , 'ROW' , ' ' ,
0315       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0316       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0317       $    3*( ISTOP - ISTART + 1 ) , MYROW , JJ )
0318        ELSE
0319            CALL DGEBS2D( CONTXT , 'ROW' , ' ' ,
0320       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0321       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0322       $    3*( ISTOP - ISTART + 1 ) )
0323        END IF
0324        END IF
0325        END IF
0326  
0327  *     Broadcast Householder information from the block
0328  
0329        IF(( MYROW.EQ.ICURROW( KI ) ) .AND.( NPCOL.GT.1 ) .AND.
0330       $( ISTART.LE.ISTOP ) ) THEN
0331        IF( MYCOL.NE.ICURCOL( KI ) ) THEN
0332            CALL DGEBR2D( CONTXT , 'ROW' , ' ' ,
0333       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0334       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0335       $    3*( ISTOP - ISTART + 1 ) , MYROW ,
0336       $    ICURCOL( KI ) )
0337        ELSE
0338            CALL DGEBS2D( CONTXT , 'ROW' , ' ' ,
0339       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0340       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0341       $    3*( ISTOP - ISTART + 1 ) )
0342        END IF
0343        END IF
0344     80 CONTINUE
0345  
0346  *     Now do column transforms and finish work
0347  
0348        DO 90 KI = 1 , IBULGE
0349  
0350            ISTART = MAX( K1( KI ) , M )
0351            ISTOP = MIN( K2( KI ) , I - 1 )
0352  
0353            IF( MOD( ISTART - 1 , HBL ).EQ.HBL - 2 ) THEN
0354                IF(( RIGHT.EQ.ICURCOL( KI ) ) .AND.
0355       $( NPROW.GT.1 ) .AND.( ISTART.LE.ISTOP ) ) THEN
0356                JJ = MOD( ICURROW( KI ) + NPROW - 1 , NPROW )
0357                IF( MYROW.NE.JJ ) THEN
0358                    CALL DGEBR2D( CONTXT , 'COL' , ' ' ,
0359       $            3*( ISTOP - ISTART + 1 ) , 1 ,
0360       $            WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0361       $            3*( ISTOP - ISTART + 1 ) , JJ , MYCOL )
0362                ELSE
0363                    CALL DGEBS2D( CONTXT , 'COL' , ' ' ,
0364       $            3*( ISTOP - ISTART + 1 ) , 1 ,
0365       $            WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0366       $            3*( ISTOP - ISTART + 1 ) )
0367                END IF
0368            END IF
0369        END IF
0370  
0371        IF(( MYCOL.EQ.ICURCOL( KI ) ) .AND.( NPROW.GT.1 ) .AND.
0372       $( ISTART.LE.ISTOP ) ) THEN
0373        IF( MYROW.NE.ICURROW( KI ) ) THEN
0374            CALL DGEBR2D( CONTXT , 'COL' , ' ' ,
0375       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0376       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0377       $    3*( ISTOP - ISTART + 1 ) , ICURROW( KI ) ,
0378       $    MYCOL )
0379        ELSE
0380            CALL DGEBS2D( CONTXT , 'COL' , ' ' ,
0381       $    3*( ISTOP - ISTART + 1 ) , 1 ,
0382       $    WORK( VECSIDX + ( ISTART - 1 )*3 + 1 ) ,
0383       $    3*( ISTOP - ISTART + 1 ) )
0384        END IF
0385        END IF
0386     90 CONTINUE
0387  
0388  *     Now do make up work to have things in block fashion
0389  
0390        DO 150 KI = 1 , IBULGE
0391            ISTART = MAX( K1( KI ) , M )
0392            ISTOP = MIN( K2( KI ) , I - 1 )
0393  
0394            MODKM1 = MOD( ISTART - 1 , HBL )
0395            IF(( MYROW.EQ.ICURROW( KI ) ) .AND.
0396       $( MYCOL.EQ.ICURCOL( KI ) ) .AND.
0397       $( MODKM1.EQ.HBL - 2 ) .AND.( ISTART.LT.I - 1 ) ) THEN
0398            K = ISTART
0399  
0400  *         Catch up on column & border work
0401  
0402            NR = MIN( 3 , I - K + 1 )
0403            V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0404            V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0405            T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0406            IF( NR.EQ.3 ) THEN
0407  
0408  *             Do some work so next step is ready...
0409  
0410  *             V3 = VCOPY( 3 )
0411                T2 = T1*V2
0412                T3 = T1*V3
0413                ITMP1 = MIN( 6 , I2 + 2 - K )
0414                ITMP2 = MAX( I1 - K + 2 , 1 )
0415                DO 100 J = 2 , ITMP1
0416                    SUM = SMALLA( 2 , J , KI ) +
0417       $            V2*SMALLA( 3 , J , KI ) +
0418       $            V3*SMALLA( 4 , J , KI )
0419                    SMALLA( 2 , J , KI ) = SMALLA( 2 , J , KI ) - SUM*T1
0420                    SMALLA( 3 , J , KI ) = SMALLA( 3 , J , KI ) - SUM*T2
0421                    SMALLA( 4 , J , KI ) = SMALLA( 4 , J , KI ) - SUM*T3
0422    100         CONTINUE
0423                DO 110 J = ITMP2 , 5
0424                    SUM = SMALLA( J , 2 , KI ) +
0425       $            V2*SMALLA( J , 3 , KI ) +
0426       $            V3*SMALLA( J , 4 , KI )
0427                    SMALLA( J , 2 , KI ) = SMALLA( J , 2 , KI ) - SUM*T1
0428                    SMALLA( J , 3 , KI ) = SMALLA( J , 3 , KI ) - SUM*T2
0429                    SMALLA( J , 4 , KI ) = SMALLA( J , 4 , KI ) - SUM*T3
0430    110         CONTINUE
0431            END IF
0432        END IF
0433  
0434        IF(( MOD( ISTART - 1 , HBL ).EQ.HBL - 1 ) .AND.
0435       $( ISTART.LE.ISTOP ) .AND.
0436       $( MYROW.EQ.ICURROW( KI ) ) .AND.
0437       $( MYCOL.EQ.ICURCOL( KI ) ) ) THEN
0438        K = ISTOP
0439  
0440  *     Catch up on column & border work
0441  
0442        NR = MIN( 3 , I - K + 1 )
0443        V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0444        V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0445        T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0446        IF( NR.EQ.3 ) THEN
0447  
0448  *         Do some work so next step is ready...
0449  
0450  *         V3 = VCOPY( 3 )
0451            T2 = T1*V2
0452            T3 = T1*V3
0453            ITMP1 = MIN( 6 , I2 - K + 3 )
0454            ITMP2 = MAX( I1 - K + 3 , 1 )
0455            DO 120 J = 3 , ITMP1
0456                SUM = SMALLA( 3 , J , KI ) +
0457       $        V2*SMALLA( 4 , J , KI ) +
0458       $        V3*SMALLA( 5 , J , KI )
0459                SMALLA( 3 , J , KI ) = SMALLA( 3 , J , KI ) - SUM*T1
0460                SMALLA( 4 , J , KI ) = SMALLA( 4 , J , KI ) - SUM*T2
0461                SMALLA( 5 , J , KI ) = SMALLA( 5 , J , KI ) - SUM*T3
0462    120     CONTINUE
0463            DO 130 J = ITMP2 , 6
0464                SUM = SMALLA( J , 3 , KI ) +
0465       $        V2*SMALLA( J , 4 , KI ) +
0466       $        V3*SMALLA( J , 5 , KI )
0467                SMALLA( J , 3 , KI ) = SMALLA( J , 3 , KI ) - SUM*T1
0468                SMALLA( J , 4 , KI ) = SMALLA( J , 4 , KI ) - SUM*T2
0469                SMALLA( J , 5 , KI ) = SMALLA( J , 5 , KI ) - SUM*T3
0470    130     CONTINUE
0471        END IF
0472        END IF
0473  
0474        MODKM1 = MOD( ISTART - 1 , HBL )
0475        IF(( MYROW.EQ.ICURROW( KI ) ) .AND.
0476       $( MYCOL.EQ.ICURCOL( KI ) ) .AND.
0477       $((( MODKM1.EQ.HBL - 2 ) .AND.( ISTART.EQ.I -
0478       $1 ) ) .OR.(( MODKM1.LT.HBL - 2 ) .AND.( ISTART.LE.I -
0479       $1 ) ) ) ) THEN
0480  
0481  *     (IROW1 , ICOL1) is(I , J) - coordinates of H(ISTART , ISTART)
0482  
0483        IROW1 = KROW( KI )
0484        ICOL1 = LOCALK2( KI )
0485        DO 140 K = ISTART , ISTOP
0486  
0487  *         Catch up on column & border work
0488  
0489            NR = MIN( 3 , I - K + 1 )
0490            V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0491            V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0492            T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0493            IF( K.LT.ISTOP ) THEN
0494  
0495  *             Do some work so next step is ready...
0496  
0497                T2 = T1*V2
0498                T3 = T1*V3
0499                CALL DLAREF ( 'Col' , A , LDA , .FALSE. , Z , LDZ ,
0500       $        .FALSE. , ICOL1 , ICOL1 , ISTART ,
0501       $        ISTOP , MIN( ISTART + 1 , I ) - K + IROW1 ,
0502       $        IROW1 , LILOZ , LIHIZ ,
0503       $        WORK( VECSIDX + 1 ) , V2 , V3 , T1 , T2 ,
0504       $        T3 )
0505                IROW1 = IROW1 + 1
0506                ICOL1 = ICOL1 + 1
0507            ELSE
0508                IF(( NR.EQ.3 ) .AND.( MOD( K - 1 ,
0509       $        HBL ).LT.HBL - 2 ) ) THEN
0510                T2 = T1*V2
0511                T3 = T1*V3
0512                CALL DLAREF ( 'Row' , A , LDA , .FALSE. , Z , LDZ ,
0513       $        .FALSE. , IROW1 , IROW1 , ISTART ,
0514       $        ISTOP , ICOL1 , MIN( MIN( K2( KI )
0515       $        + 1 , I - 1 ) , I2 ) - K + ICOL1 , LILOZ ,
0516       $        LIHIZ , WORK( VECSIDX + 1 ) , V2 ,
0517       $        V3 , T1 , T2 , T3 )
0518            END IF
0519        END IF
0520    140 CONTINUE
0521        END IF
0522  
0523  *     Send SMALLA back again.
0524  
0525        K = ISTART
0526        MODKM1 = MOD( K - 1 , HBL )
0527        IF(( MODKM1.GE.HBL - 2 ) .AND.( K.LE.I - 1 ) ) THEN
0528            IF(( MODKM1.EQ.HBL - 2 ) .AND.( K.LT.I - 1 ) ) THEN
0529  
0530  *             Copy 6 elements from global A(K - 1 : K + 4 , K - 1 : K + 4)
0531  
0532                CALL INFOG2L( K + 2 , K + 2 , DESCA , NPROW , NPCOL , MYROW ,
0533       $        MYCOL , IROW1 , ICOL1 , ITMP1 , ITMP2 )
0534                CALL PDLACP3 ( MIN( 6 , N - K + 2 ) , K - 1 , A , DESCA ,
0535       $        SMALLA( 1 , 1 , KI ) , 6 , ITMP1 , ITMP2 ,
0536       $        1 )
0537  
0538            END IF
0539            IF( MODKM1.EQ.HBL - 1 ) THEN
0540  
0541  *             Copy 6 elements from global A(K - 2 : K + 3 , K - 2 : K + 3)
0542  
0543                CALL INFOG2L( K + 1 , K + 1 , DESCA , NPROW , NPCOL , MYROW ,
0544       $        MYCOL , IROW1 , ICOL1 , ITMP1 , ITMP2 )
0545                CALL PDLACP3 ( MIN( 6 , N - K + 3 ) , K - 2 , A , DESCA ,
0546       $        SMALLA( 1 , 1 , KI ) , 6 , ITMP1 , ITMP2 ,
0547       $        1 )
0548            END IF
0549        END IF
0550  
0551    150 CONTINUE
0552  
0553  *     Now start major set of block ROW reflections
0554  
0555        DO 160 KI = 1 , IBULGE
0556            IF(( MYROW.NE.ICURROW( KI ) ) .AND.
0557       $( DOWN.NE.ICURROW( KI ) ) )GO TO 160
0558            ISTART = MAX( K1( KI ) , M )
0559            ISTOP = MIN( K2( KI ) , I - 1 )
0560  
0561            IF(( ISTOP.GT.ISTART ) .AND.
0562       $( MOD( ISTART - 1 , HBL ).LT.HBL - 2 ) .AND.
0563       $( ICURROW( KI ).EQ.MYROW ) ) THEN
0564            IROW1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0565            CALL INFOG1L( IROW1 , HBL , NPCOL , MYCOL , 0 , ITMP1 ,
0566       $    ITMP2 )
0567            ITMP2 = NUMROC( I2 , HBL , MYCOL , 0 , NPCOL )
0568            II = KROW( KI )
0569            CALL DLAREF ( 'Row' , A , LDA , WANTZ , Z , LDZ , .TRUE. , II ,
0570       $    II , ISTART , ISTOP , ITMP1 , ITMP2 , LILOZ ,
0571       $    LIHIZ , WORK( VECSIDX + 1 ) , V2 , V3 , T1 , T2 ,
0572       $    T3 )
0573        END IF
0574    160 CONTINUE
0575  
0576        DO 180 KI = 1 , IBULGE
0577            IF( KROW( KI ).GT.KP2ROW( KI ) )
0578       $        GO TO 180
0579                IF(( MYROW.NE.ICURROW( KI ) ) .AND.
0580       $( DOWN.NE.ICURROW( KI ) ) )GO TO 180
0581                ISTART = MAX( K1( KI ) , M )
0582                ISTOP = MIN( K2( KI ) , I - 1 )
0583                IF(( ISTART.EQ.ISTOP ) .OR.
0584       $( MOD( ISTART - 1 , HBL ).GE.HBL - 2 ) .OR.
0585       $( ICURROW( KI ).NE.MYROW ) ) THEN
0586                DO 170 K = ISTART , ISTOP
0587                    V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0588                    V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0589                    T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0590                    NR = MIN( 3 , I - K + 1 )
0591                    IF(( NR.EQ.3 ) .AND.( KROW( KI ).LE.
0592       $            KP2ROW( KI ) ) ) THEN
0593                    IF(( K.LT.ISTOP ) .AND.
0594       $( MOD( K - 1 , HBL ).LT.HBL - 2 ) ) THEN
0595                    ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0596                ELSE
0597                    IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0598                        ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0599                    END IF
0600                    IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0601                        ITMP1 = MIN( K + 4 , I2 ) + 1
0602                    END IF
0603                    IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
0604                        ITMP1 = MIN( K + 3 , I2 ) + 1
0605                    END IF
0606                END IF
0607  
0608  *             Find local coor of rows K through K + 2
0609  
0610                IROW1 = KROW( KI )
0611                IROW2 = KP2ROW( KI )
0612                CALL INFOG1L( ITMP1 , HBL , NPCOL , MYCOL , 0 ,
0613       $        ICOL1 , ICOL2 )
0614                ICOL2 = NUMROC( I2 , HBL , MYCOL , 0 , NPCOL )
0615                IF(( MOD( K - 1 , HBL ).LT.HBL - 2 ) .OR.
0616       $( NPROW.EQ.1 ) ) THEN
0617                T2 = T1*V2
0618                T3 = T1*V3
0619                CALL DLAREF ( 'Row' , A , LDA , WANTZ , Z , LDZ ,
0620       $        .FALSE. , IROW1 , IROW1 , ISTART ,
0621       $        ISTOP , ICOL1 , ICOL2 , LILOZ ,
0622       $        LIHIZ , WORK( VECSIDX + 1 ) , V2 ,
0623       $        V3 , T1 , T2 , T3 )
0624            END IF
0625            IF(( MOD( K - 1 , HBL ).EQ.HBL - 2 ) .AND.
0626       $( NPROW.GT.1 ) ) THEN
0627            IF( IROW1.EQ.IROW2 ) THEN
0628                CALL DGESD2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0629       $        A(( ICOL1 - 1 )*LDA + IROW2 ) ,
0630       $        LDA , UP , MYCOL )
0631            END IF
0632        END IF
0633        IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
0634       $( NPROW.GT.1 ) ) THEN
0635        IF( IROW1.EQ.IROW2 ) THEN
0636            CALL DGESD2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0637       $    A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0638       $    LDA , DOWN , MYCOL )
0639        END IF
0640        END IF
0641        END IF
0642    170 CONTINUE
0643        END IF
0644    180 CONTINUE
0645  
0646        DO 220 KI = 1 , IBULGE
0647            IF( KROW( KI ).GT.KP2ROW( KI ) )
0648       $        GO TO 220
0649                IF(( MYROW.NE.ICURROW( KI ) ) .AND.
0650       $( DOWN.NE.ICURROW( KI ) ) )GO TO 220
0651                ISTART = MAX( K1( KI ) , M )
0652                ISTOP = MIN( K2( KI ) , I - 1 )
0653                IF(( ISTART.EQ.ISTOP ) .OR.
0654       $( MOD( ISTART - 1 , HBL ).GE.HBL - 2 ) .OR.
0655       $( ICURROW( KI ).NE.MYROW ) ) THEN
0656                DO 210 K = ISTART , ISTOP
0657                    V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0658                    V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0659                    T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0660                    NR = MIN( 3 , I - K + 1 )
0661                    IF(( NR.EQ.3 ) .AND.( KROW( KI ).LE.
0662       $            KP2ROW( KI ) ) ) THEN
0663                    IF(( K.LT.ISTOP ) .AND.
0664       $( MOD( K - 1 , HBL ).LT.HBL - 2 ) ) THEN
0665                    ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0666                ELSE
0667                    IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0668                        ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0669                    END IF
0670                    IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0671                        ITMP1 = MIN( K + 4 , I2 ) + 1
0672                    END IF
0673                    IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
0674                        ITMP1 = MIN( K + 3 , I2 ) + 1
0675                    END IF
0676                END IF
0677  
0678                IROW1 = KROW( KI ) + K - ISTART
0679                IROW2 = KP2ROW( KI ) + K - ISTART
0680                CALL INFOG1L( ITMP1 , HBL , NPCOL , MYCOL , 0 ,
0681       $        ICOL1 , ICOL2 )
0682                ICOL2 = NUMROC( I2 , HBL , MYCOL , 0 , NPCOL )
0683                IF(( MOD( K - 1 , HBL ).EQ.HBL - 2 ) .AND.
0684       $( NPROW.GT.1 ) ) THEN
0685                IF( IROW1.NE.IROW2 ) THEN
0686                    CALL DGERV2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0687       $            WORK( IRBUF + 1 ) , 1 , DOWN ,
0688       $            MYCOL )
0689                    T2 = T1*V2
0690                    T3 = T1*V3
0691                    DO 190 J = ICOL1 , ICOL2
0692                        SUM = A(( J - 1 )*LDA + IROW1 ) +
0693       $                V2*A(( J - 1 )*LDA + IROW1 + 1 ) +
0694       $                V3*WORK( IRBUF + J - ICOL1 + 1 )
0695                        A(( J - 1 )*LDA + IROW1 ) = A(( J - 1 )*
0696       $                LDA + IROW1 ) - SUM*T1
0697                        A(( J - 1 )*LDA + IROW1 + 1 ) = A(( J - 1 )*
0698       $                LDA + IROW1 + 1 ) - SUM*T2
0699                        WORK( IRBUF + J - ICOL1 + 1 ) = WORK( IRBUF +
0700       $                J - ICOL1 + 1 ) - SUM*T3
0701    190             CONTINUE
0702                    CALL DGESD2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0703       $            WORK( IRBUF + 1 ) , 1 , DOWN ,
0704       $            MYCOL )
0705                END IF
0706            END IF
0707            IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
0708       $( NPROW.GT.1 ) ) THEN
0709            IF( IROW1.NE.IROW2 ) THEN
0710                CALL DGERV2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0711       $        WORK( IRBUF + 1 ) , 1 , UP ,
0712       $        MYCOL )
0713                T2 = T1*V2
0714                T3 = T1*V3
0715                DO 200 J = ICOL1 , ICOL2
0716                    SUM = WORK( IRBUF + J - ICOL1 + 1 ) +
0717       $            V2*A(( J - 1 )*LDA + IROW1 ) +
0718       $            V3*A(( J - 1 )*LDA + IROW1 + 1 )
0719                    WORK( IRBUF + J - ICOL1 + 1 ) = WORK( IRBUF +
0720       $            J - ICOL1 + 1 ) - SUM*T1
0721                    A(( J - 1 )*LDA + IROW1 ) = A(( J - 1 )*
0722       $            LDA + IROW1 ) - SUM*T2
0723                    A(( J - 1 )*LDA + IROW1 + 1 ) = A(( J - 1 )*
0724       $            LDA + IROW1 + 1 ) - SUM*T3
0725    200         CONTINUE
0726                CALL DGESD2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0727       $        WORK( IRBUF + 1 ) , 1 , UP ,
0728       $        MYCOL )
0729            END IF
0730        END IF
0731        END IF
0732    210 CONTINUE
0733        END IF
0734    220 CONTINUE
0735  
0736        DO 240 KI = 1 , IBULGE
0737            IF( KROW( KI ).GT.KP2ROW( KI ) )
0738       $        GO TO 240
0739                IF(( MYROW.NE.ICURROW( KI ) ) .AND.
0740       $( DOWN.NE.ICURROW( KI ) ) )GO TO 240
0741                ISTART = MAX( K1( KI ) , M )
0742                ISTOP = MIN( K2( KI ) , I - 1 )
0743                IF(( ISTART.EQ.ISTOP ) .OR.
0744       $( MOD( ISTART - 1 , HBL ).GE.HBL - 2 ) .OR.
0745       $( ICURROW( KI ).NE.MYROW ) ) THEN
0746                DO 230 K = ISTART , ISTOP
0747                    V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0748                    V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0749                    T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0750                    NR = MIN( 3 , I - K + 1 )
0751                    IF(( NR.EQ.3 ) .AND.( KROW( KI ).LE.
0752       $            KP2ROW( KI ) ) ) THEN
0753                    IF(( K.LT.ISTOP ) .AND.
0754       $( MOD( K - 1 , HBL ).LT.HBL - 2 ) ) THEN
0755                    ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0756                ELSE
0757                    IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0758                        ITMP1 = MIN( K2( KI ) + 1 , I - 1 ) + 1
0759                    END IF
0760                    IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0761                        ITMP1 = MIN( K + 4 , I2 ) + 1
0762                    END IF
0763                    IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
0764                        ITMP1 = MIN( K + 3 , I2 ) + 1
0765                    END IF
0766                END IF
0767  
0768                IROW1 = KROW( KI ) + K - ISTART
0769                IROW2 = KP2ROW( KI ) + K - ISTART
0770                CALL INFOG1L( ITMP1 , HBL , NPCOL , MYCOL , 0 ,
0771       $        ICOL1 , ICOL2 )
0772                ICOL2 = NUMROC( I2 , HBL , MYCOL , 0 , NPCOL )
0773                IF(( MOD( K - 1 , HBL ).EQ.HBL - 2 ) .AND.
0774       $( NPROW.GT.1 ) ) THEN
0775                IF( IROW1.EQ.IROW2 ) THEN
0776                    CALL DGERV2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0777       $            A(( ICOL1 - 1 )*LDA + IROW2 ) ,
0778       $            LDA , UP , MYCOL )
0779                END IF
0780            END IF
0781            IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
0782       $( NPROW.GT.1 ) ) THEN
0783            IF( IROW1.EQ.IROW2 ) THEN
0784                CALL DGERV2D( CONTXT , 1 , ICOL2 - ICOL1 + 1 ,
0785       $        A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0786       $        LDA , DOWN , MYCOL )
0787            END IF
0788        END IF
0789        END IF
0790    230 CONTINUE
0791        END IF
0792    240 CONTINUE
0793    250 CONTINUE
0794  
0795  *     Now start major set of block COL reflections
0796  
0797        DO 260 KI = 1 , IBULGE
0798            IF(( MYCOL.NE.ICURCOL( KI ) ) .AND.
0799       $( RIGHT.NE.ICURCOL( KI ) ) )GO TO 260
0800            ISTART = MAX( K1( KI ) , M )
0801            ISTOP = MIN( K2( KI ) , I - 1 )
0802  
0803            IF((( MOD( ISTART - 1 , HBL ).LT.HBL - 2 ) .OR.( NPCOL.EQ.
0804       $    1 ) ) .AND.( ICURCOL( KI ).EQ.MYCOL ) .AND.
0805       $( I - ISTOP + 1.GE.3 ) ) THEN
0806            K = ISTART
0807            IF(( K.LT.ISTOP ) .AND.( MOD( K - 1 ,
0808       $    HBL ).LT.HBL - 2 ) ) THEN
0809            ITMP1 = MIN( ISTART + 1 , I ) - 1
0810        ELSE
0811            IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0812                ITMP1 = MIN( K + 3 , I )
0813            END IF
0814            IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0815                ITMP1 = MAX( I1 , K - 1 ) - 1
0816            END IF
0817            IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
0818                ITMP1 = MAX( I1 , K - 2 ) - 1
0819            END IF
0820        END IF
0821  
0822        ICOL1 = KCOL( KI )
0823        CALL INFOG1L( I1 , HBL , NPROW , MYROW , 0 , IROW1 , IROW2 )
0824        IROW2 = NUMROC( ITMP1 , HBL , MYROW , 0 , NPROW )
0825        IF( IROW1.LE.IROW2 ) THEN
0826            ITMP2 = IROW2
0827        ELSE
0828            ITMP2 = - 1
0829        END IF
0830        CALL DLAREF ( 'Col' , A , LDA , WANTZ , Z , LDZ , .TRUE. ,
0831       $ICOL1 , ICOL1 , ISTART , ISTOP , IROW1 ,
0832       $IROW2 , LILOZ , LIHIZ , WORK( VECSIDX + 1 ) ,
0833       $V2 , V3 , T1 , T2 , T3 )
0834        K = ISTOP
0835        IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0836  
0837  *         Do from ITMP1 + 1 to MIN(K + 3 , I)
0838  
0839            IF( MOD( K - 1 , HBL ).LT.HBL - 3 ) THEN
0840                IROW1 = ITMP2 + 1
0841                IF( MOD(( ITMP1 / HBL ) , NPROW ).EQ.MYROW )
0842       $            THEN
0843                    IF( ITMP2.GT.0 ) THEN
0844                        IROW2 = ITMP2 + MIN( K + 3 , I ) - ITMP1
0845                    ELSE
0846                        IROW2 = IROW1 - 1
0847                    END IF
0848                ELSE
0849                    IROW2 = IROW1 - 1
0850                END IF
0851            ELSE
0852                CALL INFOG1L( ITMP1 + 1 , HBL , NPROW , MYROW , 0 ,
0853       $        IROW1 , IROW2 )
0854                IROW2 = NUMROC( MIN( K + 3 , I ) , HBL , MYROW , 0 ,
0855       $        NPROW )
0856            END IF
0857            V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0858            V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0859            T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0860            T2 = T1*V2
0861            T3 = T1*V3
0862            ICOL1 = KCOL( KI ) + ISTOP - ISTART
0863            CALL DLAREF ( 'Col' , A , LDA , .FALSE. , Z , LDZ ,
0864       $    .FALSE. , ICOL1 , ICOL1 , ISTART , ISTOP ,
0865       $    IROW1 , IROW2 , LILOZ , LIHIZ ,
0866       $    WORK( VECSIDX + 1 ) , V2 , V3 , T1 , T2 ,
0867       $    T3 )
0868        END IF
0869        END IF
0870    260 CONTINUE
0871  
0872        DO 320 KI = 1 , IBULGE
0873            IF( KCOL( KI ).GT.KP2COL( KI ) )
0874       $        GO TO 320
0875                IF(( MYCOL.NE.ICURCOL( KI ) ) .AND.
0876       $( RIGHT.NE.ICURCOL( KI ) ) )GO TO 320
0877                ISTART = MAX( K1( KI ) , M )
0878                ISTOP = MIN( K2( KI ) , I - 1 )
0879                IF( MOD( ISTART - 1 , HBL ).GE.HBL - 2 ) THEN
0880  
0881  *                 INFO is found in a buffer
0882  
0883                    ISPEC = 1
0884                ELSE
0885  
0886  *                 All INFO is local
0887  
0888                    ISPEC = 0
0889                END IF
0890  
0891                DO 310 K = ISTART , ISTOP
0892  
0893                    V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
0894                    V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
0895                    T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
0896                    NR = MIN( 3 , I - K + 1 )
0897                    IF(( NR.EQ.3 ) .AND.( KCOL( KI ).LE.KP2COL( KI ) ) )
0898       $                THEN
0899  
0900                        IF(( K.LT.ISTOP ) .AND.
0901       $( MOD( K - 1 , HBL ).LT.HBL - 2 ) ) THEN
0902                        ITMP1 = MIN( ISTART + 1 , I ) - 1
0903                    ELSE
0904                        IF( MOD( K - 1 , HBL ).LT.HBL - 2 ) THEN
0905                            ITMP1 = MIN( K + 3 , I )
0906                        END IF
0907                        IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0908                            ITMP1 = MAX( I1 , K - 1 ) - 1
0909                        END IF
0910                        IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
0911                            ITMP1 = MAX( I1 , K - 2 ) - 1
0912                        END IF
0913                    END IF
0914                    ICOL1 = KCOL( KI ) + K - ISTART
0915                    ICOL2 = KP2COL( KI ) + K - ISTART
0916                    CALL INFOG1L( I1 , HBL , NPROW , MYROW , 0 , IROW1 ,
0917       $            IROW2 )
0918                    IROW2 = NUMROC( ITMP1 , HBL , MYROW , 0 , NPROW )
0919                    IF(( MOD( K - 1 , HBL ).EQ.HBL - 2 ) .AND.
0920       $( NPCOL.GT.1 ) ) THEN
0921                    IF( ICOL1.EQ.ICOL2 ) THEN
0922                        CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0923       $                A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0924       $                LDA , MYROW , LEFT )
0925                        CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0926       $                A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0927       $                LDA , MYROW , LEFT )
0928                    ELSE
0929                        CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0930       $                WORK( ICBUF + 1 ) , IROW2 - IROW1 + 1 ,
0931       $                MYROW , RIGHT )
0932                        T2 = T1*V2
0933                        T3 = T1*V3
0934                        DO 270 J = IROW1 , IROW2
0935                            SUM = A(( ICOL1 - 1 )*LDA + J ) +
0936       $                    V2*A( ICOL1*LDA + J ) +
0937       $                    V3*WORK( ICBUF + J - IROW1 + 1 )
0938                            A(( ICOL1 - 1 )*LDA + J ) = A(( ICOL1 - 1 )*
0939       $                    LDA + J ) - SUM*T1
0940                            A( ICOL1*LDA + J ) = A( ICOL1*LDA + J ) -
0941       $                    SUM*T2
0942                            WORK( ICBUF + J - IROW1 + 1 ) = WORK( ICBUF + J -
0943       $                    IROW1 + 1 ) - SUM*T3
0944    270                 CONTINUE
0945                        CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0946       $                WORK( ICBUF + 1 ) , IROW2 - IROW1 + 1 ,
0947       $                MYROW , RIGHT )
0948                    END IF
0949                END IF
0950                IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
0951       $( NPCOL.GT.1 ) ) THEN
0952                IF( ICOL1.EQ.ICOL2 ) THEN
0953                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0954       $            A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0955       $            LDA , MYROW , RIGHT )
0956                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0957       $            A(( ICOL1 - 1 )*LDA + IROW1 ) ,
0958       $            LDA , MYROW , RIGHT )
0959                ELSE
0960                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0961       $            WORK( ICBUF + 1 ) , IROW2 - IROW1 + 1 ,
0962       $            MYROW , LEFT )
0963                    T2 = T1*V2
0964                    T3 = T1*V3
0965                    DO 280 J = IROW1 , IROW2
0966                        SUM = WORK( ICBUF + J - IROW1 + 1 ) +
0967       $                V2*A(( ICOL1 - 1 )*LDA + J ) +
0968       $                V3*A( ICOL1*LDA + J )
0969                        WORK( ICBUF + J - IROW1 + 1 ) = WORK( ICBUF + J -
0970       $                IROW1 + 1 ) - SUM*T1
0971                        A(( ICOL1 - 1 )*LDA + J ) = A(( ICOL1 - 1 )*
0972       $                LDA + J ) - SUM*T2
0973                        A( ICOL1*LDA + J ) = A( ICOL1*LDA + J ) -
0974       $                SUM*T3
0975    280             CONTINUE
0976                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0977       $            WORK( ICBUF + 1 ) , IROW2 - IROW1 + 1 ,
0978       $            MYROW , LEFT )
0979                END IF
0980            END IF
0981  
0982  *         If we want Z and we haven't already done any Z
0983            IF(( WANTZ ) .AND.( MOD( K - 1 ,
0984       $    HBL ).GE.HBL - 2 ) .AND.( NPCOL.GT.1 ) ) THEN
0985  
0986  *         Accumulate transformations in the matrix Z
0987  
0988            IROW1 = LILOZ
0989            IROW2 = LIHIZ
0990            IF( MOD( K - 1 , HBL ).EQ.HBL - 2 ) THEN
0991                IF( ICOL1.EQ.ICOL2 ) THEN
0992                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0993       $            Z(( ICOL1 - 1 )*LDZ + IROW1 ) ,
0994       $            LDZ , MYROW , LEFT )
0995                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
0996       $            Z(( ICOL1 - 1 )*LDZ + IROW1 ) ,
0997       $            LDZ , MYROW , LEFT )
0998                ELSE
0999                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1000       $            WORK( ICBUF + 1 ) ,
1001       $            IROW2 - IROW1 + 1 , MYROW ,
1002       $            RIGHT )
1003                    T2 = T1*V2
1004                    T3 = T1*V3
1005                    ICOL1 =( ICOL1 - 1 )*LDZ
1006                    DO 290 J = IROW1 , IROW2
1007                        SUM = Z( ICOL1 + J ) +
1008       $                V2*Z( ICOL1 + J + LDZ ) +
1009       $                V3*WORK( ICBUF + J - IROW1 + 1 )
1010                        Z( J + ICOL1 ) = Z( J + ICOL1 ) - SUM*T1
1011                        Z( J + ICOL1 + LDZ ) = Z( J + ICOL1 + LDZ ) -
1012       $                SUM*T2
1013                        WORK( ICBUF + J - IROW1 + 1 ) = WORK( ICBUF +
1014       $                J - IROW1 + 1 ) - SUM*T3
1015    290             CONTINUE
1016                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1017       $            WORK( ICBUF + 1 ) ,
1018       $            IROW2 - IROW1 + 1 , MYROW ,
1019       $            RIGHT )
1020                END IF
1021            END IF
1022            IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
1023                IF( ICOL1.EQ.ICOL2 ) THEN
1024                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1025       $            Z(( ICOL1 - 1 )*LDZ + IROW1 ) ,
1026       $            LDZ , MYROW , RIGHT )
1027                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1028       $            Z(( ICOL1 - 1 )*LDZ + IROW1 ) ,
1029       $            LDZ , MYROW , RIGHT )
1030                ELSE
1031                    CALL DGERV2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1032       $            WORK( ICBUF + 1 ) ,
1033       $            IROW2 - IROW1 + 1 , MYROW , LEFT )
1034                    T2 = T1*V2
1035                    T3 = T1*V3
1036                    ICOL1 =( ICOL1 - 1 )*LDZ
1037                    DO 300 J = IROW1 , IROW2
1038                        SUM = WORK( ICBUF + J - IROW1 + 1 ) +
1039       $                V2*Z( J + ICOL1 ) +
1040       $                V3*Z( J + ICOL1 + LDZ )
1041                        WORK( ICBUF + J - IROW1 + 1 ) = WORK( ICBUF +
1042       $                J - IROW1 + 1 ) - SUM*T1
1043                        Z( J + ICOL1 ) = Z( J + ICOL1 ) - SUM*T2
1044                        Z( J + ICOL1 + LDZ ) = Z( J + ICOL1 + LDZ ) -
1045       $                SUM*T3
1046    300             CONTINUE
1047                    CALL DGESD2D( CONTXT , IROW2 - IROW1 + 1 , 1 ,
1048       $            WORK( ICBUF + 1 ) ,
1049       $            IROW2 - IROW1 + 1 , MYROW , LEFT )
1050                END IF
1051            END IF
1052        END IF
1053        IF( ICURCOL( KI ).EQ.MYCOL ) THEN
1054            IF(( ISPEC.EQ.0 ) .OR.( NPCOL.EQ.1 ) ) THEN
1055                LOCALK2( KI ) = LOCALK2( KI ) + 1
1056            END IF
1057        ELSE
1058            IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
1059       $( ICURCOL( KI ).EQ.RIGHT ) ) THEN
1060            IF( K.GT.M ) THEN
1061                LOCALK2( KI ) = LOCALK2( KI ) + 2
1062            ELSE
1063                LOCALK2( KI ) = LOCALK2( KI ) + 1
1064            END IF
1065        END IF
1066        IF(( MOD( K - 1 , HBL ).EQ.HBL - 2 ) .AND.
1067       $( I - K.EQ.2 ) .AND.( ICURCOL( KI ).EQ.
1068       $RIGHT ) ) THEN
1069        LOCALK2( KI ) = LOCALK2( KI ) + 2
1070        END IF
1071        END IF
1072        END IF
1073    310 CONTINUE
1074    320 CONTINUE
1075  
1076  *     Column work done
1077  
1078    330 CONTINUE
1079  
1080  *     Now do NR = 2 work
1081  
1082        DO 410 KI = 1 , IBULGE
1083            ISTART = MAX( K1( KI ) , M )
1084            ISTOP = MIN( K2( KI ) , I - 1 )
1085            IF( MOD( ISTART - 1 , HBL ).GE.HBL - 2 ) THEN
1086  
1087  *             INFO is found in a buffer
1088  
1089                ISPEC = 1
1090            ELSE
1091  
1092  *             All INFO is local
1093  
1094                ISPEC = 0
1095            END IF
1096  
1097            DO 400 K = ISTART , ISTOP
1098  
1099                V2 = WORK( VECSIDX + ( K - 1 )*3 + 1 )
1100                V3 = WORK( VECSIDX + ( K - 1 )*3 + 2 )
1101                T1 = WORK( VECSIDX + ( K - 1 )*3 + 3 )
1102                NR = MIN( 3 , I - K + 1 )
1103                IF( NR.EQ.2 ) THEN
1104                    IF( ICURROW( KI ).EQ.MYROW ) THEN
1105                        T2 = T1*V2
1106                    END IF
1107                    IF( ICURCOL( KI ).EQ.MYCOL ) THEN
1108                        T2 = T1*V2
1109                    END IF
1110  
1111  *                 Apply G from the left to transform the rows of the matrix
1112  *                 in columns K to I2.
1113  
1114                    CALL INFOG1L( K , HBL , NPCOL , MYCOL , 0 , LILOH ,
1115       $            LIHIH )
1116                    LIHIH = NUMROC( I2 , HBL , MYCOL , 0 , NPCOL )
1117                    CALL INFOG1L( 1 , HBL , NPROW , MYROW , 0 , ITMP2 ,
1118       $            ITMP1 )
1119                    ITMP1 = NUMROC( K + 1 , HBL , MYROW , 0 , NPROW )
1120                    IF( ICURROW( KI ).EQ.MYROW ) THEN
1121                        IF(( ISPEC.EQ.0 ) .OR.( NPROW.EQ.1 ) .OR.
1122       $( MOD( K - 1 , HBL ).EQ.HBL - 2 ) ) THEN
1123                        ITMP1 = ITMP1 - 1
1124                        DO 340 J =( LILOH - 1 )*LDA ,
1125       $( LIHIH - 1 )*LDA , LDA
1126                            SUM = A( ITMP1 + J ) + V2*A( ITMP1 + 1 + J )
1127                            A( ITMP1 + J ) = A( ITMP1 + J ) - SUM*T1
1128                            A( ITMP1 + 1 + J ) = A( ITMP1 + 1 + J ) - SUM*T2
1129    340                 CONTINUE
1130                    ELSE
1131                        IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
1132                            CALL DGERV2D( CONTXT , 1 , LIHIH - LILOH + 1 ,
1133       $                    WORK( IRBUF + 1 ) , 1 , UP ,
1134       $                    MYCOL )
1135                            DO 350 J = LILOH , LIHIH
1136                                SUM = WORK( IRBUF + J - LILOH + 1 ) +
1137       $                        V2*A(( J - 1 )*LDA + ITMP1 )
1138                                WORK( IRBUF + J - LILOH + 1 ) = WORK( IRBUF +
1139       $                        J - LILOH + 1 ) - SUM*T1
1140                                A(( J - 1 )*LDA + ITMP1 ) = A(( J - 1 )*
1141       $                        LDA + ITMP1 ) - SUM*T2
1142    350                     CONTINUE
1143                            CALL DGESD2D( CONTXT , 1 , LIHIH - LILOH + 1 ,
1144       $                    WORK( IRBUF + 1 ) , 1 , UP ,
1145       $                    MYCOL )
1146                        END IF
1147                    END IF
1148                ELSE
1149                    IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
1150       $( ICURROW( KI ).EQ.DOWN ) ) THEN
1151                    CALL DGESD2D( CONTXT , 1 , LIHIH - LILOH + 1 ,
1152       $            A(( LILOH - 1 )*LDA + ITMP1 ) ,
1153       $            LDA , DOWN , MYCOL )
1154                    CALL DGERV2D( CONTXT , 1 , LIHIH - LILOH + 1 ,
1155       $            A(( LILOH - 1 )*LDA + ITMP1 ) ,
1156       $            LDA , DOWN , MYCOL )
1157                END IF
1158            END IF
1159  
1160  *         Apply G from the right to transform the columns of the
1161  *         matrix in rows I1 to MIN(K + 3 , I).
1162  
1163            CALL INFOG1L( I1 , HBL , NPROW , MYROW , 0 , LILOH ,
1164       $    LIHIH )
1165            LIHIH = NUMROC( I , HBL , MYROW , 0 , NPROW )
1166  
1167            IF( ICURCOL( KI ).EQ.MYCOL ) THEN
1168  *             LOCAL A(LILOZ : LIHIZ , LOCALK2 : LOCALK2 + 2)
1169                IF(( ISPEC.EQ.0 ) .OR.( NPCOL.EQ.1 ) .OR.
1170       $( MOD( K - 1 , HBL ).EQ.HBL - 2 ) ) THEN
1171                CALL INFOG1L( K , HBL , NPCOL , MYCOL , 0 , ITMP1 ,
1172       $        ITMP2 )
1173                ITMP2 = NUMROC( K + 1 , HBL , MYCOL , 0 , NPCOL )
1174                DO 360 J = LILOH , LIHIH
1175                    SUM = A(( ITMP1 - 1 )*LDA + J ) +
1176       $            V2*A( ITMP1*LDA + J )
1177                    A(( ITMP1 - 1 )*LDA + J ) = A(( ITMP1 - 1 )*
1178       $            LDA + J ) - SUM*T1
1179                    A( ITMP1*LDA + J ) = A( ITMP1*LDA + J ) -
1180       $            SUM*T2
1181    360         CONTINUE
1182            ELSE
1183                ITMP1 = LOCALK2( KI )
1184                IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
1185                    CALL DGERV2D( CONTXT , LIHIH - LILOH + 1 , 1 ,
1186       $            WORK( ICBUF + 1 ) ,
1187       $            LIHIH - LILOH + 1 , MYROW , LEFT )
1188                    DO 370 J = LILOH , LIHIH
1189                        SUM = WORK( ICBUF + J ) +
1190       $                V2*A(( ITMP1 - 1 )*LDA + J )
1191                        WORK( ICBUF + J ) = WORK( ICBUF + J ) -
1192       $                SUM*T1
1193                        A(( ITMP1 - 1 )*LDA + J )
1194       $                = A(( ITMP1 - 1 )*LDA + J ) - SUM*T2
1195    370             CONTINUE
1196                    CALL DGESD2D( CONTXT , LIHIH - LILOH + 1 , 1 ,
1197       $            WORK( ICBUF + 1 ) ,
1198       $            LIHIH - LILOH + 1 , MYROW , LEFT )
1199                END IF
1200            END IF
1201        ELSE
1202            IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
1203       $( ICURCOL( KI ).EQ.RIGHT ) ) THEN
1204            ITMP1 = KCOL( KI )
1205            CALL DGESD2D( CONTXT , LIHIH - LILOH + 1 , 1 ,
1206       $    A(( ITMP1 - 1 )*LDA + LILOH ) ,
1207       $    LDA , MYROW , RIGHT )
1208            CALL INFOG1L( K , HBL , NPCOL , MYCOL , 0 , ITMP1 ,
1209       $    ITMP2 )
1210            ITMP2 = NUMROC( K + 1 , HBL , MYCOL , 0 , NPCOL )
1211            CALL DGERV2D( CONTXT , LIHIH - LILOH + 1 , 1 ,
1212       $    A(( ITMP1 - 1 )*LDA + LILOH ) ,
1213       $    LDA , MYROW , RIGHT )
1214        END IF
1215        END IF
1216  
1217        IF( WANTZ ) THEN
1218  
1219  *         Accumulate transformations in the matrix Z
1220  
1221            IF( ICURCOL( KI ).EQ.MYCOL ) THEN
1222  *             LOCAL Z(LILOZ : LIHIZ , LOCALK2 : LOCALK2 + 2)
1223                IF(( ISPEC.EQ.0 ) .OR.( NPCOL.EQ.1 ) .OR.
1224       $( MOD( K - 1 , HBL ).EQ.HBL - 2 ) ) THEN
1225                ITMP1 = KCOL( KI ) + K - ISTART
1226                ITMP1 =( ITMP1 - 1 )*LDZ
1227                DO 380 J = LILOZ , LIHIZ
1228                    SUM = Z( J + ITMP1 ) +
1229       $            V2*Z( J + ITMP1 + LDZ )
1230                    Z( J + ITMP1 ) = Z( J + ITMP1 ) - SUM*T1
1231                    Z( J + ITMP1 + LDZ ) = Z( J + ITMP1 + LDZ ) -
1232       $            SUM*T2
1233    380         CONTINUE
1234                LOCALK2( KI ) = LOCALK2( KI ) + 1
1235            ELSE
1236                ITMP1 = LOCALK2( KI )
1237  *             IF WE ACTUALLY OWN COLUMN K
1238                IF( MOD( K - 1 , HBL ).EQ.HBL - 1 ) THEN
1239                    CALL DGERV2D( CONTXT , LIHIZ - LILOZ + 1 , 1 ,
1240       $            WORK( ICBUF + 1 ) , LDZ ,
1241       $            MYROW , LEFT )
1242                    ITMP1 =( ITMP1 - 1 )*LDZ
1243                    DO 390 J = LILOZ , LIHIZ
1244                        SUM = WORK( ICBUF + J ) +
1245       $                V2*Z( J + ITMP1 )
1246                        WORK( ICBUF + J ) = WORK( ICBUF + J ) -
1247       $                SUM*T1
1248                        Z( J + ITMP1 ) = Z( J + ITMP1 ) - SUM*T2
1249    390             CONTINUE
1250                    CALL DGESD2D( CONTXT , LIHIZ - LILOZ + 1 , 1 ,
1251       $            WORK( ICBUF + 1 ) , LDZ ,
1252       $            MYROW , LEFT )
1253                    LOCALK2( KI ) = LOCALK2( KI ) + 1
1254                END IF
1255            END IF
1256        ELSE
1257  
1258  *         NO WORK BUT NEED TO UPDATE ANYWAY????
1259  
1260            IF(( MOD( K - 1 , HBL ).EQ.HBL - 1 ) .AND.
1261       $( ICURCOL( KI ).EQ.RIGHT ) ) THEN
1262            ITMP1 = KCOL( KI )
1263            ITMP1 =( ITMP1 - 1 )*LDZ
1264            CALL DGESD2D( CONTXT , LIHIZ - LILOZ + 1 , 1 ,
1265       $    Z( LILOZ + ITMP1 ) , LDZ ,
1266       $    MYROW , RIGHT )
1267            CALL DGERV2D( CONTXT , LIHIZ - LILOZ + 1 , 1 ,
1268       $    Z( LILOZ + ITMP1 ) , LDZ ,
1269       $    MYROW , RIGHT )
1270            LOCALK2( KI ) = LOCALK2( KI ) + 1
1271        END IF
1272        END IF
1273        END IF
1274        END IF
1275    400 CONTINUE
1276  
1277  *     Adjust local information for this bulge
1278  
1279        IF( NPROW.EQ.1 ) THEN
1280            KROW( KI ) = KROW( KI ) + K2( KI ) - K1( KI ) + 1
1281            KP2ROW( KI ) = KP2ROW( KI ) + K2( KI ) - K1( KI ) + 1
1282        END IF
1283        IF(( MOD( K1( KI ) - 1 , HBL ).LT.HBL - 2 ) .AND.
1284       $( ICURROW( KI ).EQ.MYROW ) .AND.( NPROW.GT.1 ) )
1285       $THEN
1286        KROW( KI ) = KROW( KI ) + K2( KI ) - K1( KI ) + 1
1287        END IF
1288        IF(( MOD( K2( KI ) , HBL ).LT.HBL - 2 ) .AND.
1289       $( ICURROW( KI ).EQ.MYROW ) .AND.( NPROW.GT.1 ) )
1290       $THEN
1291        KP2ROW( KI ) = KP2ROW( KI ) + K2( KI ) - K1( KI ) + 1
1292        END IF
1293        IF(( MOD( K1( KI ) - 1 , HBL ).GE.HBL - 2 ) .AND.
1294       $(( MYROW.EQ.ICURROW( KI ) ) .OR.( DOWN.EQ.
1295       $ICURROW( KI ) ) ) .AND.( NPROW.GT.1 ) ) THEN
1296        CALL INFOG1L( K2( KI ) + 1 , HBL , NPROW , MYROW , 0 ,
1297       $KROW( KI ) , ITMP2 )
1298        ITMP2 = NUMROC( N , HBL , MYROW , 0 , NPROW )
1299        END IF
1300        IF(( MOD( K2( KI ) , HBL ).GE.HBL - 2 ) .AND.
1301       $(( MYROW.EQ.ICURROW( KI ) ) .OR.( UP.EQ.
1302       $ICURROW( KI ) ) ) .AND.( NPROW.GT.1 ) ) THEN
1303        CALL INFOG1L( 1 , HBL , NPROW , MYROW , 0 , ITMP2 ,
1304       $KP2ROW( KI ) )
1305        KP2ROW( KI ) = NUMROC( K2( KI ) + 3 , HBL , MYROW , 0 ,
1306       $NPROW )
1307        END IF
1308        IF( NPCOL.EQ.1 ) THEN
1309            KCOL( KI ) = KCOL( KI ) + K2( KI ) - K1( KI ) + 1
1310            KP2COL( KI ) = KP2COL( KI ) + K2( KI ) - K1( KI ) + 1
1311        END IF
1312        IF(( MOD( K1( KI ) - 1 , HBL ).LT.HBL - 2 ) .AND.
1313       $( ICURCOL( KI ).EQ.MYCOL ) .AND.( NPCOL.GT.1 ) )
1314       $THEN
1315        KCOL( KI ) = KCOL( KI ) + K2( KI ) - K1( KI ) + 1
1316        END IF
1317        IF(( MOD( K2( KI ) , HBL ).LT.HBL - 2 ) .AND.
1318       $( ICURCOL( KI ).EQ.MYCOL ) .AND.( NPCOL.GT.1 ) )
1319       $THEN
1320        KP2COL( KI ) = KP2COL( KI ) + K2( KI ) - K1( KI ) + 1
1321        END IF
1322        IF(( MOD( K1( KI ) - 1 , HBL ).GE.HBL - 2 ) .AND.
1323       $(( MYCOL.EQ.ICURCOL( KI ) ) .OR.( RIGHT.EQ.
1324       $ICURCOL( KI ) ) ) .AND.( NPCOL.GT.1 ) ) THEN
1325        CALL INFOG1L( K2( KI ) + 1 , HBL , NPCOL , MYCOL , 0 ,
1326       $KCOL( KI ) , ITMP2 )
1327        ITMP2 = NUMROC( N , HBL , MYCOL , 0 , NPCOL )
1328        END IF
1329        IF(( MOD( K2( KI ) , HBL ).GE.HBL - 2 ) .AND.
1330       $(( MYCOL.EQ.ICURCOL( KI ) ) .OR.( LEFT.EQ.
1331       $ICURCOL( KI ) ) ) .AND.( NPCOL.GT.1 ) ) THEN
1332        CALL INFOG1L( 1 , HBL , NPCOL , MYCOL , 0 , ITMP2 ,
1333       $KP2COL( KI ) )
1334        KP2COL( KI ) = NUMROC( K2( KI ) + 3 , HBL , MYCOL , 0 ,
1335       $NPCOL )
1336        END IF
1337        K1( KI ) = K2( KI ) + 1
1338        ISTOP = MIN( K1( KI ) + ROTN - MOD( K1( KI ) , ROTN ) , I - 2 )
1339        ISTOP = MIN( ISTOP , K1( KI ) + HBL - 3 -
1340       $MOD( K1( KI ) - 1 , HBL ) )
1341        ISTOP = MIN( ISTOP , I2 - 2 )
1342        ISTOP = MAX( ISTOP , K1( KI ) )
1343  *     ISTOP = MIN( ISTOP , I - 1 )
1344        K2( KI ) = ISTOP
1345        IF( K1( KI ).EQ.ISTOP ) THEN
1346            IF(( MOD( ISTOP - 1 , HBL ).EQ.HBL - 2 ) .AND.
1347       $( I - ISTOP.GT.1 ) ) THEN
1348  
1349  *         Next step switches rows & cols
1350  
1351            ICURROW( KI ) = MOD( ICURROW( KI ) + 1 , NPROW )
1352            ICURCOL( KI ) = MOD( ICURCOL( KI ) + 1 , NPCOL )
1353        END IF
1354        END IF
1355    410 CONTINUE
1356        IF( K2( IBULGE ).LE.I - 1 )
1357       $    GO TO 40
1358        END IF
1359  
1360    420 CONTINUE
1361  
1362  *     Failure to converge in remaining number of iterations
1363  
1364        INFO = I
1365        RETURN
1366  
1367    430 CONTINUE
1368  
1369        IF( L.EQ.I ) THEN
1370  
1371  *         H(I , I - 1) is negligible : one eigenvalue has converged.
1372  
1373            CALL INFOG2L( I , I , DESCA , NPROW , NPCOL , MYROW , MYCOL , IROW ,
1374       $    ICOL , ITMP1 , ITMP2 )
1375            IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
1376                WR( I ) = A(( ICOL - 1 )*LDA + IROW )
1377            ELSE
1378                WR( I ) = ZERO
1379            END IF
1380            WI( I ) = ZERO
1381        ELSE IF( L.EQ.I - 1 ) THEN
1382  
1383  *         H(I - 1 , I - 2) is negligible : a pair of eigenvalues have converged.
1384  
1385            WR( I - 1 ) = ZERO
1386            WR( I ) = ZERO
1387            WI( I - 1 ) = ZERO
1388            WI( I ) = ZERO
1389            MODKM1 = MOD( I - 1 + HBL , HBL )
1390            CALL INFOG2L( I - 1 , I - 1 , DESCA , NPROW , NPCOL , MYROW , MYCOL ,
1391       $    IROW1 , ICOL1 , II , JJ )
1392            IF(( MYROW.EQ.II ) .AND.( MYCOL.EQ.JJ ) ) THEN
1393                H11 = A(( ICOL1 - 1 )*LDA + IROW1 )
1394                IF( MODKM1.NE.0 ) THEN
1395                    H21 = A(( ICOL1 - 1 )*LDA + IROW1 + 1 )
1396                    H12 = A( ICOL1*LDA + IROW1 )
1397                    H22 = A( ICOL1*LDA + IROW1 + 1 )
1398                ELSE
1399                    IF( NPROW.GT.1 ) THEN
1400                        CALL DGERV2D( CONTXT , 1 , 1 , H21 , 1 , DOWN , MYCOL )
1401                    ELSE
1402                        H21 = A(( ICOL1 - 1 )*LDA + IROW1 + 1 )
1403                    END IF
1404                    IF( NPCOL.GT.1 ) THEN
1405                        CALL DGERV2D( CONTXT , 1 , 1 , H12 , 1 , MYROW , RIGHT )
1406                    ELSE
1407                        H12 = A( ICOL1*LDA + IROW1 )
1408                    END IF
1409                    IF( NUM.GT.1 ) THEN
1410                        CALL DGERV2D( CONTXT , 1 , 1 , H22 , 1 , DOWN , RIGHT )
1411                    ELSE
1412                        H22 = A( ICOL1*LDA + IROW1 + 1 )
1413                    END IF
1414                END IF
1415                H00 = HALF*( H11 + H22 )
1416                H10 = H11*H22 - H12*H21
1417            ELSE
1418                IF( MODKM1.EQ.0 ) THEN
1419                    IF(( NPROW.GT.1 ) .AND.( MYCOL.EQ.JJ ) .AND.
1420       $( UP.EQ.II ) ) THEN
1421                    CALL INFOG2L( I , I - 1 , DESCA , NPROW , NPCOL , MYROW ,
1422       $            MYCOL , IROW1 , ICOL1 , ITMP1 , ITMP2 )
1423                    CALL DGESD2D( CONTXT , 1 , 1 ,
1424       $            A(( ICOL1 - 1 )*LDA + IROW1 ) , 1 , II , JJ )
1425                END IF
1426                IF(( NPCOL.GT.1 ) .AND.( LEFT.EQ.JJ ) .AND.
1427       $( MYROW.EQ.II ) ) THEN
1428                CALL INFOG2L( I - 1 , I , DESCA , NPROW , NPCOL , MYROW ,
1429       $        MYCOL , IROW1 , ICOL1 , ITMP1 , ITMP2 )
1430                CALL DGESD2D( CONTXT , 1 , 1 ,
1431       $        A(( ICOL1 - 1 )*LDA + IROW1 ) , 1 , II , JJ )
1432            END IF
1433            IF(( NUM.GT.1 ) .AND.( LEFT.EQ.JJ ) .AND.
1434       $( UP.EQ.II ) ) THEN
1435            CALL INFOG2L( I , I , DESCA , NPROW , NPCOL , MYROW , MYCOL ,
1436       $    IROW1 , ICOL1 , ITMP1 , ITMP2 )
1437            CALL DGESD2D( CONTXT , 1 , 1 ,
1438       $    A(( ICOL1 - 1 )*LDA + IROW1 ) , 1 , II , JJ )
1439        END IF
1440        END IF
1441        H00 = ZERO
1442        H10 = ZERO
1443        END IF
1444        H21 = H00*H00 - H10
1445        IF( H21.GE.ZERO ) THEN
1446            H21 = SQRT( H21 )
1447            WR( I - 1 ) = H00 + H21
1448            WI( I - 1 ) = ZERO
1449            WR( I ) = H00 - H21
1450            WI( I ) = ZERO
1451        ELSE
1452            H21 = SQRT( ABS( H21 ) )
1453            WR( I - 1 ) = H00
1454            WI( I - 1 ) = H21
1455            WR( I ) = H00
1456            WI( I ) = - H21
1457        END IF
1458        ELSE
1459  
1460  *         Find the eigenvalues in H(L : I , L : I) , L < I - 1
1461  
1462            JBLK = I - L + 1
1463            IF( JBLK.LE.2*IBLK ) THEN
1464                CALL PDLACP3 ( I - L + 1 , L , A , DESCA , S1 , 2*IBLK , 0 , 0 , 0 )
1465                CALL DLAHQR( .FALSE. , .FALSE. , JBLK , 1 , JBLK , S1 , 2*IBLK ,
1466       $        WR( L ) , WI( L ) , 1 , JBLK , Z , LDZ , IERR )
1467                IF( NODE.NE.0 ) THEN
1468  
1469  *                 Erase the eigenvalues
1470  
1471                    DO 440 K = L , I
1472                        WR( K ) = ZERO
1473                        WI( K ) = ZERO
1474    440             CONTINUE
1475                END IF
1476            END IF
1477        END IF
1478  
1479  *     Decrement number of remaining iterations , and return to start of
1480  *     the main loop with new value of I.
1481  
1482        ITN = ITN - ITS
1483        IF( M.EQ.L - 10 ) THEN
1484            I = L - 1
1485        ELSE
1486            I = M
1487        END IF
1488  *     I = L - 1
1489        GO TO 10
1490  
1491    450 CONTINUE
1492        CALL DGSUM2D( CONTXT , 'All' , ' ' , N , 1 , WR , N , - 1 , - 1 )
1493        CALL DGSUM2D( CONTXT , 'All' , ' ' , N , 1 , WI , N , - 1 , - 1 )
1494        RETURN
1495  
1496  *     END OF PDLAHQR
1497  
1498        END