1 SUBROUTINE pssyttrd( UPLO, N, A, IA, JA, DESCA, D, E, TAU, WORK,
10 INTEGER IA, INFO, JA, LWORK, N
14 REAL A( * ), D( * ), E( * ), TAU( * ), WORK( * )
401 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
402 $ mb_, nb_, rsrc_, csrc_, lld_
403 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
404 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
405 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
407 parameter( one = 1.0e0 )
408 REAL Z_ONE, Z_NEGONE, Z_ZERO
409 parameter( z_one = 1.0e0, z_negone = -1.0e0,
412 parameter( zero = 0.0e+0 )
419 LOGICAL BALANCED, INTERLEAVE, , UPPER
420 INTEGER ANB, BINDEX, CURCOL, CURROW, I, ICTXT, INDEX,
421 $ indexa, indexinh, indexinv, inh, inhb, inht,
422 $ inhtb, intmp, inv, invb, invt, invtb, j, lda,
423 $ ldv, ldzg, lii, liib, liip1, lij, lijb, lijp1,
424 $ ltlip1, ltnm1, lwmin, maxindex, minindex,
425 $ mycol, myfirstrow, myrow, mysetnum, nbzg, np,
426 $ npb, npcol, npm0, npm1, nprow, nps, npset, nq,
427 $ nqb, nqm1, numrows, nxtcol, nxtrow, pbmax,
428 $ pbmin, pbsize, pnb, rowsperproc
429 REAL ALPHA, BETA, C, NORM, ONEOVERBETA, SAFMAX,
430 $ safmin, toph, topnv, toptau, topv, ttoph, ttopv
437 INTEGER IDUM1( 1 ), IDUM2( 1 )
438 REAL CC( 3 ), DTMP( 5 )
443 $
sgemv, sgerv2d, sgesd2d, sgsum2d, slamov,
449 INTEGER ICEIL, NUMROC, PJLAENV
451 EXTERNAL lsame, iceil, numroc, pjlaenv, pslamch, snrm2
454 INTRINSIC ichar,
max,
min, mod, real, sign, sqrt
460 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
483 ictxt = desca( ctxt_ )
486 safmax = sqrt( pslamch( ictxt,
'O' ) ) / n
487 safmin = sqrt( pslamch( ictxt,
'S' ) )
492 IF( nprow.EQ.-1 )
THEN
493 info = -( 600+ctxt_ )
498 pnb = pjlaenv( ictxt, 2,
'PSSYTTRD',
'L', 0, 0, 0,
499 anb = pjlaenv( ictxt, 3,
'PSSYTTRD',
'L', 0, 0, 0, 0 )
501 interleave = ( pjlaenv( ictxt, 4,
'PSSYTTRD',
'L', 1, 0, 0,
503 twogemms = ( pjlaenv( ictxt, 4,
'PSSYTTRD',
'L', 2, 0, 0,
505 balanced = ( pjlaenv( ictxt, 4,
'PSSYTTRD',
'L', 3, 0, 0,
508 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
511 upper = lsame( uplo,
'U' )
512 IF( info.EQ.0 .AND. desca( nb_ ).NE.1 )
529 nps =
max( numroc( n, 1, 0, 0, nprow ), 2*anb )
530 lwmin = 2*( anb+1 )*( 4*nps+2 ) + nps
532 work( 1 ) = real( lwmin )
533 IF( .NOT.lsame( uplo,
'L' ) )
THEN
535 ELSE IF( ia.NE.1 )
THEN
537 ELSE IF( ja.NE.1 )
THEN
539 ELSE IF( nprow.NE.npcol )
THEN
540 info = -( 600+ctxt_ )
541 ELSE IF( desca( dtype_ ).NE.1 )
THEN
542 info = -( 600+dtype_ )
543 ELSE IF( desca( mb_ ).NE.1 )
THEN
545 ELSE IF( desca( nb_ ).NE.1 )
THEN
547 ELSE IF( desca( rsrc_ ).NE.0 )
THEN
548 info = -( 600+rsrc_ )
549 ELSE IF( desca( csrc_ ).NE.0 )
THEN
550 info = -( 600+csrc_ )
551 ELSE IF( lwork.LT.lwmin )
THEN
556 idum1( 1 ) = ichar(
'U' )
558 idum1( 1 ) = ichar(
'L' )
562 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
567 CALL pxerbla( ictxt,
'PSSYTTRD', -info )
579 np = numroc( n, 1, myrow, 0, nprow )
580 nq = numroc( n, 1, mycol, 0, npcol )
591 ictxt = desca( ctxt_ )
612 IF( interleave )
THEN
628 ldv = 4*(
max( npm1, nqm1 ) ) + 2
633 invt = inh + ( anb+1 )*ldv
635 inht = invt + ldv / 2
636 intmp = invt + ldv*( anb+1 )
639 ldv =
max( npm1, nqm1 )
641 inht = inh + ldv*( anb+1 )
642 inv = inht + ldv*( anb+1 )
650 invt = inv + ldv*( anb+1 ) + 1
651 intmp = invt + ldv*( 2*anb )
656 CALL pxerbla( ictxt,
'PSSYTTRD', -info )
657 work( 1 ) = real( lwmin )
673 work( inh+i-1 ) = z_zero
674 work( inv+i-1 ) = z_zero
677 work( inht+i-1 ) = z_zero
686 IF( mycol.GT.myrow )
THEN
692 DO 210 minindex = 1, n - 1, anb
695 maxindex =
min( minindex+anb-1, n )
696 lijb = numroc( maxindex, 1, mycol, 0, npcol ) + 1
697 liib = numroc( maxindex, 1, myrow, 0, nprow ) + 1
701 inhtb = inht + lijb - 1
702 invtb = invt + lijb - 1
703 inhb = inh + liib - 1
704 invb = inv + liib - 1
709 DO 160 index = minindex,
min( maxindex, n-1 )
711 bindex = index - minindex
716 nxtrow = mod( currow+1, nprow )
717 nxtcol = mod( curcol+1, npcol )
723 IF( myrow.EQ.currow )
THEN
727 IF( mycol.EQ.curcol )
THEN
743 IF( mycol.EQ.curcol )
THEN
745 indexa = lii + ( lij-1 )*lda
746 indexinv = inv + lii - 1 + ( bindex-1 )*ldv
747 indexinh = inh + lii - 1 + ( bindex-1 )*ldv
748 ttoph = work( inht+lij-1+bindex*ldv )
751 IF( index.GT.1 )
THEN
752 DO 30 i = 0, npm0 - 1
754 a( indexa+i ) = a( indexa+i ) -
755 $ work( indexinv+ldv+i )*ttoph -
756 $ work( indexinh+ldv+i )*ttopv
764 IF( mycol.EQ.curcol )
THEN
768 IF( myrow.EQ.currow )
THEN
769 dtmp( 2 ) = a( lii+( lij-1 )*lda )
773 IF( myrow.EQ.nxtrow )
THEN
774 dtmp( 3 ) = a( liip1+( lij-1 )*lda )
781 norm = snrm2( npm1, a( liip1+( lij-1 )*lda ), 1 )
789 IF( dtmp( 1 ).GE.safmax .OR. dtmp( 1 ).LT.safmin )
THEN
794 dtmp( 1 ) = dtmp( 1 )*dtmp( 1 )
795 CALL sgsum2d( ictxt,
'C',
' ', 5, 1, dtmp, 5, -1,
797 IF( dtmp( 5 ).EQ.zero )
THEN
798 dtmp( 1 ) = sqrt( dtmp( 1 ) )
801 CALL pstreecomb( ictxt,
'C', 1, dtmp, -1, mycol,
808 IF( myrow.EQ.currow .AND. mycol.EQ.curcol )
THEN
809 a( lii+( lij-1 )*lda ) = d( lij )
815 norm = sign( norm, alpha )
817 IF( norm.EQ.zero )
THEN
822 oneoverbeta = 1.0e0 / beta
824 CALL sscal( npm1, oneoverbeta,
825 $ a( liip1+( lij-1 )*lda ), 1 )
828 IF( myrow.EQ.nxtrow )
THEN
829 a( liip1+( lij-1 )*lda ) = z_one
840 DO 40 i = 0, npm1 - 1
841 work( inv+liip1-1+bindex*ldv+npm1+i ) = a( liip1+i+
845 IF( mycol.EQ.curcol )
THEN
846 work( inv+liip1-1+bindex*ldv+npm1+npm1 ) = toptau
847 CALL sgebs2d( ictxt,
'R', '
', NPM1+NPM1+1, 1,
848 $ WORK( INV+LIIP1-1+BINDEX*LDV ),
851 CALL SGEBR2D( ICTXT, 'r
', ' ', NPM1+NPM1+1, 1,
852 $ WORK( INV+LIIP1-1+BINDEX*LDV ),
853 $ NPM1+NPM1+1, MYROW, CURCOL )
854 TOPTAU = WORK( INV+LIIP1-1+BINDEX*LDV+NPM1+NPM1 )
856 DO 50 I = 0, NPM1 - 1
857 WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+I ) = WORK( INV+LIIP1-
858 $ 1+BINDEX*LDV+NPM1+I )
861.LT.
IF( INDEXN ) THEN
862.EQ..AND..EQ.
IF( MYROWNXTROW MYCOLCURCOL )
863 $ A( LIIP1+( LIJ-1 )*LDA ) = E( LIJ )
869.EQ.
IF( MYROWMYCOL ) THEN
870 DO 60 I = 0, NPM1 + NPM1
871 WORK( INVT+LIJP1-1+BINDEX*LDV+I ) = WORK( INV+LIIP1-1+
875 CALL SGESD2D( ICTXT, NPM1+NPM1, 1,
876 $ WORK( INV+LIIP1-1+BINDEX*LDV ), NPM1+NPM1,
878 CALL SGERV2D( ICTXT, NQM1+NQM1, 1,
879 $ WORK( INVT+LIJP1-1+BINDEX*LDV ), NQM1+NQM1,
883 DO 70 I = 0, NQM1 - 1
884 WORK( INHT+LIJP1-1+( BINDEX+1 )*LDV+I ) = WORK( INVT+
885 $ LIJP1-1+BINDEX*LDV+NQM1+I )
891.GT.
IF( INDEX1 ) THEN
892 DO 90 J = LIJP1, LIJB - 1
893 DO 80 I = 0, NPM1 - 1
895 A( LIIP1+I+( J-1 )*LDA ) = A( LIIP1+I+( J-1 )*LDA )
896 $ - WORK( INV+LIIP1-1+BINDEX*LDV+I )*
897 $ WORK( INHT+J-1+BINDEX*LDV ) -
898 $ WORK( INH+LIIP1-1+BINDEX*LDV+I )*
899 $ WORK( INVT+J-1+BINDEX*LDV )
916 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV ) = Z_ZERO
917 WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV+NQM1-1 ) = Z_ZERO
920.EQ.
IF( MYROWMYCOL ) THEN
921.GT.
IF( LTNM11 ) THEN
922 CALL STRMVT( 'l
', LTNM1-1,
923 $ A( LTLIP1+1+( LIJP1-1 )*LDA ), LDA,
924 $ WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV ), 1,
925 $ WORK( INH+LTLIP1+1-1+( BINDEX+1 )*LDV ),
926 $ 1, WORK( INV+LTLIP1+1-1+( BINDEX+1 )*
927 $ LDV ), 1, WORK( INHT+LIJP1-1+( BINDEX+
931 WORK( INVT+LIJP1+I-1-1+( BINDEX+1 )*LDV )
932 $ = WORK( INVT+LIJP1+I-1-1+( BINDEX+1 )*LDV ) +
933 $ A( LTLIP1+I-1+( LIJP1+I-1-1 )*LDA )*
934 $ WORK( INH+LTLIP1+I-1-1+( BINDEX+1 )*LDV )
938 $ CALL STRMVT( 'l
', LTNM1, A( LTLIP1+( LIJP1-1 )*LDA ),
939 $ LDA, WORK( INVT+LIJP1-1+( BINDEX+1 )*
940 $ LDV ), 1, WORK( INH+LTLIP1-1+( BINDEX+
941 $ 1 )*LDV ), 1, WORK( INV+LTLIP1-1+
942 $ ( BINDEX+1 )*LDV ), 1,
943 $ WORK( INHT+LIJP1-1+( BINDEX+1 )*LDV ),
962 DO 110 I = 1, 2*( BINDEX+1 )
963 WORK( INTMP-1+I ) = 0
969 ROWSPERPROC = ICEIL( NQB, NPSET )
970 MYFIRSTROW = MIN( NQB+1, 1+ROWSPERPROC*MYSETNUM )
971 NUMROWS = MIN( ROWSPERPROC, NQB-MYFIRSTROW+1 )
976 CALL SGEMV( 'c
', NUMROWS, BINDEX+1, Z_ONE,
977 $ WORK( INHTB+MYFIRSTROW-1 ), LDV,
978 $ WORK( INHTB+MYFIRSTROW-1+( BINDEX+1 )*LDV ),
979 $ 1, Z_ZERO, WORK( INTMP ), 1 )
981 CALL SGEMV( 'c
', NUMROWS, BINDEX+1, Z_ONE,
982 $ WORK( INVTB+MYFIRSTROW-1 ), LDV,
983 $ WORK( INHTB+MYFIRSTROW-1+( BINDEX+1 )*LDV ),
984 $ 1, Z_ZERO, WORK( INTMP+BINDEX+1 ), 1 )
987 CALL SGSUM2D( ICTXT, 'c
', ' ', 2*( BINDEX+1 ), 1,
988 $ WORK( INTMP ), 2*( BINDEX+1 ), -1, -1 )
992 CALL SGEMV( 'c
', NQB, BINDEX+1, Z_ONE, WORK( INHTB ),
993 $ LDV, WORK( INHTB+( BINDEX+1 )*LDV ), 1,
994 $ Z_ZERO, WORK( INTMP ), 1 )
996 CALL SGEMV( 'c
', NQB, BINDEX+1, Z_ONE, WORK( INVTB ),
997 $ LDV, WORK( INHTB+( BINDEX+1 )*LDV ), 1,
998 $ Z_ZERO, WORK( INTMP+BINDEX+1 ), 1 )
1007 ROWSPERPROC = ICEIL( NPB, NPSET )
1008 MYFIRSTROW = MIN( NPB+1, 1+ROWSPERPROC*MYSETNUM )
1009 NUMROWS = MIN( ROWSPERPROC, NPB-MYFIRSTROW+1 )
1011 CALL SGSUM2D( ICTXT, 'r
', ' ', 2*( BINDEX+1 ), 1,
1012 $ WORK( INTMP ), 2*( BINDEX+1 ), -1, -1 )
1016.GT.
IF( INDEX1. ) THEN
1017 CALL SGEMV( 'n
', NUMROWS, BINDEX+1, Z_NEGONE,
1018 $ WORK( INVB+MYFIRSTROW-1 ), LDV,
1019 $ WORK( INTMP ), 1, Z_ONE,
1020 $ WORK( INVB+MYFIRSTROW-1+( BINDEX+1 )*
1024 CALL SGEMV( 'n
', NUMROWS, BINDEX+1, Z_NEGONE,
1025 $ WORK( INHB+MYFIRSTROW-1 ), LDV,
1026 $ WORK( INTMP+BINDEX+1 ), 1, Z_ONE,
1027 $ WORK( INVB+MYFIRSTROW-1+( BINDEX+1 )*
1033 CALL SGEMV( 'n
', NPB, BINDEX+1, Z_NEGONE, WORK( INVB ),
1034 $ LDV, WORK( INTMP ), 1, Z_ONE,
1035 $ WORK( INVB+( BINDEX+1 )*LDV ), 1 )
1039 CALL SGEMV( 'n
', NPB, BINDEX+1, Z_NEGONE, WORK( INHB ),
1040 $ LDV, WORK( INTMP+BINDEX+1 ), 1, Z_ONE,
1041 $ WORK( INVB+( BINDEX+1 )*LDV ), 1 )
1048.EQ.
IF( MYROWMYCOL ) THEN
1049 DO 120 I = 0, NQM1 - 1
1050 WORK( INTMP+I ) = WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV+
1054 CALL SGESD2D( ICTXT, NQM1, 1,
1055 $ WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV ),
1056 $ NQM1, MYCOL, MYROW )
1057 CALL SGERV2D( ICTXT, NPM1, 1, WORK( INTMP ), NPM1, MYCOL,
1061 DO 130 I = 0, NPM1 - 1
1062 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I ) = WORK( INV+LIIP1-
1063 $ 1+( BINDEX+1 )*LDV+I ) + WORK( INTMP+I )
1068 CALL SGSUM2D( ICTXT, 'r
', ' ', NPM1, 1,
1069 $ WORK( INV+LIIP1-1+( BINDEX+1 )*LDV ), NPM1,
1077.EQ.
IF( MYCOLNXTCOL ) THEN
1079 DO 140 I = 0, NPM1 - 1
1080 CC( 1 ) = CC( 1 ) + WORK( INV+LIIP1-1+( BINDEX+1 )*
1081 $ LDV+I )*WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+
1084.EQ.
IF( MYROWNXTROW ) THEN
1085 CC( 2 ) = WORK( INV+LIIP1-1+( BINDEX+1 )*LDV )
1086 CC( 3 ) = WORK( INH+LIIP1-1+( BINDEX+1 )*LDV )
1091 CALL SGSUM2D( ICTXT, 'c
', ' ', 3, 1, CC, 3, -1, NXTCOL )
1097 TOPNV = TOPTAU*( TOPV-C*TOPTAU / 2*TOPH )
1103 DO 150 I = 0, NPM1 - 1
1104 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I ) = TOPTAU*
1105 $ ( WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I )-C*TOPTAU /
1106 $ 2*WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+I ) )
1117.LT.
IF( MAXINDEXN ) THEN
1119 DO 170 I = 0, NPM1 - 1
1120 WORK( INTMP+I ) = WORK( INH+LIIP1-1+ANB*LDV+I )
1125.NOT.
IF( TWOGEMMS ) THEN
1126 IF( INTERLEAVE ) THEN
1129 CALL SLAMOV( 'a
', LTNM1, ANB, WORK( INHT+LIJP1-1 ),
1130 $ LDV, WORK( INVT+LIJP1-1+ANB*LDV ), LDV )
1132 CALL SLAMOV( 'a
', LTNM1, ANB, WORK( INV+LTLIP1-1 ),
1133 $ LDV, WORK( INH+LTLIP1-1+ANB*LDV ), LDV )
1143 DO 180 PBMIN = 1, LTNM1, PNB
1145 PBSIZE = MIN( PNB, LTNM1-PBMIN+1 )
1146 PBMAX = MIN( LTNM1, PBMIN+PNB-1 )
1147 CALL SGEMM( 'n
', 'c
', PBSIZE, PBMAX, NBZG, Z_NEGONE,
1148 $ WORK( INH+LTLIP1-1+PBMIN-1 ), LDZG,
1149 $ WORK( INVT+LIJP1-1 ), LDZG, Z_ONE,
1150 $ A( LTLIP1+PBMIN-1+( LIJP1-1 )*LDA ), LDA )
1152 CALL SGEMM( 'n
', 'c
', PBSIZE, PBMAX, ANB, Z_NEGONE,
1153 $ WORK( INV+LTLIP1-1+PBMIN-1 ), LDZG,
1154 $ WORK( INHT+LIJP1-1 ), LDZG, Z_ONE,
1155 $ A( LTLIP1+PBMIN-1+( LIJP1-1 )*LDA ), LDA )
1161 DO 190 I = 0, NPM1 - 1
1162 WORK( INV+LIIP1-1+I ) = WORK( INV+LIIP1-1+ANB*LDV+I )
1163 WORK( INH+LIIP1-1+I ) = WORK( INTMP+I )
1165 DO 200 I = 0, NQM1 - 1
1166 WORK( INHT+LIJP1-1+I ) = WORK( INHT+LIJP1-1+ANB*LDV+I )
1176.EQ.
IF( MYCOLNXTCOL ) THEN
1177.EQ.
IF( MYROWNXTROW ) THEN
1179 D( NQ ) = A( NP+( NQ-1 )*LDA )
1181 CALL SGEBS2D( ICTXT, 'c
', ' ', 1, 1, D( NQ ), 1 )
1183 CALL SGEBR2D( ICTXT, 'c
', ' ', 1, 1, D( NQ ), 1, NXTROW,
1191 WORK( 1 ) = REAL( LWMIN )