1      SUBROUTINE pcheevr( JOBZ, RANGE, UPLO, N, A, IA, JA, 
 
    2     $                    DESCA, VL, VU, IL, IU, M, NZ, W, Z, IZ,
 
    4     $                    WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK,
 
   14      CHARACTER          JOBZ, RANGE, UPLO
 
   16      INTEGER            IA, IL, INFO, IU, IZ, JA, JZ, LIWORK, LRWORK,
 
   21      INTEGER            DESCA( * ), DESCZ( * ), IWORK( * )
 
   22      REAL               W( * ), RWORK( * )
 
   23      COMPLEX            A( * ), WORK( * ), Z( * )
 
  321      INTEGER            CTXT_, M_, N_,
 
  322     $                   MB_, NB_, RSRC_, CSRC_
 
  323      PARAMETER          ( CTXT_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
 
  324     $                   rsrc_ = 7, csrc_ = 8 )
 
  326      PARAMETER          ( ZERO = 0.0e0 )
 
  329      LOGICAL            ALLEIG, COLBRT, DOBCST, FINISH, FIRST, INDEIG,
 
  330     $                   lower, lquery, valeig, vstart, wantz
 
  331      INTEGER            ANB, DOL, DOU, DSTCOL, DSTROW, EIGCNT, FRSTCL,
 
  332     $                   I, IAROW, ICTXT, IIL, IINDERR, IINDWLC, IINFO,
 
  333     $                   iiu, im, indd, indd2, inde, inde2, inderr,
 
  334     $                   indilu, indrtau, indrw, indrwork, indtau,
 
  335     $                   indwlc, indwork, ipil, ipiu, iproc, izrow,
 
  336     $                   lastcl, lengthi, lengthi2, liwmin, llrwork,
 
  337     $                   llwork, lrwmin, lrwopt, lwmin, lwopt, maxcls,
 
  338     $                   mq00, mycol, myil, myiu, myproc, myrow, mz, nb,
 
  339     $                   ndepth, needil, neediu, nhetrd_lwopt, nnp,
 
  340     $                   np00, npcol, nprocs, nprow, nps, nsplit,
 
  341     $                   offset, parity, rlengthi, rlengthi2, rstarti,
 
  342     $                   size1, size2, sqnpc, srccol, srcrow, starti,
 
  345      REAL                        PIVMIN, SAFMIN, SCALE, VLL, VUU, WL,
 
  349      INTEGER            IDUM1( 4 ), IDUM2( 4 )
 
  353      INTEGER            ICEIL, INDXG2P, NUMROC, PJLAENV
 
  355      EXTERNAL            ICEIL, INDXG2P, LSAME, NUMROC, PJLAENV,
 
  359      EXTERNAL            blacs_gridinfo, 
chk1mat, igebr2d, igebs2d,
 
  363     $                    sgerv2d, sgesd2d, slarrc, 
slasrt2,
 
  367      INTRINSIC           abs, 
cmplx, ichar, int, 
max, 
min, mod, real,
 
  380      wantz = lsame( jobz, 
'V' )
 
  381      lower = lsame( uplo, 
'L' )
 
  382      alleig = lsame( range, 
'A' )
 
  383      valeig = lsame( range, 
'V' )
 
  384      indeig = lsame( range, 
'I' )
 
  385      lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
 
  392      ictxt = desca( ctxt_ )
 
  393      safmin = pslamch( ictxt, 
'Safe minimum' )
 
  402      llwork = lwork - indwork + 1
 
  415      llrwork = lrwork - indrwork + 1
 
  422      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
 
  425      nprocs = nprow * npcol
 
  426      myproc = myrow * npcol + mycol
 
  427      IF( nprow.EQ.-1 ) 
THEN 
  428         info = -( 800+ctxt_ )
 
  429      ELSE IF( wantz ) 
THEN 
  430         IF( ictxt.NE.descz( ctxt_ ) ) 
THEN 
  431            info = -( 2100+ctxt_ )
 
  442      ELSE IF ( indeig ) 
THEN 
  450      np00 = numroc( n, nb, 0, 0, nprow )
 
  451      mq00 = numroc( mz, nb, 0, 0, npcol )            
 
  453         indrw = indrwork + 
max(18*n, np00*mq00 + 2*nb*nb)
 
  454         lrwmin = indrw - 1 + (iceil(mz, nprocs) + 2)*n
 
  455         lwmin = n + 
max((np00 + mq00 + nb) * nb, 3 * nb)
 
  457         indrw = indrwork + 12*n
 
  459         lwmin = n + 
max( nb*( np00 + 1 ), 3 * nb ) 
 
  463      lrwmin = 
max(3, lrwmin)
 
  465      lwmin = 
max(3, lwmin)
 
  468      anb = pjlaenv( ictxt, 3, 
'PCHETTRD', 
'L', 0, 0, 0, 0 )
 
  469      sqnpc = int( sqrt( real( nprocs ) ) )
 
  470      nps = 
max( numroc( n, 1, 0, 0, sqnpc ), 2*anb )
 
  471      nhetrd_lwopt = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
 
  472      lwopt = 
max( lwopt, n+nhetrd_lwopt )
 
  474      size1 = indrw - indrwork
 
  481      nnp = 
max( n, nprocs+1, 4 )
 
  483        liwmin = 12*nnp + 2*n 
 
  485        liwmin = 10*nnp + 2*n
 
  494      indilu = liwmin - 2*nprocs + 1            
 
  504         CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
 
  506     $      
CALL chk1mat( n, 4, n, 4, iz, jz, descz, 21, info )
 
  509            IF( .NOT.( wantz .OR. lsame( jobz, 
'N' ) ) ) 
THEN 
  511            ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) 
