1 SUBROUTINE psposvx( FACT, UPLO, N, NRHS, A, IA, JA, DESCA, AF,
2 $ IAF, JAF, DESCAF, EQUED, SR, SC, B, IB, JB,
3 $ DESCB, X, IX, JX, DESCX, RCOND, FERR, BERR,
4 $ WORK, LWORK, IWORK, LIWORK, INFO )
12 CHARACTER EQUED, FACT, UPLO
13 INTEGER IA, IAF, IB, INFO, IX, JA, JAF, JB, JX, LIWORK,
18 INTEGER DESCA( * ), DESCAF( * ), DESCB( * ),
19 $ DESCX( * ), IWORK( * )
21 $ b( * ), berr( * ), ferr( * ),
22 $ sc( * ), sr( * ), work( * ), x( * )
353 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
354 $ LLD_, MB_, M_, NB_, N_, RSRC_
355 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
356 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
357 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
359 PARAMETER ( ONE = 1.0e+0, zero = 0.0e+0 )
362 LOGICAL EQUIL, LQUERY, NOFACT, RCEQU
363 INTEGER I, IACOL, IAROW, IAFROW, IBROW, IBCOL, ICOFF,
364 $ ICOFFA, ICTXT, IDUMM, IIA, IIB, IIX, INFEQU,
365 $ iroff, iroffa, iroffaf, iroffb, iroffx, ixcol,
366 $ ixrow, j, jja, jjb, jjx, ldb, ldx, liwmin,
367 $ lwmin, mycol, myrow, np, npcol, nprow, nrhsq,
369 REAL AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
372 INTEGER IDUM1( 5 ), IDUM2( 5 )
383 INTEGER INDXG2P, NUMROC
384 REAL PSLANSY, PSLAMCH
385 EXTERNAL indxg2p, lsame, numroc, pslansy, pslamch
388 INTRINSIC ichar,
max,
min, mod
394 ictxt = desca( ctxt_ )
395 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
400 IF( nprow.EQ.-1 )
THEN
403 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 8, info )
404 IF( lsame( fact,
'F' ) )
405 $
CALL chk1mat( n, 3, n, 3, iaf, jaf, descaf, 12, info )
406 CALL chk1mat( n, 3, nrhs, 4, ib, jb, descb, 20, info )
408 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
410 iafrow = indxg2p( iaf, descaf( mb_ ), myrow,
411 $ descaf( rsrc_ ), nprow )
412 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
414 ixrow = indxg2p( ix, descx( mb_ ), myrow, descx( rsrc_ ),
416 iroffa = mod( ia-1, desca( mb_ ) )
417 iroffaf = mod( iaf-1, descaf( mb_ ) )
418 icoffa = mod( ja-1, desca( nb_ ) )
419 iroffb = mod( ib-1, descb( mb_ ) )
420 iroffx = mod( ix-1, descx( mb_ ) )
421 CALL infog2l( ia, ja, desca, nprow, npcol, myrow,
422 $ mycol, iia, jja, iarow, iacol )
423 np = numroc( n+iroffa, desca( mb_ ), myrow, iarow, nprow )
426 nq = numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
429 lwmin = 3*desca( lld_ )
431 nofact = lsame( fact,
'N' )
432 equil = lsame( fact,
'E' )
433 IF( nofact .OR. equil )
THEN
437 rcequ = lsame( equed,
'Y' )
438 smlnum = pslamch( ictxt,
'Safe minimum' )
439 bignum = one / smlnum
441 IF( .NOT.nofact .AND. .NOT.equil .AND.
442 $ .NOT.lsame( fact,
'F' ) )
THEN
444 ELSE IF( .NOT.lsame( uplo,
'U' ) .AND.
445 $ .NOT.lsame( uplo,
'L' ) )
THEN
447 ELSE IF( iroffa.NE.0 )
THEN
449 ELSE IF( icoffa.NE.0 .OR. iroffa.NE.icoffa )
THEN
451 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
453 ELSE IF( iafrow.NE.iarow )
THEN
455 ELSE IF( iroffaf.NE.0 )
THEN
457 ELSE IF( ictxt.NE.descaf( ctxt_ ) )
THEN
459 ELSE IF( lsame( fact,
'F' ) .AND. .NOT.
460 $ ( rcequ .OR. lsame( equed,
'N' ) ) )
THEN
467 DO 10 j = iia, iia + np - 1
468 smin =
min( smin, sr( j ) )
469 smax =
max( smax, sr( j ) )
471 CALL sgamn2d( ictxt,
'Columnwise',
' ', 1, 1, smin,
472 $ 1, idumm, idumm, -1, -1, mycol )
473 CALL sgamx2d( ictxt,
'Columnwise',
' ', 1, 1, smax,
474 $ 1, idumm, idumm, -1, -1, mycol )
475 IF( smin.LE.zero )
THEN
477 ELSE IF( n.GT.0 )
THEN
478 scond =
max( smin, smlnum ) /
min( smax, bignum )
486 work( 1 ) = real( lwmin )
488 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
490 IF( ibrow.NE.iarow )
THEN
492 ELSE IF( ixrow.NE.ibrow )
THEN
494 ELSE IF( descb( mb_ ).NE.desca( nb_ ) )
THEN
496 ELSE IF( ictxt.NE.descb( ctxt_ ) )
THEN
498 ELSE IF( ictxt.NE.descx( ctxt_ ) )
THEN
500 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
502 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
505 idum1( 1 ) = ichar( fact )
507 idum1( 2 ) = ichar( uplo )
509 IF( lsame( fact,
'F' ) )
THEN
510 idum1( 3 ) = ichar( equed )
512 IF( lwork.EQ.-1 )
THEN
518 IF( liwork.EQ.-1 )
THEN
524 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 8, n, 3, nrhs,
525 $ 4, ib, jb, descb, 19, 5, idum1, idum2,
528 IF( lwork.EQ.-1 )
THEN
534 IF( liwork.EQ.-1 )
THEN
540 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 8, n, 3, nrhs,
541 $ 4, ib, jb, descb, 19, 4, idum1, idum2,
548 CALL pxerbla( ictxt,
'PSPOSVX', -info )
550 ELSE IF( lquery )
THEN
558 CALL pspoequ( n, a, ia, ja, desca, sr, sc, scond, amax,
561 IF( infequ.EQ.0 )
THEN
565 CALL pslaqsy( uplo, n, a, ia, ja, desca, sr, sc, scond,
567 rcequ = lsame( equed,
'Y' )
573 CALL infog2l( ib, jb, descb, nprow, npcol, myrow, mycol, iib,
574 $ jjb, ibrow, ibcol )
576 iroff = mod( ib-1, descb( mb_ ) )
577 icoff = mod( jb-1, descb( nb_ ) )
578 np = numroc( n+iroff, descb( mb_ ), myrow, ibrow, nprow )
579 nrhsq = numroc( nrhs+icoff, descb( nb_ ), mycol, ibcol, npcol )
580 IF( myrow.EQ.ibrow ) np = np-iroff
581 IF( mycol.EQ.ibcol ) nrhsq = nrhsq-icoff
584 DO 30 j = jjb, jjb+nrhsq-1
585 DO 20 i = iib, iib+np-1
586 b( i + ( j-1 )*ldb ) = sr( i )*b( i + ( j-1 )*ldb )
591 IF( nofact .OR. equil )
THEN
595 CALL pslacpy(
'Full', n, n, a, ia, ja, desca, af, iaf, jaf,
597 CALL pspotrf( uplo, n, af, iaf, jaf, descaf, info )
610 anorm = pslansy(
'1', uplo, n, a, ia, ja, desca, work )
614 CALL pspocon( uplo, n, af, iaf, jaf, descaf, anorm, rcond, work,
615 $ lwork, iwork, liwork, info )
619 IF( rcond.LT.pslamch( ictxt,
'Epsilon' ) )
THEN
626 CALL pslacpy(
'Full', n, nrhs, b, ib, jb, descb, x, ix, jx,
628 CALL pspotrs( uplo, n, nrhs, af, iaf, jaf, descaf, x, ix, jx,
634 CALL psporfs( uplo, n, nrhs, a, ia, ja, desca, af, iaf, jaf,
635 $ descaf, b, ib, jb, descb, x, ix, jx, descx, ferr,
636 $ berr, work, lwork, iwork, liwork, info )
641 CALL infog2l( ix, jx, descx, nprow, npcol, myrow, mycol, iix,
642 $ jjx, ixrow, ixcol )
644 iroff = mod( ix-1, descx( mb_ ) )
645 icoff = mod( jx-1, descx( nb_ ) )
646 np = numroc( n+iroff, descx( mb_ ), myrow, ixrow, nprow )
647 nrhsq = numroc( nrhs+icoff, descx( nb_ ), mycol, ixcol, npcol )
648 IF( myrow.EQ.ibrow ) np = np-iroff
649 IF( mycol.EQ.ibcol ) nrhsq = nrhsq-icoff
652 DO 50 j = jjx, jjx+nrhsq-1
653 DO 40 i = iix, iix+np-1
654 x( i + ( j-1 )*ldx ) = sr( i )*x( i + ( j-1 )*ldx )
657 DO 60 j = jjx, jjx+nrhsq-1
658 ferr( j ) = ferr( j ) / scond
662 work( 1 ) = real( lwmin )