1 SUBROUTINE pdsyttrd( UPLO, N, A, IA, JA, DESCA, D, E, TAU, WORK,
10 INTEGER IA, INFO, JA, LWORK, N
14 DOUBLE PRECISION A( * ), ( * ), 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.0d0 )
408 DOUBLE PRECISION Z_ONE, Z_NEGONE, Z_ZERO
409 parameter( z_one = 1.0d0, z_negone = -1.0d0,
411 DOUBLE PRECISION ZERO
412 parameter( zero = 0.0d+0 )
419 LOGICAL BALANCED, INTERLEAVE, TWOGEMMS, UPPER
420 INTEGER ANB, BINDEX, CURCOL, CURROW, , 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 DOUBLE PRECISION ALPHA, BETA, C, CONJTOPH, CONJTOPV, NORM,
430 $ oneoverbeta, safmax, safmin, toph, topnv,
438 INTEGER IDUM1( 1 ), IDUM2( 1 )
439 DOUBLE PRECISION CC( 3 ), DTMP( 5 )
450 INTEGER ICEIL, NUMROC, PJLAENV
451 DOUBLE PRECISION DNRM2, PDLAMCH
452 EXTERNAL lsame, iceil, numroc, pjlaenv, dnrm2, pdlamch
455 INTRINSIC dble, ichar,
max,
min, mod, sign, sqrt
461 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
484 ictxt = desca( ctxt_ )
487 safmax = sqrt( pdlamch( ictxt,
'O' ) ) / n
488 safmin = sqrt( pdlamch( ictxt,
'S' ) )
493 IF( nprow.EQ.-1 )
THEN
494 info = -( 600+ctxt_ )
499 pnb = pjlaenv( ictxt, 2,
'PDSYTTRD',
'L', 0, 0, 0, 0 )
500 anb = pjlaenv( ictxt, 3,
'PDSYTTRD',
'L', 0, 0, 0, 0 )
502 interleave = ( pjlaenv( ictxt, 4,
'PDSYTTRD',
'L', 1, 0, 0,
504 twogemms = ( pjlaenv( ictxt, 4,
'PDSYTTRD',
'L', 2, 0, 0,
506 balanced = ( pjlaenv( ictxt, 4,
'PDSYTTRD',
'L', 3, 0, 0,
509 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
512 upper = lsame( uplo,
'U' )
513 IF( info.EQ.0 .AND. desca( nb_ ).NE.1 )
530 nps =
max( numroc( n, 1, 0, 0, nprow ), 2*anb )
531 lwmin = 2*( anb+1 )*( 4*nps+2 ) + nps
533 work( 1 ) = dble( lwmin )
534 IF( .NOT.lsame( uplo,
'L' ) )
THEN
536 ELSE IF( ia.NE.1 )
THEN
538 ELSE IF( ja.NE.1 )
THEN
540 ELSE IF( nprow.NE.npcol )
THEN
541 info = -( 600+ctxt_ )
542 ELSE IF( desca( dtype_ ).NE.1 )
THEN
543 info = -( 600+dtype_ )
544 ELSE IF( desca( mb_ ).NE.1 )
THEN
546 ELSE IF( desca( nb_ ).NE.1 )
THEN
548 ELSE IF( desca( rsrc_ ).NE.0 )
THEN
549 info = -( 600+rsrc_ )
550 ELSE IF( desca( csrc_ ).NE.0 )
THEN
551 info = -( 600+csrc_ )
552 ELSE IF( lwork.LT.lwmin
THEN
557 idum1( 1 ) = ichar(
'U' )
559 idum1( 1 ) = ichar(
'L' )
563 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
568 CALL pxerbla( ictxt,
'PDSYTTRD', -info )
580 np = numroc( n, 1, myrow, 0, nprow )
581 nq = numroc( n, 1, mycol, 0, npcol )
592 ictxt = desca( ctxt_ )
613 IF( interleave )
THEN
629 ldv = 4*(
max( npm1, nqm1 ) ) + 2
634 invt = inh + ( anb+1 )*ldv
636 inht = invt + ldv / 2
637 intmp = invt + ldv*( anb+1 )
640 ldv =
max( npm1, nqm1 )
642 inht = inh + ldv*( anb+1 )
643 inv = inht + ldv*( anb+1 )
651 invt = inv + ldv*( anb+1 ) + 1
652 intmp = invt + ldv*( 2*anb )
658 work( 1 ) = dble( lwmin )
674 work( inh+i-1 ) = z_zero
675 work( inv+i-1 ) = z_zero
678 work( inht+i-1 ) = z_zero
687 IF( mycol.GT.myrow )
THEN
693 DO 210 minindex = 1, n - 1, anb
696 maxindex =
min( minindex+anb-1, n )
698 liib = numroc( maxindex, 1, myrow, 0, nprow ) + 1
702 inhtb = inht + lijb - 1
703 invtb = invt + lijb - 1
704 inhb = inh + liib - 1
705 invb = inv + liib - 1
710 DO 160 index = minindex,
min( maxindex, n-1 )
712 bindex = index - minindex
718 nxtcol = mod( curcol+1, npcol )
724 IF( myrow.EQ.currow )
THEN
728 IF( mycol.EQ.curcol )
THEN
746 indexa = lii + ( lij-1 )*lda
749 conjtoph = work( inht+lij-1+bindex*ldv )
752 IF( index.GT.1 )
THEN
755 a( indexa+i ) = a( indexa+i ) -
756 $ work( indexinv+ldv+i )*conjtoph -
757 $ work( indexinh+ldv+i )*conjtopv
765 IF( mycol.EQ.curcol )
THEN
769 IF( myrow.EQ.currow )
THEN
770 dtmp( 2 ) = a( lii+( lij-1 )*lda )
774 IF( myrow.EQ.nxtrow )
THEN
775 dtmp( 3 ) = a( liip1+( lij-1 )*lda )
782 norm = dnrm2( npm1, a( liip1
790 IF( dtmp( 1 ).GE.safmax .OR. dtmp( 1 ).LT.safmin )
THEN
795 dtmp( 1 ) = dtmp( 1 )*dtmp( 1 )
796 CALL dgsum2d( ictxt,
'C',
' ', 5, 1, dtmp, 5, -1,
798 IF( dtmp( 5 ).EQ.zero )
THEN
799 dtmp( 1 ) = sqrt( dtmp( 1 ) )
802 CALL pdtreecomb( ictxt,
'C', 1, dtmp, -1, mycol,
809 IF( myrow.EQ.currow .AND. mycol.EQ.curcol )
THEN
810 a( lii+( lij-1 )*lda ) = d( lij )
816 norm = sign( norm, alpha )
818 IF( norm.EQ.zero )
THEN
823 oneoverbeta = 1.0d0 / beta
825 CALL dscal( npm1, oneoverbeta,
826 $ a( liip1+( lij-1 )*lda ), 1 )
829 IF( myrow.EQ.nxtrow )
THEN
830 a( liip1+( lij-1 )*lda ) = z_one
841 DO 40 i = 0, npm1 - 1
842 work( inv+liip1-1+bindex*ldv+npm1+i ) = a( liip1+i+
846 IF( mycol.EQ.curcol )
THEN
847 work( inv+liip1-1+bindex*ldv+npm1+npm1 ) = toptau
848 CALL dgebs2d( ictxt, 'r
', ' ', NPM1+NPM1+1, 1,
849 $ WORK( INV+LIIP1-1+BINDEX*LDV ),
852 CALL DGEBR2D( ICTXT, 'r
', ' ', NPM1+NPM1+1, 1,
853 $ WORK( INV+LIIP1-1+BINDEX*LDV ),
854 $ NPM1+NPM1+1, MYROW, CURCOL )
855 TOPTAU = WORK( INV+LIIP1-1+BINDEX*LDV+NPM1+NPM1 )
857 DO 50 I = 0, NPM1 - 1
858 WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+I ) = WORK( INV+LIIP1-
859 $ 1+BINDEX*LDV+NPM1+I )
862.LT.
IF( INDEXN ) THEN
863.EQ..AND..EQ.
IF( MYROWNXTROW MYCOLCURCOL )
864 $ A( LIIP1+( LIJ-1 )*LDA ) = E( LIJ )
870.EQ.
IF( MYROWMYCOL ) THEN
871 DO 60 I = 0, NPM1 + NPM1
872 WORK( INVT+LIJP1-1+BINDEX*LDV+I ) = WORK( INV+LIIP1-1+
876 CALL DGESD2D( ICTXT, NPM1+NPM1, 1,
877 $ WORK( INV+LIIP1-1+BINDEX*LDV ), NPM1+NPM1,
879 CALL DGERV2D( ICTXT, NQM1+NQM1, 1,
880 $ WORK( INVT+LIJP1-1+BINDEX*LDV ), NQM1+NQM1,
884 DO 70 I = 0, NQM1 - 1
885 WORK( INHT+LIJP1-1+( BINDEX+1 )*LDV+I ) = WORK( INVT+
886 $ LIJP1-1+BINDEX*LDV+NQM1+I )
892.GT.
IF( INDEX1 ) THEN
893 DO 90 J = LIJP1, LIJB - 1
894 DO 80 I = 0, NPM1 - 1
896 A( LIIP1+I+( J-1 )*LDA ) = A( LIIP1+I+( J-1 )*LDA )
897 $ - WORK( INV+LIIP1-1+BINDEX*LDV+I )*
898 $ WORK( INHT+J-1+BINDEX*LDV ) -
899 $ WORK( INH+LIIP1-1+BINDEX*LDV+I )*
900 $ WORK( INVT+J-1+BINDEX*LDV )
917 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV ) = Z_ZERO
918 WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV+NQM1-1 ) = Z_ZERO
921.EQ.
IF( MYROWMYCOL ) THEN
922.GT.
IF( LTNM11 ) THEN
923 CALL DTRMVT( 'l
', LTNM1-1,
924 $ A( LTLIP1+1+( LIJP1-1 )*LDA ), LDA,
925 $ WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV ), 1,
926 $ WORK( INH+LTLIP1+1-1+( BINDEX+1 )*LDV ),
927 $ 1, WORK( INV+LTLIP1+1-1+( BINDEX+1 )*
928 $ LDV ), 1, WORK( INHT+LIJP1-1+( BINDEX+
932 WORK( INVT+LIJP1+I-1-1+( BINDEX+1 )*LDV )
933 $ = WORK( INVT+LIJP1+I-1-1+( BINDEX+1 )*LDV ) +
934 $ A( LTLIP1+I-1+( LIJP1+I-1-1 )*LDA )*
935 $ WORK( INH+LTLIP1+I-1-1+( BINDEX+1 )*LDV )
939 $ CALL DTRMVT( 'l
', LTNM1, A( LTLIP1+( LIJP1-1 )*LDA ),
940 $ LDA, WORK( INVT+LIJP1-1+( BINDEX+1 )*
941 $ LDV ), 1, WORK( INH+LTLIP1-1+( BINDEX+
942 $ 1 )*LDV ), 1, WORK( INV+LTLIP1-1+
943 $ ( BINDEX+1 )*LDV ), 1,
944 $ WORK( INHT+LIJP1-1+( BINDEX+1 )*LDV ),
963 DO 110 I = 1, 2*( BINDEX+1 )
964 WORK( INTMP-1+I ) = 0
970 ROWSPERPROC = ICEIL( NQB, NPSET )
971 MYFIRSTROW = MIN( NQB+1, 1+ROWSPERPROC*MYSETNUM )
972 NUMROWS = MIN( ROWSPERPROC, NQB-MYFIRSTROW+1 )
977 CALL DGEMV( 'c
', NUMROWS, BINDEX+1, Z_ONE,
978 $ WORK( INHTB+MYFIRSTROW-1 ), LDV,
979 $ WORK( INHTB+MYFIRSTROW-1+( BINDEX+1 )*LDV ),
980 $ 1, Z_ZERO, WORK( INTMP ), 1 )
982 CALL DGEMV( 'c
', NUMROWS, BINDEX+1, Z_ONE,
983 $ WORK( INVTB+MYFIRSTROW-1 ), LDV,
984 $ WORK( INHTB+MYFIRSTROW-1+( BINDEX+1 )*LDV ),
985 $ 1, Z_ZERO, WORK( INTMP+BINDEX+1 ), 1 )
988 CALL DGSUM2D( ICTXT, 'c
', ' ', 2*( BINDEX+1 ), 1,
989 $ WORK( INTMP ), 2*( BINDEX+1 ), -1, -1 )
993 CALL DGEMV( 'c
', NQB, BINDEX+1, Z_ONE, WORK( INHTB ),
994 $ LDV, WORK( INHTB+( BINDEX+1 )*LDV ), 1,
995 $ Z_ZERO, WORK( INTMP ), 1 )
997 CALL DGEMV( 'c
', NQB, BINDEX+1, Z_ONE, WORK( INVTB ),
998 $ LDV, WORK( INHTB+( BINDEX+1 )*LDV ), 1,
999 $ Z_ZERO, WORK( INTMP+BINDEX+1 ), 1 )
1008 ROWSPERPROC = ICEIL( NPB, NPSET )
1009 MYFIRSTROW = MIN( NPB+1, 1+ROWSPERPROC*MYSETNUM )
1010 NUMROWS = MIN( ROWSPERPROC, NPB-MYFIRSTROW+1 )
1012 CALL DGSUM2D( ICTXT, 'r
', ' ', 2*( BINDEX+1 ), 1,
1013 $ WORK( INTMP ), 2*( BINDEX+1 ), -1, -1 )
1017.GT.
IF( INDEX1. ) THEN
1018 CALL DGEMV( 'n
', NUMROWS, BINDEX+1, Z_NEGONE,
1019 $ WORK( INVB+MYFIRSTROW-1 ), LDV,
1020 $ WORK( INTMP ), 1, Z_ONE,
1021 $ WORK( INVB+MYFIRSTROW-1+( BINDEX+1 )*
1025 CALL DGEMV( 'n
', NUMROWS, BINDEX+1, Z_NEGONE,
1026 $ WORK( INHB+MYFIRSTROW-1 ), LDV,
1027 $ WORK( INTMP+BINDEX+1 ), 1, Z_ONE,
1028 $ WORK( INVB+MYFIRSTROW-1+( BINDEX+1 )*
1034 CALL DGEMV( 'n
', NPB, BINDEX+1, Z_NEGONE, WORK( INVB ),
1035 $ LDV, WORK( INTMP ), 1, Z_ONE,
1036 $ WORK( INVB+( BINDEX+1 )*LDV ), 1 )
1040 CALL DGEMV( 'n
', NPB, BINDEX+1, Z_NEGONE, WORK( INHB ),
1041 $ LDV, WORK( INTMP+BINDEX+1 ), 1, Z_ONE,
1042 $ WORK( INVB+( BINDEX+1 )*LDV ), 1 )
1049.EQ.
IF( MYROWMYCOL ) THEN
1050 DO 120 I = 0, NQM1 - 1
1051 WORK( INTMP+I ) = WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV+
1055 CALL DGESD2D( ICTXT, NQM1, 1,
1056 $ WORK( INVT+LIJP1-1+( BINDEX+1 )*LDV ),
1057 $ NQM1, MYCOL, MYROW )
1058 CALL DGERV2D( ICTXT, NPM1, 1, WORK( INTMP ), NPM1, MYCOL,
1062 DO 130 I = 0, NPM1 - 1
1063 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I ) = WORK( INV+LIIP1-
1064 $ 1+( BINDEX+1 )*LDV+I ) + WORK( INTMP+I )
1069 CALL DGSUM2D( ICTXT, 'r
', ' ', NPM1, 1,
1070 $ WORK( INV+LIIP1-1+( BINDEX+1 )*LDV ), NPM1,
1078.EQ.
IF( MYCOLNXTCOL ) THEN
1080 DO 140 I = 0, NPM1 - 1
1081 CC( 1 ) = CC( 1 ) + WORK( INV+LIIP1-1+( BINDEX+1 )*
1082 $ LDV+I )*WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+
1085.EQ.
IF( MYROWNXTROW ) THEN
1086 CC( 2 ) = WORK( INV+LIIP1-1+( BINDEX+1 )*LDV )
1087 CC( 3 ) = WORK( INH+LIIP1-1+( BINDEX+1 )*LDV )
1092 CALL DGSUM2D( ICTXT, 'c
', ' ', 3, 1, CC, 3, -1, NXTCOL )
1098 TOPNV = TOPTAU*( TOPV-C*TOPTAU / 2*TOPH )
1104 DO 150 I = 0, NPM1 - 1
1105 WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I ) = TOPTAU*
1106 $ ( WORK( INV+LIIP1-1+( BINDEX+1 )*LDV+I )-C*TOPTAU /
1107 $ 2*WORK( INH+LIIP1-1+( BINDEX+1 )*LDV+I ) )
1118.LT.
IF( MAXINDEXN ) THEN
1120 DO 170 I = 0, NPM1 - 1
1121 WORK( INTMP+I ) = WORK( INH+LIIP1-1+ANB*LDV+I )
1126.NOT.
IF( TWOGEMMS ) THEN
1127 IF( INTERLEAVE ) THEN
1130 CALL DLAMOV( 'a
', LTNM1, ANB, WORK( INHT+LIJP1-1 ),
1131 $ LDV, WORK( INVT+LIJP1-1+ANB*LDV ), LDV )
1133 CALL DLAMOV( 'a
', LTNM1, ANB, WORK( INV+LTLIP1-1 ),
1134 $ LDV, WORK( INH+LTLIP1-1+ANB*LDV ), LDV )
1144 DO 180 PBMIN = 1, LTNM1, PNB
1146 PBSIZE = MIN( PNB, LTNM1-PBMIN+1 )
1147 PBMAX = MIN( LTNM1, PBMIN+PNB-1 )
1148 CALL DGEMM( 'n
', 'c
', PBSIZE, PBMAX, NBZG, Z_NEGONE,
1149 $ WORK( INH+LTLIP1-1+PBMIN-1 ), LDZG,
1150 $ WORK( INVT+LIJP1-1 ), LDZG, Z_ONE,
1151 $ A( LTLIP1+PBMIN-1+( LIJP1-1 )*LDA ), LDA )
1153 CALL DGEMM( 'n
', 'c
', PBSIZE, PBMAX, ANB, Z_NEGONE,
1154 $ WORK( INV+LTLIP1-1+PBMIN-1 ), LDZG,
1155 $ WORK( INHT+LIJP1-1 ), LDZG, Z_ONE,
1156 $ A( LTLIP1+PBMIN-1+( LIJP1-1 )*LDA ), LDA )
1162 DO 190 I = 0, NPM1 - 1
1163 WORK( INV+LIIP1-1+I ) = WORK( INV+LIIP1-1+ANB*LDV+I )
1164 WORK( INH+LIIP1-1+I ) = WORK( INTMP+I )
1166 DO 200 I = 0, NQM1 - 1
1167 WORK( INHT+LIJP1-1+I ) = WORK( INHT+LIJP1-1+ANB*LDV+I )
1177.EQ.
IF( MYCOLNXTCOL ) THEN
1178.EQ.
IF( MYROWNXTROW ) THEN
1180 D( NQ ) = A( NP+( NQ-1 )*LDA )
1182 CALL DGEBS2D( ICTXT, 'c
', ' ', 1, 1, D( NQ ), 1 )
1184 CALL DGEBR2D( ICTXT, 'c
', ' ', 1, 1, D( NQ ), 1, NXTROW,
1192 WORK( 1 ) = DBLE( LWMIN )