THEN 
  513            ELSE IF( .NOT.( lower .OR. lsame( uplo, 
'U' ) ) ) 
THEN 
  515            ELSE IF( mod( ia-1, desca( mb_ ) ).NE.0 ) 
THEN 
  517            ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl ) 
THEN 
  519            ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
 
  522            ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ))
 
  525            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) 
THEN 
  527            ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) 
THEN 
  529            ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) 
THEN 
  531            ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) 
THEN 
  535               iarow = indxg2p( 1, desca( nb_ ), myrow, 
 
  536     $                       desca( rsrc_ ), nprow )
 
  537               izrow = indxg2p( 1, desca( nb_ ), myrow, 
 
  538     $                          descz( rsrc_ ), nprow )
 
  539               IF( iarow.NE.izrow ) 
THEN 
  541               ELSE IF( mod( ia-1, desca( mb_ ) ).NE.
 
  542     $             mod( iz-1, descz( mb_ ) ) ) 
THEN 
  544               ELSE IF( desca( m_ ).NE.descz( m_ ) ) 
THEN 
  546               ELSE IF( desca( n_ ).NE.descz( n_ ) ) 
THEN 
  548               ELSE IF( desca( mb_ ).NE.descz( mb_ ) ) 
THEN 
  550               ELSE IF( desca( nb_ ).NE.descz( nb_ ) ) 
THEN 
  552               ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) ) 
THEN 
  553                  info = -( 2100+rsrc_ )
 
  554               ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) ) 
THEN 
  555                  info = -( 2100+csrc_ )
 
  556               ELSE IF( ictxt.NE.descz( ctxt_ ) ) 
THEN 
  557                  info = -( 2100+ctxt_ )
 
  563            idum1( 2 ) = ichar( 
'L' )
 
  565            idum1( 2 ) = ichar( 
'U' )
 
  569            idum1( 3 ) = ichar( 
'A' )
 
  570         ELSE IF( indeig ) 
