3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          NORM
   11      INTEGER            IA, INFO, JA, LRWORK, LWORK, N
   12      REAL               ANORM, RCOND
   13
   14
   15      INTEGER            DESCA( * )
   16      REAL               RWORK( * )
   17      COMPLEX            A( * ), WORK( * )
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  177     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  178      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  179     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  180     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  181      REAL               ONE, ZERO
  182      parameter( one = 1.0e+0, zero = 0.0e+0 )
  183
  184
  185      LOGICAL            LQUERY, ONENRM
  186      CHARACTER          CBTOP, COLCTOP, NORMIN, ROWCTOP
  187      INTEGER            IACOL, IAROW, ICOFF, ICTXT, IIA, IPNL, IPNU,
  188     $                   IPV, IPW, IPX, IROFF, IV, IX, IXX, JJA, JV, JX,
  189     $                   KASE, KASE1, LRWMIN, LWMIN, MYCOL, MYROW, NP,
  190     $                   NPCOL, NPMOD, NPROW, NQ, NQMOD
  191      REAL               AINVNM, SCALE, SL, SMLNUM, SU
  192      COMPLEX            WMAX, ZDUM
  193
  194
  195      INTEGER            DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 3 ),
  196     $                   IDUM2( 3 )
  197
  198
  203
  204
  205      LOGICAL            LSAME
  206      INTEGER            ICEIL, INDXG2P, NUMROC
  207      REAL               PSLAMCH
  209
  210
  211      INTRINSIC          abs, aimag, ichar, 
max, mod, real
 
  212
  213
  214      REAL               CABS1
  215
  216
  217      cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
  218
  219
  220
  221
  222
  223      ictxt = desca( ctxt_ )
  224      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  225
  226
  227
  228      info = 0
  229      IF( nprow.EQ.-1 ) THEN
  230         info = -( 600 + ctxt_ )
  231      ELSE
  232         CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
 
  233         IF( info.EQ.0 ) THEN
  234            onenrm = norm.EQ.
'1' .OR. 
lsame( norm, 
'O' )
 
  235            iarow = 
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
 
  236     $                       nprow )
  237            iacol = 
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
 
  238     $                       npcol )
  239            npmod = 
numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
 
  240     $                      myrow, iarow, nprow )
  241            nqmod = 
numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
 
  242     $                      mycol, iacol, npcol )
  243            lwmin = 2*npmod +
  244     $              
max( 2, 
max( desca( nb_ )*
 
  245     $                   
max( 1, 
iceil( nprow-1, npcol ) ), nqmod +
 
  246     $                   desca( nb_ )*
  247     $                   
max( 1, 
iceil( npcol-1, nprow ) ) ) )
 
  248            work( 1 ) = real( lwmin )
  249            lrwmin = 
max( 1, 2*nqmod )
 
  250            rwork( 1 ) = real( lrwmin )
  251            lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
  252
  253            IF( .NOT.onenrm .AND. .NOT.
lsame( norm, 
'I' ) ) 
THEN 
  254               info = -1
  255            ELSE IF( anorm.LT.zero ) THEN
  256               info = -7
  257            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  258               info = -10
  259            ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
  260               info = -12
  261            END IF
  262         END IF
  263
  264         IF( onenrm ) THEN
  265            idum1( 1 ) = ichar( '1' )
  266         ELSE
  267            idum1( 1 ) = ichar( 'I' )
  268         END IF
  269         idum2( 1 ) = 1
  270         IF( lwork.EQ.-1 ) THEN
  271            idum1( 2 ) = -1
  272         ELSE
  273            idum1( 2 ) = 1
  274         END IF
  275         idum2( 2 ) = 10
  276         IF( lrwork.EQ.-1 ) THEN
  277            idum1( 3 ) = -1
  278         ELSE
  279            idum1( 3 ) = 1
  280         END IF
  281         idum2( 3 ) = 12
  282         CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 3, idum1, idum2,
 
  283     $                  info )
  284      END IF
  285
  286      IF( info.NE.0 ) THEN
  287         CALL pxerbla( ictxt, 
'PCGECON', -info )
 
  288         RETURN
  289      ELSE IF( lquery ) THEN
  290         RETURN
  291      END IF
  292
  293
  294
  295      rcond = zero
  296      IF( n.EQ.0 ) THEN
  297         rcond = one
  298         RETURN
  299      ELSE IF( anorm.EQ.zero ) THEN
  300         RETURN
  301      ELSE IF( n.EQ.1 ) THEN
  302         rcond = one
  303         RETURN
  304      END IF
  305
  306      CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
  307      CALL pb_topget( ictxt, 'Combine', 'Rowwise',    rowctop )
  308      CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
  309      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    '1-tree' )
  310
  311      smlnum = 
