1 SUBROUTINE psgerfs( TRANS, N, NRHS, A, IA, JA, DESCA, AF, IAF,
2 $ JAF, DESCAF, IPIV, B, IB, JB, DESCB, X, IX,
3 $ JX, DESCX, FERR, BERR, WORK, LWORK, IWORK,
13 INTEGER IA, IAF, IB, IX, INFO, JA, JAF, JB, JX,
14 $ LIWORK, LWORK, N, NRHS
17 INTEGER DESCA( * ), DESCAF( * ), DESCB( * ),
18 $ DESCX( * ),IPIV( * ), IWORK( * )
19 REAL A( * ), AF( * ), B( * ), BERR( * ), FERR( * ),
261 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
262 $ LLD_, , M_, NB_, N_, RSRC_
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 )
267 PARAMETER ( ITMAX = 5 )
269 parameter( zero = 0.0e+0, one = 1.0e+0 )
271 parameter( two = 2.0e+0, three = 3.0e+0 )
274 LOGICAL LQUERY, NOTRAN
276 INTEGER COUNT, IACOL, IAFCOL, IAFROW, IAROW, IXBCOL,
277 $ ixbrow, ixcol, ixrow, icoffa, icoffaf, icoffb,
278 $ icoffx, ictxt, icurcol, idum, ii, iixb, iiw,
279 $ ioffxb, ipb, ipr, ipv, iroffa, iroffaf, iroffb,
280 $ iroffx, iw, j, jbrhs, jj, jjfbe, jjxb, jn, jw,
281 $ k, kase, ldxb, liwmin, lwmin, mycol, myrhs,
282 $ myrow, np, np0, npcol, npmod, nprow, nz
283 REAL EPS, EST, LSTRES, S, SAFE1, SAFE2, SAFMIN
286 INTEGER DESCW( DLEN_ ), IDUM1( 5 ), IDUM2( 5 )
290 INTEGER ICEIL, INDXG2P, NUMROC
292 EXTERNAL iceil, indxg2p, lsame, numroc, pslamch
301 INTRINSIC abs, ichar,
max,
min, mod, real
307 ictxt = desca( ctxt_ )
312 notran = lsame( trans, 'n
' )
315.EQ.
IF( NPROW-1 ) THEN
318 CALL CHK1MAT( N, 2, N, 2, IA, JA, DESCA, 7, INFO )
319 CALL CHK1MAT( N, 2, N, 2, IAF, JAF, DESCAF, 11, INFO )
320 CALL CHK1MAT( N, 2, NRHS, 3, IB, JB, DESCB, 16, INFO )
321 CALL CHK1MAT( N, 2, NRHS, 3, IX, JX, DESCX, 20, INFO )
323 IROFFA = MOD( IA-1, DESCA( MB_ ) )
324 ICOFFA = MOD( JA-1, DESCA( NB_ ) )
325 IROFFAF = MOD( IAF-1, DESCAF( MB_ ) )
326 ICOFFAF = MOD( JAF-1, DESCAF( NB_ ) )
327 IROFFB = MOD( IB-1, DESCB( MB_ ) )
328 ICOFFB = MOD( JB-1, DESCB( NB_ ) )
329 IROFFX = MOD( IX-1, DESCX( MB_ ) )
330 ICOFFX = MOD( JX-1, DESCX( NB_ ) )
331 IAROW = INDXG2P( IA, DESCA( MB_ ), MYROW, DESCA( RSRC_ ),
333 IAFCOL = INDXG2P( JAF, DESCAF( NB_ ), MYCOL,
334 $ DESCAF( CSRC_ ), NPCOL )
335 IAFROW = INDXG2P( IAF, DESCAF( MB_ ), MYROW,
336 $ DESCAF( RSRC_ ), NPROW )
337 IACOL = INDXG2P( JA, DESCA( NB_ ), MYCOL, DESCA( CSRC_ ),
339 CALL INFOG2L( IB, JB, DESCB, NPROW, NPCOL, MYROW, MYCOL,
340 $ IIXB, JJXB, IXBROW, IXBCOL )
341 IXROW = INDXG2P( IX, DESCX( MB_ ), MYROW, DESCX( RSRC_ ),
343 IXCOL = INDXG2P( JX, DESCX( NB_ ), MYCOL, DESCX( CSRC_ ),
345 NPMOD = NUMROC( N+IROFFA, DESCA( MB_ ), MYROW, IAROW,
349 WORK( 1 ) = REAL( LWMIN )
351.EQ..OR..EQ.
LQUERY = ( LWORK-1 LIWORK-1 )
353.NOT..AND..NOT.
IF( ( NOTRAN ) ( LSAME( TRANS, 't.AND.
' ) )
354.NOT.
$ ( LSAME( TRANS, 'c
' ) ) ) THEN
356.LT.
ELSE IF( N0 ) THEN
358.LT.
ELSE IF( NRHS0 ) THEN
360.NE.
ELSE IF( IROFFA0 ) THEN
362.NE.
ELSE IF( ICOFFA0 ) THEN
364.NE.
ELSE IF( DESCA( MB_ )DESCA( NB_ ) ) THEN
365 INFO = -( 700 + NB_ )
366.NE.
ELSE IF( DESCA( MB_ )DESCAF( MB_ ) ) THEN
367 INFO = -( 1100 + MB_ )
368.NE..OR..NE.
ELSE IF( IROFFAF0 IAROWIAFROW ) THEN
370.NE.
ELSE IF( DESCA( NB_ )DESCAF( NB_ ) ) THEN
371 INFO = -( 1100 + NB_ )
372.NE..OR..NE.
ELSE IF( ICOFFAF0 IACOLIAFCOL ) THEN
374.NE.
ELSE IF( ICTXTDESCAF( CTXT_ ) ) THEN
375 INFO = -( 1100 + CTXT_ )
376.NE..OR..NE.
ELSE IF( IROFFAIROFFB IAROWIXBROW ) THEN
378.NE.
ELSE IF( DESCA( MB_ )DESCB( MB_ ) ) THEN
379 INFO = -( 1600 + MB_ )
380.NE.
ELSE IF( ICTXTDESCB( CTXT_ ) ) THEN
381 INFO = -( 1600 + CTXT_ )
382.NE.
ELSE IF( DESCB( MB_ )DESCX( MB_ ) ) THEN
383 INFO = -( 2000 + MB_ )
384.NE..OR..NE.
ELSE IF( IROFFX0 IXBROWIXROW ) THEN
386.NE.
ELSE IF( DESCB( NB_ )DESCX( NB_ ) ) THEN
387 INFO = -( 2000 + NB_ )
388.NE..OR..NE.
ELSE IF( ICOFFBICOFFX IXBCOLIXCOL ) THEN
390.NE.
ELSE IF( ICTXTDESCX( CTXT_ ) ) THEN
391 INFO = -( 2000 + CTXT_ )
392.LT..AND..NOT.
ELSE IF( LWORKLWMIN LQUERY ) THEN
394.LT..AND..NOT.
ELSE IF( LIWORKLIWMIN LQUERY ) THEN
400 IDUM1( 1 ) = ICHAR( 'n
' )
401 ELSE IF( LSAME( TRANS, 't
' ) ) THEN
402 IDUM1( 1 ) = ICHAR( 't
' )
404 IDUM1( 1 ) = ICHAR( 'c
' )
411.EQ.
IF( LWORK-1 ) THEN
417.EQ.
IF( LIWORK-1 ) THEN
423 CALL PCHK2MAT( N, 2, N, 2, IA, JA, DESCA, 7, N, 2, N, 2, IAF,
424 $ JAF, DESCAF, 11, 5, IDUM1, IDUM2, INFO )
425 CALL PCHK2MAT( N, 2, NRHS, 3, IB, JB, DESCB, 16, N, 2, NRHS, 3,
426 $ IX, JX, DESCX, 20, 5, IDUM1, IDUM2, INFO )
429 CALL PXERBLA( ICTXT, 'psgerfs', -INFO )
431 ELSE IF( LQUERY ) THEN
436 MYRHS = NUMROC( JB+NRHS-1, DESCB( NB_ ), MYCOL, DESCB( CSRC_ ),
441.LE..OR..EQ.
IF( N1 NRHS0 ) THEN
442 DO 10 JJ = JJFBE, MYRHS
455 NP0 = NUMROC( N+IROFFB, DESCB( MB_ ), MYROW, IXBROW, NPROW )
456 CALL DESCSET( DESCW, N+IROFFB, 1, DESCA( MB_ ), 1, IXBROW, IXBCOL,
457 $ ICTXT, MAX( 1, NP0 ) )
461.EQ.
IF( MYROWIXBROW ) THEN
471 IOFFXB = ( JJXB-1 )*LDXB
476 EPS = PSLAMCH( ICTXT, 'epsilon
' )
477 SAFMIN = PSLAMCH( ICTXT, 'safe minimum
' )
480 JN = MIN( ICEIL( JB, DESCB( NB_ ) ) * DESCB( NB_ ), JB+NRHS-1 )
485 DO 100 K = 0, JBRHS-1
497 CALL PSCOPY( N, B, IB, JB+K, DESCB, 1, WORK( IPR ), IW, JW,
499 CALL PSGEMV( TRANS, N, N, -ONE, A, IA, JA, DESCA, X, IX,
500 $ JX+K, DESCX, 1, ONE, WORK( IPR ), IW, JW,
513.EQ.
IF( MYCOLIXBCOL ) THEN
515 DO 30 II = IIXB, IIXB + NP - 1
516 WORK( IIW+II-IIXB ) = ABS( B( II+IOFFXB ) )
521 CALL PSAGEMV( TRANS, N, N, ONE, A, IA, JA, DESCA, X, IX, JX+K,
522 $ DESCX, 1, ONE, WORK( IPB ), IW, JW, DESCW, 1 )
525.EQ.
IF( MYCOLIXBCOL ) THEN
527 DO 40 II = IIW-1, IIW+NP-2
528.GT.
IF( WORK( IPB+II )SAFE2 ) THEN
529 S = MAX( S, ABS( WORK( IPR+II ) ) /
532 S = MAX( S, ( ABS( WORK( IPR+II ) )+SAFE1 ) /
533 $ ( WORK( IPB+II )+SAFE1 ) )
539 CALL SGAMX2D( ICTXT, 'all
', ' ', 1, 1, S, 1, IDUM, IDUM, 1,
541.EQ.
IF( MYCOLIXBCOL )
551.GT..AND..LE..AND..LE.
IF( SEPS TWO*SLSTRES COUNTITMAX ) THEN
555 CALL PSGETRS( TRANS, N, 1, AF, IAF, JAF, DESCAF, IPIV,
556 $ WORK( IPR ), IW, JW, DESCW, INFO )
557 CALL PSAXPY( N, ONE, WORK( IPR ), IW, JW, DESCW, 1, X, IX,
590.EQ.
IF( MYCOLIXBCOL ) THEN
592 DO 50 II = IIW-1, IIW+NP-2
593.GT.
IF( WORK( IPB+II )SAFE2 ) THEN
594 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
595 $ NZ*EPS*WORK( IPB+II )
597 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
598 $ NZ*EPS*WORK( IPB+II ) + SAFE1
606.EQ.
IF( MYCOLIXBCOL ) THEN
607 CALL SGEBS2D( ICTXT, 'rowwise
', ' ', NP, 1, WORK( IPR ),
610 CALL SGEBR2D( ICTXT, 'rowwise
', ' ', NP, 1, WORK( IPR ),
611 $ DESCW( LLD_ ), MYROW, IXBCOL )
613 DESCW( CSRC_ ) = MYCOL
614 CALL PSLACON( N, WORK( IPV ), IW, JW, DESCW, WORK( IPR ),
615 $ IW, JW, DESCW, IWORK, EST, KASE )
616 DESCW( CSRC_ ) = IXBCOL
623 CALL PSGETRS( TRANST, N, 1, AF, IAF, JAF, DESCAF,
624 $ IPIV, WORK( IPR ), IW, JW, DESCW, INFO )
626.EQ.
IF( MYCOLIXBCOL ) THEN
628 DO 70 II = IIW-1, IIW+NP-2
629 WORK( IPR+II ) = WORK( IPB+II )*WORK( IPR+II )
637.EQ.
IF( MYCOLIXBCOL ) THEN
639 DO 80 II = IIW-1, IIW+NP-2
640 WORK( IPR+II ) = WORK( IPB+II )*WORK( IPR+II )
645 CALL PSGETRS( TRANS, N, 1, AF, IAF, JAF, DESCAF, IPIV,
646 $ WORK( IPR ), IW, JW, DESCW, INFO )
654.EQ.
IF( MYCOLIXBCOL ) THEN
656 DO 90 II = IIXB, IIXB+NP-1
657 LSTRES = MAX( LSTRES, ABS( X( IOFFXB+II ) ) )
660 CALL SGAMX2D( ICTXT, 'column
', ' ', 1, 1, LSTRES, 1, IDUM,
661 $ IDUM, 1, -1, MYCOL )
663 $ FERR( JJFBE ) = EST / LSTRES
667 IOFFXB = IOFFXB + LDXB
673 ICURCOL = MOD( IXBCOL+1, NPCOL )
677 DO 200 J = JN+1, JB+NRHS-1, DESCB( NB_ )
678 JBRHS = MIN( JB+NRHS-J, DESCB( NB_ ) )
679 DESCW( CSRC_ ) = ICURCOL
681 DO 190 K = 0, JBRHS-1
693 CALL PSCOPY( N, B, IB, J+K, DESCB, 1, WORK( IPR ), IW, JW,
695 CALL PSGEMV( TRANS, N, N, -ONE, A, IA, JA, DESCA, X,
696 $ IX, J+K, DESCX, 1, ONE, WORK( IPR ), IW, JW,
710.EQ.
IF( MYCOLICURCOL ) THEN
712 DO 120 II = IIXB, IIXB+NP-1
713 WORK( IIW+II-IIXB ) = ABS( B( II+IOFFXB ) )
718 CALL PSAGEMV( TRANS, N, N, ONE, A, IA, JA, DESCA, X, IX,
719 $ J+K, DESCX, 1, ONE, WORK( IPB ), IW, JW,
723.EQ.
IF( MYCOLICURCOL ) THEN
725 DO 130 II = IIW-1, IIW+NP-2
726.GT.
IF( WORK( IPB+II )SAFE2 ) THEN
727 S = MAX( S, ABS( WORK( IPR+II ) ) /
730 S = MAX( S, ( ABS( WORK( IPR+II ) )+SAFE1 ) /
731 $ ( WORK( IPB+II )+SAFE1 ) )
737 CALL SGAMX2D( ICTXT, 'all
', ' ', 1, 1, S, 1, IDUM, IDUM, 1,
739.EQ.
IF( MYCOLICURCOL )
749.GT..AND..LE..AND.
IF( SEPS TWO*SLSTRES
750.LE.
$ COUNTITMAX ) THEN
754 CALL PSGETRS( TRANS, N, 1, AF, IAF, JAF, DESCAF, IPIV,
755 $ WORK( IPR ), IW, JW, DESCW, INFO )
756 CALL PSAXPY( N, ONE, WORK( IPR ), IW, JW, DESCW, 1, X,
757 $ IX, J+K, DESCX, 1 )
789.EQ.
IF( MYCOLICURCOL ) THEN
791 DO 140 II = IIW-1, IIW+NP-2
792.GT.
IF( WORK( IPB+II )SAFE2 ) THEN
793 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
794 $ NZ*EPS*WORK( IPB+II )
796 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
797 $ NZ*EPS*WORK( IPB+II ) + SAFE1
805.EQ.
IF( MYCOLICURCOL ) THEN
806 CALL SGEBS2D( ICTXT, 'rowwise
', ' ', NP, 1, WORK( IPR ),
809 CALL SGEBR2D( ICTXT, 'rowwise
', ' ', NP, 1, WORK( IPR ),
810 $ DESCW( LLD_ ), MYROW, ICURCOL )
812 DESCW( CSRC_ ) = MYCOL
813 CALL PSLACON( N, WORK( IPV ), IW, JW, DESCW, WORK( IPR ),
814 $ IW, JW, DESCW, IWORK, EST, KASE )
815 DESCW( CSRC_ ) = ICURCOL
822 CALL PSGETRS( TRANST, N, 1, AF, IAF, JAF, DESCAF,
823 $ IPIV, WORK( IPR ), IW, JW, DESCW, INFO )
825.EQ.
IF( MYCOLICURCOL ) THEN
827 DO 160 II = IIW-1, IIW+NP-2
828 WORK( IPR+II ) = WORK( IPB+II )*
837.EQ.
IF( MYCOLICURCOL ) THEN
839 DO 170 II = IIW-1, IIW+NP-2
840 WORK( IPR+II ) = WORK( IPB+II )*
846 CALL PSGETRS( TRANS, N, 1, AF, IAF, JAF, DESCAF,
847 $ IPIV, WORK( IPR ), IW, JW, DESCW,
856.EQ.
IF( MYCOLICURCOL ) THEN
858 DO 180 II = IIXB, IIXB+NP-1
859 LSTRES = MAX( LSTRES, ABS( X( IOFFXB+II ) ) )
862 CALL SGAMX2D( ICTXT, 'column
', ' ', 1, 1, LSTRES,
863 $ 1, IDUM, IDUM, 1, -1, MYCOL )
865 $ FERR( JJFBE ) = EST / LSTRES
869 IOFFXB = IOFFXB + LDXB
875 ICURCOL = MOD( ICURCOL+1, NPCOL )
879 WORK( 1 ) = REAL( LWMIN )
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine psgerfs(trans, n, nrhs, a, ia, ja, desca, af, iaf, jaf, descaf, ipiv, b, ib, jb, descb, x, ix, jx, descx, ferr, berr, work, lwork, iwork, liwork, info)