THEN 
  571            idum1( 3 ) = ichar( 
'I' )
 
  573            idum1( 3 ) = ichar( 
'V' )
 
  583            idum1( 1 ) = ichar( 
'V' )
 
  584            CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 8, n, 4, n, 4,iz,
 
  585     $                     jz, descz, 21, 4, idum1, idum2, info )
 
  587            idum1( 1 ) = ichar( 
'N' )
 
  588            CALL pchk1mat( n, 4, n, 4, ia, ja, desca, 8, 4, idum1,
 
  591         work( 1 ) = 
cmplx( lwopt )
 
  592         rwork( 1 ) = real( lrwopt )
 
  597         CALL pxerbla( ictxt, 
'PCHEEVR', -info )
 
  599      ELSE IF( lquery ) 
THEN 
  613         work( 1 ) = 
cmplx( lwopt )
 
  614         rwork( 1 ) = real( lrwopt )
 
  637      CALL pchentrd( uplo, n, a, ia, ja, desca, rwork( indd ),
 
  638     $               rwork( inde ), work( indtau ), work( indwork ),
 
  639     $               llwork, rwork( indrwork ), llrwork,iinfo )
 
  642      IF (iinfo .NE. 0) 
THEN 
  643         CALL pxerbla( ictxt, 
'PCHENTRD', -iinfo )
 
  653      IF( ia.EQ.1 .AND. ja.EQ.1 .AND. 
 
  654     $    desca( rsrc_ ).EQ.0 .AND. desca( csrc_ ).EQ.0 )
 
  656         CALL pslared1d( n, ia, ja, desca, rwork( indd ), 
 
  657     $                   rwork( indd2 ), rwork( indrwork ), llrwork )
 
  659         CALL pslared1d( n, ia, ja, desca, rwork( inde ), 
 
  660     $                   rwork( inde2 ), rwork( indrwork ), llrwork )
 
  665            CALL pcelget( 
'A', 
' ', work( indwork ), a, 
 
  666     $                    i+ia-1, i+ja-1, desca )
 
  667            rwork( indd2+i-1 ) = real( work( indwork ) )
 
  669         IF( lsame( uplo, 
'U' ) ) 
THEN 
  671               CALL pcelget( 
'A', 
' ', work( indwork ), a, 
 
  672     $                       i+ia-1, i+ja, desca )
 
  673               rwork( inde2+i-1 ) = real( work( indwork ) )
 
  677               CALL pcelget( 
'A', 
' ', work( indwork ), a,
 
  678     $                       i+ia, i+ja-1, desca )
 
  679               rwork( inde2+i-1 ) = real( work( indwork ) )
 
  695      ELSE IF ( indeig ) 
THEN 
  698      ELSE IF ( valeig ) 
THEN 
  699         CALL slarrc(
'T', n, vll, vuu, rwork( indd2 ), 
 
  700     $    rwork( inde2 + offset ), safmin, eigcnt, iil, iiu, info)
 
  711         work( 1 ) = real( lwopt )
 
  730      CALL pmpim2( iil, iiu, nprocs,
 
  731     $             iwork(indilu), iwork(indilu+nprocs) )
 
  735      myil = iwork(indilu+myproc)
 
  736      myiu = iwork(indilu+nprocs+myproc)
 
  739      zoffset = 
max(0, myil - iil - 1)
 
  740      first = ( myil .EQ. iil )
 
  753         IF ( myil.GT.0 ) 
THEN 
  755            dou = myiu - myil + 1
 
  756            CALL sstegr2( jobz, 
'I', n,  rwork( indd2 ),
 
  757     $                  rwork( inde2+offset ), vll, vuu, myil, myiu,
 
  758     $                  im, w( 1 ), rwork( indrw ), n, 
 
  760     $                  iwork( 1 ), rwork( indrwork ), size1, 
 
  761     $                  iwork( 2*n+1 ), size2, 
 
  762     $                  dol, dou, zoffset, iinfo )
 
  767              w( myil-iil+i ) = w( i )
 
  772         IF (iinfo .NE. 0) 
THEN 
  773            CALL pxerbla( ictxt, 
'SSTEGR2', -iinfo )
 
  776      ELSEIF ( wantz .AND. nprocs.EQ.1 ) 
THEN 
  781         IF ( myil.GT.0 ) 
THEN 
  784            CALL sstegr2( jobz, 
'I', n,  rwork( indd2 ),
 
  785     $                  rwork( inde2+offset ), vll, vuu, iil, iiu,
 
  786     $                  im, w( 1 ), rwork( indrw ), n, 
 
  788     $                  iwork( 1 ), rwork( indrwork ), size1, 
 
  789     $                  iwork( 2*n+1 ), size2, dol, dou,
 
  792         IF (iinfo .NE. 0) 
THEN 
  793            CALL pxerbla( ictxt, 
'SSTEGR2', -iinfo )
 
  796      ELSEIF ( wantz ) 
THEN 
  802         IF ( myil.GT.0 ) 
THEN 
  805            CALL sstegr2a( jobz, 
'I', n,  rwork( indd2 ),
 
  806     $                  rwork( inde2+offset ), vll, vuu, iil, iiu,
 
  807     $                  im, w( 1 ), rwork( indrw ), n, 
 
  808     $                  n, rwork( indrwork ), size1, 
 
  809     $                  iwork( 2*n+1 ), size2, dol, 
 
  810     $                  dou, needil, neediu,
 
  811     $                  inderr, nsplit, pivmin, scale, wl, wu,
 
  814         IF (iinfo .NE. 0) 
THEN 
  815            CALL pxerbla( ictxt, 
'SSTEGR2A', -iinfo )
 
  827         iinderr = indrwork + inderr - 1
 
  847               IF (myproc .EQ. (i - 1)) 
THEN 
  853                     lengthi = myiu - myil + 1
 
  858                  CALL igesd2d( ictxt, 2, 1, iwork, 2, 
 
  860                  IF (( starti.GE.1 ) .AND. ( lengthi.GE.1 )) 
THEN 
  863                     CALL scopy(lengthi,w( starti ),1,
 
  866                     CALL scopy(lengthi,rwork(iinderr+starti-1),1,
 
  867     $                          rwork( indd+lengthi ), 1)               
 
  869                     CALL sgesd2d( ictxt, lengthi2, 
 
  870     $                    1, rwork( indd ), lengthi2,
 
  873               ELSE IF (myproc .EQ. 0) 
THEN 
  874                  srcrow = (i-1) / npcol
 
  875                  srccol = mod(i-1, npcol)
 
  876                  CALL igerv2d( ictxt, 2, 1, iwork, 2, 
 
  880                  IF (( starti.GE.1 ) .AND. ( lengthi.GE.1 )) 
THEN 
  883                     CALL sgerv2d( ictxt, lengthi2, 1,
 
  884     $                 rwork(indd), lengthi2, srcrow, srccol )
 
  886                     CALL scopy( lengthi, rwork(indd), 1,
 
  889                     CALL scopy(lengthi,rwork(indd+lengthi),1,
 
  890     $                          rwork( iinderr+starti-1 ), 1)     
 
  894            lengthi = iiu - iil + 1
 
  895            lengthi2 = lengthi * 2
 
  896            IF (myproc .EQ. 0) 
THEN 
  898               CALL scopy(lengthi,w ,1, rwork( indd ), 1)               
 
  899               CALL scopy(lengthi,rwork( iinderr ),1,
 
  900     $                          rwork( indd+lengthi ), 1)               
 
  901               CALL sgebs2d( ictxt, 
'A', 
' ', lengthi2, 1, 
 
  902     $              rwork(indd), lengthi2 )
 
  906               CALL sgebr2d( ictxt, 
'A', 
' ', lengthi2, 1,
 
  907     $             rwork(indd), lengthi2, srcrow, srccol )
 
  908               CALL scopy( lengthi, rwork(indd), 1, w, 1)
 
  909               CALL scopy(lengthi,rwork(indd+lengthi),1,
 
  910     $                          rwork( iinderr ), 1)                   
 
  916            IF( (nprocs.GT.1).AND.(myil.GT.0) ) 
THEN 
  917               CALL pmpcol( myproc, nprocs, iil, needil, neediu, 
 
  918     $                   iwork(indilu), iwork(indilu+nprocs),
 
  919     $                   colbrt, frstcl, lastcl )
 
  927               DO 47 iproc = frstcl, lastcl
 
  928                  IF (myproc .EQ. iproc) 
THEN 
  931                     lengthi = myiu - myil + 1
 
  934                     IF ((starti.GE.1) .AND. (lengthi.GE.1)) 
THEN 
  936                        CALL scopy(lengthi,w( starti ),1,
 
  940     $                          rwork( iinderr+starti-1 ),1,
 
  941     $                          rwork(indd+lengthi), 1)                 
 
  944                     DO 46 i = frstcl, lastcl                      
 
  945                        IF(i.EQ.myproc) 
GOTO 46
 
  947                        dstcol = mod(i, npcol)
 
  948                        CALL igesd2d( ictxt, 2, 1, iwork, 2, 
 
  950                        IF ((starti.GE.1) .AND. (lengthi.GE.1)) 
THEN 
  953                           CALL sgesd2d( ictxt, lengthi2, 
 
  954     $                          1, rwork(indd), lengthi2,
 
  959                     srcrow = iproc / npcol
 
  960                     srccol = mod(iproc, npcol)
 
  961                     CALL igerv2d( ictxt, 2, 1, iwork, 2, 
 
  965                     IF ((rstarti.GE.1 ) .AND. (rlengthi.GE.1 )) 
THEN 
  966                        rlengthi2 = 2*rlengthi
 
  967                        CALL sgerv2d( ictxt, rlengthi2, 1,
 
  968     $                      rwork(inde), rlengthi2,
 
  971                        CALL scopy( rlengthi,rwork(inde), 1,
 
  974                        CALL scopy(rlengthi,rwork(inde+rlengthi),1,
 
  975     $                          rwork( iinderr+rstarti-1 ), 1)          
 
  989         IF ( myil.GT.0 ) 
THEN 
  990            CALL sstegr2b( jobz, n,  rwork( indd2 ),
 
  991     $                  rwork( inde2+offset ), 
 
  992     $                  im, w( 1 ), rwork( indrw ), n, n,
 
  993     $                  iwork( 1 ), rwork( indrwork ), size1, 
 
  994     $                  iwork( 2*n+1 ), size2, dol, 
 
  995     $                  dou, needil, neediu, indwlc,
 
  996     $                  pivmin, scale, wl, wu,
 
  998     $                  maxcls, ndepth, parity, zoffset, iinfo )
 
  999            iindwlc = indrwork + indwlc - 1
 
 1000            IF(.NOT.finish) 
THEN 
 1001               IF((needil.LT.dol).OR.(neediu.GT.dou)) 
THEN 
 1002                  CALL pmpcol( myproc, nprocs, iil, needil, neediu,
 
 1003     $                 iwork(indilu), iwork(indilu+nprocs),
 
 1004     $                   colbrt, frstcl, lastcl )
 
 1015                  DO 147 iproc = frstcl, lastcl
 
 1016                     IF (myproc .EQ. iproc) 
THEN 
 1020                           lengthi = myiu - myil + 1
 
 1025                        IF ((starti.GE.1).AND.(lengthi.GE.1)) 
THEN 
 1028     $                          rwork( iindwlc+starti-1 ),1,
 
 1032     $                          rwork( iinderr+starti-1 ),1,
 
 1033     $                          rwork(indd+lengthi), 1)                 
 
 1036                        DO 146 i = frstcl, lastcl                      
 
 1037                           IF(i.EQ.myproc) 
GOTO 146
 
 1039                           dstcol = mod(i, npcol)
 
 1040                           CALL igesd2d( ictxt, 2, 1, iwork, 2, 
 
 1042                           IF ((starti.GE.1).AND.(lengthi.GE.1)) 
THEN 
 1043                              lengthi2 = 2*lengthi
 
 1045                              CALL sgesd2d( ictxt, lengthi2, 
 
 1046     $                             1, rwork(indd), lengthi2,
 
 1051                        srcrow = iproc / npcol
 
 1052                        srccol = mod(iproc, npcol)
 
 1053                        CALL igerv2d( ictxt, 2, 1, iwork, 2, 
 
 1057                        IF ((rstarti.GE.1).AND.(rlengthi.GE.1)) 
THEN 
 1058                           rlengthi2 = 2*rlengthi
 
 1059                           CALL sgerv2d( ictxt,rlengthi2, 1,
 
 1060     $                         rwork(inde),rlengthi2,
 
 1063                           CALL scopy(rlengthi,rwork(inde), 1,
 
 1064     $                          rwork( iindwlc+rstarti-1 ), 1)        
 
 1066                           CALL scopy(rlengthi,rwork(inde+rlengthi),
 
 1067     $                          1,rwork( iinderr+rstarti-1 ), 1)        
 
 1075         IF (iinfo .NE. 0) 
THEN 
 1076            CALL pxerbla( ictxt, 
'SSTEGR2B', -iinfo )
 
 1098         IF (myproc .EQ. (i - 1)) 
THEN 
 1101            starti = myil - iil + 1
 
 1104               lengthi = myiu - myil + 1
 
 1109            CALL igesd2d( ictxt, 2, 1, iwork, 2, 
 
 1111            IF ((starti.GE.1).AND.(lengthi.GE.1)) 
THEN 
 1112               CALL sgesd2d( ictxt, lengthi, 
 
 1113     $              1, w( starti ), lengthi,
 
 1116         ELSE IF (myproc .EQ. 0) 
THEN 
 1117            srcrow = (i-1) / npcol
 
 1118            srccol = mod(i-1, npcol)
 
 1119            CALL igerv2d( ictxt, 2, 1, iwork, 2, 
 
 1123            IF ((starti.GE.1).AND.(lengthi.GE.1)) 
THEN 
 1124               CALL sgerv2d( ictxt, lengthi, 1,
 
 1125     $                 w( starti ), lengthi, srcrow, srccol )
 
 1132      CALL igsum2d( ictxt, 
'A', 
' ', 1, 1, m, 1, -1, -1 )
 
 1135      IF (myproc .EQ. 0) 
THEN 
 1137         CALL sgebs2d( ictxt, 
'A', 
' ', m, 1, w, m )
 
 1141         CALL sgebr2d( ictxt, 
'A', 
' ', m, 1,
 
 1142     $           w, m, srcrow, srccol )
 
 1149         iwork( nprocs+1+i ) = i
 
 1151      CALL slasrt2( 
'I', m, w, iwork( nprocs+2 ), iinfo )
 
 1152      IF (iinfo.NE.0) 
THEN 
 1153         CALL pxerbla( ictxt, 
'SLASRT2', -iinfo )
 
 1164            iwork( m+nprocs+1+iwork( nprocs+1+i ) ) = i
 
 1168         DO 180 i = 1, nprocs
 
 1171            ipil = iwork(indilu+i-1)
 
 1172            ipiu = iwork(indilu+nprocs+i-1)
 
 1173            IF (ipil .EQ. 0) 
THEN 
 1174               iwork( i + 1 ) = iwork( i )
 
 1176               iwork( i + 1 ) = iwork( i ) + ipiu - ipil + 1
 
 1181            CALL pclaevswp(n, rwork( indrw ), n, z, iz, jz, 
 
 1182     $       descz, iwork( 1 ), iwork( nprocs+m+2 ), rwork( indrwork ), 
 
 1185            CALL pclaevswp(n, rwork( indrw + n ), n, z, iz, jz, 
 
 1186     $       descz, iwork( 1 ), iwork( nprocs+m+2 ), rwork( indrwork ),
 
 1199           CALL pcunmtr( 
'L', uplo, 
'N', n, nz, a, ia, ja, desca,
 
 1200     $                    work( indtau ), z, iz, jz, descz,
 
 1201     $                    work( indwork ), llwork, iinfo )
 
 1203         IF (iinfo.NE.0) 
THEN 
 1204            CALL pxerbla( ictxt, 
'PCUNMTR', -iinfo )
 
 1211      work( 1 ) = 
cmplx( lwopt )
 
 1212      rwork( 1 ) = real( lrwopt )