pslamch( ictxt, 
'Safe minimum' )
 
  312      iroff = mod( ia-1, desca( mb_ ) )
  313      icoff = mod( ja-1, desca( nb_ ) )
  314      CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
 
  315     $              iarow, iacol )
  316      np = 
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
 
  317      nq = 
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
 
  318      iv = iroff + 1
  319      ix = iv
  320      jv = icoff + 1
  321      jx = jv
  322
  323      ipx = 1
  324      ipv = ipx + np
  325      ipw = ipv + np
  326      ipnl = 1
  327      ipnu = ipnl + nq
  328
  329      CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  330     $              ictxt, 
max( 1, np ) )
 
  331      CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  332     $              ictxt, 
max( 1, np ) )
 
  333
  334
  335
  336      ainvnm = zero
  337      normin = 'N'
  338      IF( onenrm ) THEN
  339         kase1 = 1
  340      ELSE
  341         kase1 = 2
  342      END IF
  343      kase = 0
  344
  345   10 CONTINUE
  346      CALL pclacon( n, work( ipv ), iv, jv, descv, work( ipx ), ix, jx,
 
  347     $              descx, ainvnm, kase )
  348      IF( kase.NE.0 ) THEN
  349         IF( kase.EQ.kase1 ) THEN
  350
  351
  352
  353            descx( csrc_ ) = iacol
  354            CALL pclatrs( 
'Lower', 
'No transpose', 
'Unit', normin,
 
  355     $                    n, a, ia, ja, desca, work( ipx ), ix, jx,
  356     $                    descx, sl, rwork( ipnl ), work( ipw ) )
  357            descx( csrc_ ) = mycol
  358
  359
  360
  361            descx( csrc_ ) = iacol
  362            CALL pclatrs( 
'Upper', 
'No transpose', 
'Non-unit', normin,
 
  363     $                    n, a, ia, ja, desca, work( ipx ), ix, jx,
  364     $                    descx, su, rwork( ipnu ), work( ipw ) )
  365            descx( csrc_ ) = mycol
  366         ELSE
  367
  368
  369
  370            descx( csrc_ ) = iacol
  371            CALL pclatrs( 
'Upper', 
'Conjugate transpose', 
'Non-unit',
 
  372     $                    normin, n, a, ia, ja, desca, work( ipx ), ix,
  373     $                    jx, descx, su, rwork( ipnu ), work( ipw ) )
  374            descx( csrc_ ) = mycol
  375
  376
  377
  378            descx( csrc_ ) = iacol
  379            CALL pclatrs( 
'Lower', 
'Conjugate transpose', 
'Unit',
 
  380     $                    normin, n, a, ia, ja, desca, work( ipx ),
  381     $                    ix, jx, descx, sl, rwork( ipnl ),
  382     $                    work( ipw ) )
  383            descx( csrc_ ) = mycol
  384         END IF
  385
  386
  387
  388         scale = sl*su
  389         normin = 'Y'
  390         IF( scale.NE.one ) THEN
  391            CALL pcamax( n, wmax, ixx, work( ipx ), ix, jx, descx, 1 )
  392            IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
  393               CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', cbtop )
  394               IF( myrow.EQ.iarow ) THEN
  395                  CALL cgebs2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1 )
  396               ELSE
  397                  CALL cgebr2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1,
  398     $                          iarow, mycol )
  399               END IF
  400            END IF
  401            IF( scale.LT.cabs1( wmax )*smlnum .OR. scale.EQ.zero )
  402     $         GO TO 20
  403            CALL pcsrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
 
  404         END IF
  405         GO TO 10
  406      END IF
  407
  408
  409
  410      IF( ainvnm.NE.zero )
  411     $   rcond = ( one / ainvnm ) / anorm
  412
  413   20 CONTINUE
  414
  415      CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
  416      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    rowctop )
  417
  418      RETURN
  419
  420
  421
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
 
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
 
integer function iceil(inum, idenom)
 
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
 
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
 
integer function numroc(n, nb, iproc, isrcproc, nprocs)
 
real function pslamch(ictxt, cmach)
 
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
 
subroutine pclacon(n, v, iv, jv, descv, x, ix, jx, descx, est, kase)
 
subroutine pclatrs(uplo, trans, diag, normin, n, a, ia, ja, desca, x, ix, jx, descx, scale, cnorm, work)
 
subroutine pcsrscl(n, sa, sx, ix, jx, descx, incx)
 
subroutine pxerbla(ictxt, srname, info)