1 SUBROUTINE pclattrs( UPLO, TRANS, DIAG, NORMIN, N, A, IA, JA,
2 $ DESCA, X, IX, JX, DESCX, SCALE, CNORM, INFO )
10 CHARACTER DIAG, NORMIN, TRANS, UPLO
11 INTEGER IA, INFO, IX, JA, JX, N
15 INTEGER DESCA( * ), DESCX( * )
17 COMPLEX A( * ), X( * )
255 REAL ZERO, HALF, ONE, TWO
256 parameter( zero = 0.0e+0, half = 0.5e+0, one = 1.0e+0,
259 parameter( czero = ( 0.0e+0, 0.0e+0 ),
260 $ cone = ( 1.0e+0, 0.0e+0 ) )
261 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
262 $ mb_, nb_, rsrc_, csrc_, lld_
263 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
264 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
265 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
268 LOGICAL NOTRAN, NOUNIT, UPPER
269 INTEGER CONTXT, CSRC, I, ICOL, ICOLX, IMAX, IROW,
270 $ irowx, itmp1, itmp1x, itmp2, itmp2x, j, jfirst,
271 $ jinc, jlast, lda, ldx, mb, mycol, myrow, nb,
273 REAL BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
276 COMPLEX CSUMJ, TJJS, USCAL, XJTMP, ZDUM
283 EXTERNAL lsame, isamax, pslamch, cladiv
298 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
299 cabs2( zdum ) = abs( real( zdum
300 $ abs( aimag( zdum ) / 2.e0 )
305 upper = lsame( uplo,
'U' )
306 notran = lsame( trans, 'n
' )
307 NOUNIT = LSAME( DIAG, 'n
' )
309 CONTXT = DESCA( CTXT_ )
310 RSRC = DESCA( RSRC_ )
311 CSRC = DESCA( CSRC_ )
319.NOT..AND..NOT.
IF( UPPER LSAME( UPLO, 'l
' ) ) THEN
321.NOT..AND..NOT.
ELSE IF( NOTRAN LSAME( TRANS, 't.AND..NOT.
' )
322 $ LSAME( TRANS, 'c
' ) ) THEN
324.NOT..AND..NOT.
ELSE IF( NOUNIT LSAME( DIAG, 'u
' ) ) THEN
326.NOT.
ELSE IF( LSAME( NORMIN, 'y.AND..NOT.
' )
327 $ LSAME( NORMIN, 'n
' ) ) THEN
329.LT.
ELSE IF( N0 ) THEN
333 CALL BLACS_GRIDINFO( CONTXT, NPROW, NPCOL, MYROW, MYCOL )
336 CALL PXERBLA( CONTXT, 'pclattrs', -INFO )
347 SMLNUM = PSLAMCH( CONTXT, 'safe minimum
' )
348 BIGNUM = ONE / SMLNUM
349 CALL PSLABAD( CONTXT, SMLNUM, BIGNUM )
350 SMLNUM = SMLNUM / PSLAMCH( CONTXT, 'precision
' )
351 BIGNUM = ONE / SMLNUM
355 IF( LSAME( NORMIN, 'n
' ) ) THEN
365 CALL PSCASUM( J-1, CNORM( J ), A, IA, JA+J-1, DESCA, 1 )
372 CALL PSCASUM( N-J, CNORM( J ), A, IA+J, JA+J-1, DESCA,
377 CALL SGSUM2D( CONTXT, 'row
', ' ', N, 1, CNORM, 1, -1, -1 )
383 IMAX = ISAMAX( N, CNORM, 1 )
385.LE.
IF( TMAXBIGNUM*HALF ) THEN
388 TSCAL = HALF / ( SMLNUM*TMAX )
389 CALL SSCAL( N, TSCAL, CNORM, 1 )
396 CALL PCAMAX( N, ZDUM, IMAX, X, IX, JX, DESCX, 1 )
397 XMAX( 1 ) = CABS2( ZDUM )
398 CALL SGSUM2D( CONTXT, 'row
', ' ', 1, 1, XMAX, 1, -1, -1 )
415.NE.
IF( TSCALONE ) THEN
427 GROW = HALF / MAX( XBND, SMLNUM )
429 DO 30 J = JFIRST, JLAST, JINC
437 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL, MYROW,
438 $ MYCOL, IROW, ICOL, ITMP1, ITMP2 )
439.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
440 TJJS = A( ( ICOL-1 )*LDA+IROW )
441 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1 )
443 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
448.GE.
IF( TJJSMLNUM ) THEN
452 XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
460.GE.
IF( TJJ+CNORM( J )SMLNUM ) THEN
464 GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
479 GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
480 DO 40 J = JFIRST, JLAST, JINC
489 GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
508.NE.
IF( TSCALONE ) THEN
520 GROW = HALF / MAX( XBND, SMLNUM )
522 DO 60 J = JFIRST, JLAST, JINC
531 XJ = ONE + CNORM( J )
532 GROW = MIN( GROW, XBND / XJ )
535 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL, MYROW,
536 $ MYCOL, IROW, ICOL, ITMP1, ITMP2 )
537.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
538 TJJS = A( ( ICOL-1 )*LDA+IROW )
539 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1 )
541 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
546.GE.
IF( TJJSMLNUM ) THEN
551 $ XBND = XBND*( TJJ / XJ )
559 GROW = MIN( GROW, XBND )
566 GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
567 DO 70 J = JFIRST, JLAST, JINC
576 XJ = ONE + CNORM( J )
583.GT.
IF( ( GROW*TSCAL )SMLNUM ) THEN
588 CALL PCTRSV( UPLO, TRANS, DIAG, N, A, IA, JA, DESCA, X, IX, JX,
594.GT.
IF( XMAX( 1 )BIGNUM*HALF ) THEN
599 SCALE = ( BIGNUM*HALF ) / XMAX( 1 )
600 CALL PCSSCAL( N, SCALE, X, IX, JX, DESCX, 1 )
603 XMAX( 1 ) = XMAX( 1 )*TWO
610 DO 100 J = JFIRST, JLAST, JINC
615 CALL INFOG2L( IX+J-1, JX, DESCX, NPROW, NPCOL, MYROW,
616 $ MYCOL, IROWX, ICOLX, ITMP1X, ITMP2X )
617.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) ) THEN
619 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1 )
621 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, XJTMP, 1,
627 CALL INFOG2L( IA+J-1, JA+J-1, DESCA, NPROW, NPCOL,
628 $ MYROW, MYCOL, IROW, ICOL, ITMP1, ITMP2 )
629.EQ..AND..EQ.
IF( ( MYROWITMP1 ) ( MYCOLITMP2 ) ) THEN
630 TJJS = A( ( ICOL-1 )*LDA+IROW )*TSCAL
631 CALL CGEBS2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1 )
633 CALL CGEBR2D( CONTXT, 'all
', ' ', 1, 1, TJJS, 1,
642.GT.
IF( TJJSMLNUM ) THEN
646.LT.
IF( TJJONE ) THEN
647.GT.
IF( XJTJJ*BIGNUM ) THEN
652 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
655 XMAX( 1 ) = XMAX( 1 )*REC
660 XJTMP = CLADIV( XJTMP, TJJS )
662.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
666.GT.
ELSE IF( TJJZERO ) THEN
670.GT.
IF( XJTJJ*BIGNUM ) THEN
675 REC = ( TJJ*BIGNUM ) / XJ
676.GT.
IF( CNORM( J )ONE ) THEN
681 REC = REC / CNORM( J )
683 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
686 XMAX( 1 ) = XMAX( 1 )*REC
690 XJTMP = CLADIV( XJTMP, TJJS )
692.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
701 CALL PCLASET( ' ', N, 1, CZERO, CZERO, X, IX, JX,
703.EQ..AND..EQ.
IF( ( MYROWITMP1X ) ( MYCOLITMP2X ) )
719.GT.
IF( CNORM( J )( BIGNUM-XMAX( 1 ) )*REC ) THEN
724 CALL PCSSCAL( N, REC, X, IX, JX, DESCX, 1 )
728.GT.
ELSE IF( XJ*CNORM( J )( BIGNUM-XMAX( 1 ) ) ) THEN
732 CALL PCSSCAL( N, HALF, X, IX, JX, DESCX, 1 )
744 CALL PCAXPY( J-1, ZDUM, A, IA, JA+J-1, DESCA, 1, X,
746 CALL PCAMAX( J-1, ZDUM, IMAX, X, IX, JX, DESCX, 1 )
747 XMAX( 1 ) = CABS1( ZDUM )
748 CALL SGSUM2D( CONTXT, 'row
', ' ', 1, 1, xmax, 1,
758 CALL pcaxpy( n-j, zdum, a, ia+j, ja+j-1, desca, 1,
759 $ x, ix+j, jx, descx, 1 )
760 CALL pcamax( n-j, zdum, i, x, ix+j, jx, descx, 1 )
761 xmax( 1 ) = cabs1( zdum )
762 CALL sgsum2d( contxt,
'Row'' ', 1, 1, xmax, 1,
768 ELSE IF( lsame( trans,
'T' ) )
THEN
772 DO 120 j = jfirst, jlast, jinc
778 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
779 $ mycol, irowx, icolx, itmp1x, itmp2x )
780 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
782 CALL cgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
784 CALL cgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
788 uscal =
cmplx( tscal )
789 rec = one /
max( xmax( 1 ), one )
790 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
797 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
798 $ myrow, mycol, irow, icol, itmp1,
800 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
802 tjjs = a( ( icol-1 )*lda+irow )*tscal
803 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
806 CALL cgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
813 IF( tjj.GT.one )
THEN
817 rec =
min( one, rec*tjj )
818 uscal = cladiv( uscal, tjjs )
820 IF( rec.LT.one )
THEN
821 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
829 IF( uscal.EQ.cone )
THEN
836 $ x, ix, jx, descx, 1 )
837 ELSE IF( j.LT.n )
THEN
838 CALL pcdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
839 $ x, ix+j, jx, descx, 1 )
841 IF( mycol.EQ.itmp2x )
THEN
842 CALL cgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
844 CALL cgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
856 zdum = conjg( uscal )
857 CALL pcscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
858 CALL pcdotu( j-1, csumj, a, ia, ja+j-1, desca, 1,
859 $ x, ix, jx, descx, 1 )
861 CALL pcscal( j-1, zdum, a, ia, ja+j-
862 ELSE IF( j.LT.n )
THEN
866 zdum = conjg( uscal )
868 CALL pcdotu( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
869 $ x, ix+j, jx, descx, 1 )
870 zdum = cladiv( zdum, uscal )
871 CALL pcscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
873 IF( mycol.EQ.itmp2x )
THEN
874 CALL cgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
876 CALL cgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
881 IF( uscal.EQ.
cmplx( tscal ) )
THEN
888 xjtmp = xjtmp - csumj
894 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
895 $ myrow, mycol, irow, icol, itmp1,
897 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
899 tjjs = a( ( icol-1 )*lda+irow )*tscal
900 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
903 CALL cgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
915 IF( tjj.GT.smlnum )
THEN
919 IF( tjj.LT.one )
THEN
920 IF( xj.GT.tjj*bignum )
THEN
925 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
928 xmax( 1 ) = xmax( 1 )*rec
932 xjtmp = cladiv( xjtmp, tjjs )
933 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
937 ELSE IF( tjj.GT.zero )
THEN
941 IF( xj.GT.tjj*bignum )
THEN
945 rec = ( tjj*bignum ) / xj
946 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
949 xmax( 1 ) = xmax( 1 )*rec
952 xjtmp = cladiv( xjtmp, tjjs )
953 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
962 CALL pclaset(
' ', n, 1, czero, czero, x, ix, jx,
964 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
979 xjtmp = cladiv( xjtmp, tjjs ) - csumj
980 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
985 xmax( 1 ) =
max( xmax( 1 ), cabs1( xjtmp
992 DO 140 j = jfirst, jlast, jinc
997 CALL infog2l( ix+j-1, jx, descx, nprow, npcol, myrow,
998 $ mycol, irowx, icolx, itmp1x, itmp2x )
999 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
THEN
1001 CALL cgebs2d( contxt,
'All',
' ', 1, 1, xjtmp, 1 )
1003 CALL cgebr2d( contxt,
'All',
' ', 1, 1, xjtmp, 1,
1008 rec = one /
max( xmax( 1 ), one )
1009 IF( cnorm( j ).GT.( bignum-xj )*rec )
THEN
1016 CALL infog2l( ia+j-1, ja+j-1, desca, nprow, npcol,
1017 $ myrow, mycol, irow, icol, itmp1,
1019 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1021 tjjs = conjg( a( ( icol-1 )*lda+irow ) )*tscal
1022 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1025 CALL cgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
1032 IF( tjj.GT.one )
THEN
1036 rec =
min( one, rec*tjj )
1037 uscal = cladiv( uscal, tjjs )
1039 IF( rec.LT.one )
THEN
1040 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
1043 xmax( 1 ) = xmax( 1 )*rec
1048 IF( uscal.EQ.cone )
THEN
1054 CALL pcdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1055 $ x, ix, jx, descx, 1 )
1056 ELSE IF( j.LT.n )
THEN
1057 CALL pcdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1058 $ x, ix+j, jx, descx, 1 )
1060 IF( mycol.EQ.itmp2x )
THEN
1061 CALL cgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1063 CALL cgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1076 zdum = conjg( uscal )
1077 CALL pcscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1078 CALL pcdotc( j-1, csumj, a, ia, ja+j-1, desca, 1,
1079 $ x, ix, jx, descx, 1 )
1080 zdum = cladiv( cone, zdum )
1081 CALL pcscal( j-1, zdum, a, ia, ja+j-1, desca, 1 )
1082 ELSE IF( j.LT.n )
THEN
1087 zdum = conjg( uscal )
1088 CALL pcscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1089 CALL pcdotc( n-j, csumj, a, ia+j, ja+j-1, desca, 1,
1090 $ x, ix+j, jx, descx, 1 )
1091 zdum = cladiv( cone, zdum )
1092 CALL pcscal( n-j, zdum, a, ia+j, ja+j-1, desca, 1 )
1094 IF( mycol.EQ.itmp2x )
THEN
1095 CALL cgebs2d( contxt,
'Row',
' ', 1, 1, csumj, 1 )
1097 CALL cgebr2d( contxt,
'Row',
' ', 1, 1, csumj, 1,
1102 IF( uscal.EQ.
cmplx( tscal ) )
THEN
1109 xjtmp = xjtmp - csumj
1116 $ myrow, mycol, irow, icol, itmp1,
1118 IF( ( myrow.EQ.itmp1 ) .AND. ( mycol.EQ.itmp2 ) )
1120 tjjs = conjg( a( ( icol-1 )*lda+irow ) )*tscal
1121 CALL cgebs2d( contxt,
'All',
' ', 1, 1, tjjs,
1124 CALL cgebr2d( contxt,
'All',
' ', 1, 1, tjjs, 1,
1136 IF( tjj.GT.smlnum )
THEN
1140 IF( tjj.LT.one )
THEN
1141 IF( xj.GT.tjj*bignum )
THEN
1146 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
1153 xjtmp = cladiv( xjtmp, tjjs )
1154 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1156 ELSE IF( tjj.GT.zero )
THEN
1160 IF( xj.GT.tjj*bignum
THEN
1165 CALL pcsscal( n, rec, x, ix, jx, descx, 1 )
1172 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1173 $ x( irowx ) = xjtmp
1181 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1195 IF( ( myrow.EQ.itmp1x ) .AND. ( mycol.EQ.itmp2x ) )
1198 xmax( 1 ) =
max( xmax( 1 ), cabs1
1201 scale = scale / tscal
1206 IF( tscal.NE.one )
THEN
1207 CALL sscal( n, one / tscal, cnorm, 1 )