1 SUBROUTINE pssyevr( JOBZ, RANGE, UPLO, N, A, IA, JA,
2 $ DESCA, VL, VU, IL, IU, M, NZ, W, Z, IZ,
3 $ JZ, DESCZ, WORK, LWORK, IWORK, LIWORK,
13 CHARACTER JOBZ, RANGE, UPLO
14 INTEGER IA, IL, INFO, IU, IZ, JA, JZ, LIWORK, LWORK, M
19 INTEGER DESCA( * ), DESCZ( * ), IWORK( * )
20 REAL A( * ), W( * ), WORK( * ), Z( * )
295 $ MB_, , RSRC_, CSRC_
296 PARAMETER ( CTXT_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
297 $ rsrc_ = 7, csrc_ = 8 )
299 parameter( zero = 0.0e0 )
302 LOGICAL ALLEIG, COLBRT, DOBCST, FINISH, FIRST, INDEIG,
303 $ LOWER, LQUERY, VALEIG, VSTART, WANTZ
304 INTEGER ANB, DOL, , DSTCOL, DSTROW, EIGCNT, ,
305 $ i, iarow, ictxt, iil, iinderr, iindwlc, iinfo,
306 $ iiu, im, indd, indd2, inde, inde2, inderr,
307 $ indilu, indrw, indtau, indwlc, indwork, ipil,
308 $ ipiu, iproc, izrow, lastcl, lengthi, lengthi2,
309 $ liwmin, llwork, lwmin, lwopt, maxcls, mq00,
310 $ mycol, myil, myiu, myproc, myrow, mz, nb,
311 $ ndepth, needil, neediu, nnp, np00, npcol,
312 $ nprocs, nprow, nps, nsplit, nsytrd_lwopt,
313 $ offset, parity, rlengthi, rlengthi2, rstarti,
314 $ size1, size2, sqnpc, srccol, srcrow, starti,
317 REAL PIVMIN, SAFMIN, SCALE, VLL, VUU, WL,
321 INTEGER IDUM1( 4 ), IDUM2( 4 )
325 INTEGER ICEIL, INDXG2P, NUMROC, PJLAENV
327 EXTERNAL iceil, indxg2p, lsame, numroc, pjlaenv,
339 INTRINSIC abs, real, ichar, int,
max,
min, mod, sqrt
351 wantz = lsame( jobz,
'V' )
352 lower = lsame( uplo,
'L' )
353 alleig = lsame( range,
'A' )
354 valeig = lsame( range,
'V' )
355 indeig = lsame( range,
'I' )
356 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
363 ictxt = desca( ctxt_ )
364 safmin =
pslamch( ictxt,
'Safe minimum' )
377 llwork = lwork - indwork + 1
387 nprocs = nprow * npcol
388 myproc = myrow * npcol + mycol
389 IF( nprow.EQ.-1 )
THEN
390 info = -( 800+ctxt_ )
391 ELSE IF( wantz )
THEN
392 IF( ictxt.NE.descz( ctxt_ ) )
THEN
393 info = -( 2100+ctxt_ )
404 ELSE IF ( indeig )
THEN
413 np00 = numroc( n, nb, 0, 0, nprow )
414 mq00 = numroc( mz, nb, 0, 0, npcol )
415 indrw = indwork +
max(18*n, np00*mq00 + 2*nb*nb)
416 lwmin = indrw - 1 + (iceil(mz, nprocs) + 2)*n
418 indrw = indwork + 12*n
422 lwmin =
max(3, lwmin)
424 anb = pjlaenv( ictxt, 3,
'PSSYTTRD',
'L', 0, 0, 0, 0 )
425 sqnpc = int( sqrt( real( nprocs ) ) )
426 nps =
max( numroc( n, 1, 0, 0, sqnpc ), 2*anb )
427 nsytrd_lwopt = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
428 lwopt =
max( lwopt, 5*n+nsytrd_lwopt )
430 size1 = indrw - indwork
437 nnp =
max( n, nprocs+1, 4 )
439 liwmin = 12*nnp + 2*n
441 liwmin = 10*nnp + 2*n
450 indilu = liwmin - 2*nprocs + 1
460 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
462 $
CALL chk1mat( n, 4, n, 4, iz, jz, descz, 21, info )
465 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
467 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) )
THEN
469 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
471 ELSE IF( mod( ia-1, desca( mb_ ) ).NE.0 )
THEN
473 ELSE IF( valeig .AND. n.GT.0 .AND. vu.LE.vl )
THEN
475 ELSE IF( indeig .AND. ( il.LT.1 .OR. il.GT.
max( 1, n ) ) )
478 ELSE IF( indeig .AND. ( iu.LT.
min( n, il ) .OR. iu.GT.n ) )
481 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
483 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
485 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
489 iarow = indxg2p( 1, desca( nb_ ), myrow,
490 $ desca( rsrc_ ), nprow )
491 izrow = indxg2p( 1, desca( nb_ ), myrow,
492 $ descz( rsrc_ ), nprow )
493 IF( iarow.NE.izrow )
THEN
495 ELSE IF( mod( ia-1, desca( mb_ ) ).NE.
496 $ mod( iz-1, descz( mb_ ) ) )
THEN
498 ELSE IF( desca( m_ ).NE.descz( m_ ) )
THEN
500 ELSE IF( desca( n_ ).NE.descz( n_ ) )
THEN
502 ELSE IF( desca( mb_ ).NE.descz( mb_ ) )
THEN
504 ELSE IF( desca( nb_ ).NE.descz( nb_ ) )
THEN
506 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) )
THEN
507 info = -( 2100+rsrc_ )
508 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) )
THEN
509 info = -( 2100+csrc_ )
510 ELSE IF( ictxt.NE.descz( ctxt_ ) )
THEN
511 info = -( 2100+ctxt_ )
517 idum1( 2 ) = ichar(
'L' )
519 idum1( 2 ) = ichar(
'U' )
523 idum1( 3 ) = ichar(
'A' )
524 ELSE IF( indeig )
THEN
525 idum1( 3 ) = ichar(
'I' )
527 idum1( 3 ) = ichar( 'v
' )
537 IDUM1( 1 ) = ICHAR( 'v
' )
538 CALL PCHK2MAT( N, 4, N, 4, IA, JA, DESCA, 8, N, 4, N, 4, IZ,
539 $ JZ, DESCZ, 21, 4, IDUM1, IDUM2, INFO )
541 IDUM1( 1 ) = ICHAR( 'n
' )
542 CALL PCHK1MAT( N, 4, N, 4, IA, JA, DESCA, 8, 4, IDUM1,
545 WORK( 1 ) = REAL( LWOPT )
550 CALL PXERBLA( ICTXT, 'pssyevr', -INFO )
552 ELSE IF( LQUERY ) THEN
566 WORK( 1 ) = REAL( LWOPT )
589 CALL PSSYNTRD( UPLO, N, A, IA, JA, DESCA, WORK( INDD ),
590 $ WORK( INDE ), WORK( INDTAU ), WORK( INDWORK ),
594.NE.
IF (IINFO 0) THEN
595 CALL PXERBLA( ICTXT, 'pssyntrd', -IINFO )
605.EQ..AND..EQ..AND.
IF( IA1 JA1
606.EQ..AND..EQ.
$ DESCA( RSRC_ )0 DESCA( CSRC_ )0 )
608 CALL PSLARED1D( N, IA, JA, DESCA, WORK( INDD ), WORK( INDD2 ),
609 $ WORK( INDWORK ), LLWORK )
611 CALL PSLARED1D( N, IA, JA, DESCA, WORK( INDE ), WORK( INDE2 ),
612 $ WORK( INDWORK ), LLWORK )
617 CALL PSELGET( 'a
', ' ', WORK( INDD2+I-1 ), A, I+IA-1,
620 IF( LSAME( UPLO, 'u
' ) ) THEN
622 CALL PSELGET( 'a
', ' ', WORK( INDE2+I-1 ), A, I+IA-1,
627 CALL PSELGET( 'a
', ' ', WORK( INDE2+I-1 ), A, I+IA,
644 ELSE IF ( INDEIG ) THEN
647 ELSE IF ( VALEIG ) THEN
648 CALL SLARRC('t
', N, VLL, VUU, WORK( INDD2 ),
649 $ WORK( INDE2 + OFFSET ), SAFMIN, EIGCNT, IIL, IIU, INFO)
660 WORK( 1 ) = REAL( LWOPT )
678 CALL PMPIM2( IIL, IIU, NPROCS,
679 $ IWORK(INDILU), IWORK(INDILU+NPROCS) )
683 MYIL = IWORK(INDILU+MYPROC)
684 MYIU = IWORK(INDILU+NPROCS+MYPROC)
687 ZOFFSET = MAX(0, MYIL - IIL - 1)
688.EQ.
FIRST = ( MYIL IIL )
701.GT.
IF ( MYIL0 ) THEN
703 DOU = MYIU - MYIL + 1
704 CALL SSTEGR2( JOBZ, 'i
', N, WORK( INDD2 ),
705 $ WORK( INDE2+OFFSET ), VLL, VUU, MYIL, MYIU,
706 $ IM, W( 1 ), WORK( INDRW ), N,
708 $ IWORK( 1 ), WORK( INDWORK ), SIZE1,
709 $ IWORK( 2*N+1 ), SIZE2,
710 $ DOL, DOU, ZOFFSET, IINFO )
715 W( MYIL-IIL+I ) = W( I )
720.NE.
IF (IINFO 0) THEN
721 CALL PXERBLA( ICTXT, 'sstegr2', -IINFO )
724.AND..EQ.
ELSEIF ( WANTZ NPROCS1 ) THEN
729.GT.
IF ( MYIL0 ) THEN
732 CALL SSTEGR2( JOBZ, 'i
', N, WORK( INDD2 ),
733 $ WORK( INDE2+OFFSET ), VLL, VUU, IIL, IIU,
734 $ IM, W( 1 ), WORK( INDRW ), N,
736 $ IWORK( 1 ), WORK( INDWORK ), SIZE1,
737 $ IWORK( 2*N+1 ), SIZE2, DOL, DOU,
740.NE.
IF (IINFO 0) THEN
741 CALL PXERBLA( ICTXT, 'sstegr2', -IINFO )
744 ELSEIF ( WANTZ ) THEN
752.GT.
IF ( MYIL0 ) THEN
755 CALL SSTEGR2A( JOBZ, 'i
', N, WORK( INDD2 ),
756 $ WORK( INDE2+OFFSET ), VLL, VUU, IIL, IIU,
757 $ IM, W( 1 ), WORK( INDRW ), N,
758 $ N, WORK( INDWORK ), SIZE1,
759 $ IWORK( 2*N+1 ), SIZE2, DOL,
760 $ DOU, NEEDIL, NEEDIU,
761 $ INDERR, NSPLIT, PIVMIN, SCALE, WL, WU,
764.NE.
IF (IINFO 0) THEN
765 CALL PXERBLA( ICTXT, 'sstegr2a', -IINFO )
777 IINDERR = INDWORK + INDERR - 1
795.EQ.
IF (MYPROC (I - 1)) THEN
801 LENGTHI = MYIU - MYIL + 1
806 CALL IGESD2D( ICTXT, 2, 1, IWORK, 2,
808.GE..AND..GE.
IF (( STARTI1 ) ( LENGTHI1 )) THEN
811 CALL SCOPY(LENGTHI,W( STARTI ),1,
814 CALL SCOPY(LENGTHI,WORK( IINDERR+STARTI-1 ),1,
815 $ WORK( INDD+LENGTHI ), 1)
817 CALL SGESD2D( ICTXT, LENGTHI2,
818 $ 1, WORK( INDD ), LENGTHI2,
821.EQ.
ELSE IF (MYPROC 0) THEN
822 SRCROW = (I-1) / NPCOL
823 SRCCOL = MOD(I-1, NPCOL)
824 CALL IGERV2D( ICTXT, 2, 1, IWORK, 2,
828.GE..AND..GE.
IF (( STARTI1 ) ( LENGTHI1 )) THEN
831 CALL SGERV2D( ICTXT, LENGTHI2, 1,
832 $ WORK(INDD), LENGTHI2, SRCROW, SRCCOL )
834 CALL SCOPY( LENGTHI, WORK(INDD), 1,
837 CALL SCOPY(LENGTHI,WORK(INDD+LENGTHI),1,
838 $ WORK( IINDERR+STARTI-1 ), 1)
842 LENGTHI = IIU - IIL + 1
843 LENGTHI2 = LENGTHI * 2
844.EQ.
IF (MYPROC 0) THEN
846 CALL SCOPY(LENGTHI,W ,1, WORK( INDD ), 1)
847 CALL SCOPY(LENGTHI,WORK( IINDERR ),1,
848 $ WORK( INDD+LENGTHI ), 1)
849 CALL SGEBS2D( ICTXT, 'a
', ' ', LENGTHI2, 1,
850 $ WORK(INDD), LENGTHI2 )
854 CALL SGEBR2D( ICTXT, 'a
', ' ', LENGTHI2, 1,
855 $ WORK(INDD), LENGTHI2, SRCROW, SRCCOL )
856 CALL SCOPY( LENGTHI, WORK(INDD), 1, W, 1)
857 CALL SCOPY(LENGTHI,WORK(INDD+LENGTHI),1,
858 $ WORK( IINDERR ), 1)
865.GT..AND..GT.
IF( (NPROCS1)(MYIL0) ) THEN
866 CALL PMPCOL( MYPROC, NPROCS, IIL, NEEDIL, NEEDIU,
867 $ IWORK(INDILU), IWORK(INDILU+NPROCS),
868 $ COLBRT, FRSTCL, LASTCL )
876 DO 47 IPROC = FRSTCL, LASTCL
877.EQ.
IF (MYPROC IPROC) THEN
880 LENGTHI = MYIU - MYIL + 1
883.GE..AND..GE.
IF ((STARTI1) (LENGTHI1)) THEN
885 CALL SCOPY(LENGTHI,W( STARTI ),1,
889 $ WORK( IINDERR+STARTI-1 ),1,
890 $ WORK(INDD+LENGTHI), 1)
893 DO 46 I = FRSTCL, LASTCL
894.EQ.
IF(IMYPROC) GOTO 46
896 DSTCOL = MOD(I, NPCOL)
897 CALL IGESD2D( ICTXT, 2, 1, IWORK, 2,
899.GE..AND..GE.
IF ((STARTI1) (LENGTHI1)) THEN
902 CALL SGESD2D( ICTXT, LENGTHI2,
903 $ 1, WORK(INDD), LENGTHI2,
908 SRCROW = IPROC / NPCOL
909 SRCCOL = MOD(IPROC, NPCOL)
910 CALL IGERV2D( ICTXT, 2, 1, IWORK, 2,
914.GE..AND..GE.
IF ((RSTARTI1 ) (RLENGTHI1 )) THEN
915 RLENGTHI2 = 2*RLENGTHI
916 CALL SGERV2D( ICTXT, RLENGTHI2, 1,
917 $ WORK(INDE), RLENGTHI2,
920 CALL SCOPY( RLENGTHI, WORK(INDE), 1,
923 CALL SCOPY(RLENGTHI,WORK(INDE+RLENGTHI),1,
924 $ WORK( IINDERR+RSTARTI-1 ), 1)
939.GT.
IF ( MYIL0 ) THEN
940 CALL SSTEGR2B( JOBZ, N, WORK( INDD2 ),
941 $ WORK( INDE2+OFFSET ),
942 $ IM, W( 1 ), WORK( INDRW ), N, N,
943 $ IWORK( 1 ), WORK( INDWORK ), SIZE1,
944 $ IWORK( 2*N+1 ), SIZE2, DOL,
945 $ DOU, NEEDIL, NEEDIU, INDWLC,
946 $ PIVMIN, SCALE, WL, WU,
948 $ MAXCLS, NDEPTH, PARITY, ZOFFSET, IINFO )
949 IINDWLC = INDWORK + INDWLC - 1
951.LT..OR..GT.
IF((NEEDILDOL)(NEEDIUDOU)) THEN
952 CALL PMPCOL( MYPROC, NPROCS, IIL, NEEDIL, NEEDIU,
953 $ IWORK(INDILU), IWORK(INDILU+NPROCS),
954 $ COLBRT, FRSTCL, LASTCL )
965 DO 147 IPROC = FRSTCL, LASTCL
966.EQ.
IF (MYPROC IPROC) THEN
970 LENGTHI = MYIU - MYIL + 1
975.GE..AND..GE.
IF ((STARTI1)(LENGTHI1)) THEN
978 $ WORK( IINDWLC+STARTI-1 ),1,
982 $ WORK( IINDERR+STARTI-1 ),1,
983 $ WORK(INDD+LENGTHI), 1)
986 DO 146 I = FRSTCL, LASTCL
987.EQ.
IF(IMYPROC) GOTO 146
989 DSTCOL = MOD(I, NPCOL)
990 CALL IGESD2D( ICTXT, 2, 1, IWORK, 2,
992.GE..AND..GE.
IF ((STARTI1)(LENGTHI1)) THEN
995 CALL SGESD2D( ICTXT, LENGTHI2,
996 $ 1, WORK(INDD), LENGTHI2,
1001 SRCROW = IPROC / NPCOL
1002 SRCCOL = MOD(IPROC, NPCOL)
1003 CALL IGERV2D( ICTXT, 2, 1, IWORK, 2,
1007.GE..AND..GE.
IF ((RSTARTI1)(RLENGTHI1)) THEN
1008 RLENGTHI2 = 2*RLENGTHI
1009 CALL SGERV2D( ICTXT,RLENGTHI2, 1,
1010 $ WORK(INDE),RLENGTHI2,
1013 CALL SCOPY(RLENGTHI, WORK(INDE), 1,
1014 $ WORK( IINDWLC+RSTARTI-1 ), 1)
1016 CALL SCOPY(RLENGTHI,WORK(INDE+RLENGTHI),1,
1017 $ WORK( IINDERR+RSTARTI-1 ), 1)
1025.NE.
IF (IINFO 0) THEN
1026 CALL PXERBLA( ICTXT, 'sstegr2b', -IINFO )
1047.EQ.
IF (MYPROC (I - 1)) THEN
1050 STARTI = MYIL - IIL + 1
1053 LENGTHI = MYIU - MYIL + 1
1058 CALL IGESD2D( ICTXT, 2, 1, IWORK, 2,
1060.GE..AND..GE.
IF ((STARTI1)(LENGTHI1)) THEN
1061 CALL SGESD2D( ICTXT, LENGTHI,
1062 $ 1, W( STARTI ), LENGTHI,
1065.EQ.
ELSE IF (MYPROC 0) THEN
1066 SRCROW = (I-1) / NPCOL
1067 SRCCOL = MOD(I-1, NPCOL)
1068 CALL IGERV2D( ICTXT, 2, 1, IWORK, 2,
1072.GE..AND..GE.
IF ((STARTI1)(LENGTHI1)) THEN
1073 CALL SGERV2D( ICTXT, LENGTHI, 1,
1074 $ W( STARTI ), LENGTHI, SRCROW, SRCCOL )
1081 CALL IGSUM2D( ICTXT, 'a',
' ', 1, 1, m, 1, -1, -1 )
1084 IF (myproc .EQ. 0)
THEN
1086 CALL sgebs2d( ictxt,
'A',
' ', m, 1, w, m )
1090 CALL sgebr2d( ictxt,
'A',
' ', m, 1,
1091 $ w, m, srcrow, srccol )
1098 iwork( nprocs+1+i ) = i
1100 CALL slasrt2(
'I', m, w, iwork( nprocs+2 ), iinfo )
1101 IF (iinfo.NE.0)
THEN
1102 CALL pxerbla( ictxt,
'SLASRT2', -iinfo )
1113 iwork( m+nprocs+1+iwork( nprocs+1+i ) ) = i
1117 DO 180 i = 1, nprocs
1120 ipil = iwork(indilu+i-1)
1121 ipiu = iwork(indilu+nprocs+i-1)
1122 IF (ipil .EQ. 0)
THEN
1123 iwork( i + 1 ) = iwork( i )
1125 iwork( i + 1 ) = iwork( i ) + ipiu - ipil + 1
1130 CALL pslaevswp(n, work( indrw ), n, z, iz, jz,
1131 $ descz, iwork( 1 ), iwork( nprocs+m+2 ), work( indwork ),
1134 CALL pslaevswp(n, work( indrw + n ), n, z, iz, jz,
1135 $ descz, iwork( 1 ), iwork( nprocs+m+2 ), work( indwork ),
1148 CALL psormtr(
'L', uplo,
'N', n, nz, a, ia, ja, desca,
1149 $ work( indtau ), z, iz, jz, descz,
1150 $ work( indwork ), size1, iinfo )
1152 IF (iinfo.NE.0)
THEN
1153 CALL pxerbla( ictxt,
'PSORMTR', -iinfo )
1160 work( 1 ) = real( lwopt )