3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          UPLO
   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      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  171     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  172      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  173     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  174     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  175      REAL               ONE, ZERO
  176      parameter( one = 1.0e+0, zero = 0.0e+0 )
  177
  178
  179      LOGICAL            LQUERY, UPPER
  180      CHARACTER          CBTOP, COLCTOP, NORMIN, ROWCTOP
  181      INTEGER            IACOL, IAROW, ICOFF, ICTXT, IIA, IPNL, IPNU,
  182     $                   IPV, IPW, IPX, IROFF, IV, IX, IXX, JJA, JV,
  183     $                   JX, KASE, LRWMIN, LWMIN, MYCOL, MYROW, NP,
  184     $                   NPCOL, NPROW, NPMOD, NQ, NQMOD
  185      REAL               AINVNM, SCALE, SL, SU, SMLNUM
  186      COMPLEX            WMAX, ZDUM
  187
  188
  189      INTEGER            DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 3 ),
  190     $                   IDUM2( 3 )
  191
  192
  193      EXTERNAL           blacs_gridinfo, cgebr2d, cgebs2d, 
chk1mat,
 
  197
  198
  199      LOGICAL            LSAME
  200      INTEGER            ICEIL, INDXG2P, NUMROC
  201      REAL               PSLAMCH
  203
  204
  205      INTRINSIC          abs, aimag, ichar, 
max, mod, real
 
  206
  207
  208      REAL               CABS1
  209
  210
  211      cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
  212
  213
  214
  215
  216
  217      ictxt = desca( ctxt_ )
  218      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  219
  220
  221
  222      info = 0
  223      IF( nprow.EQ.-1 ) THEN
  224         info = -(600+ctxt_)
  225      ELSE
  226         CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
 
  227         IF( info.EQ.0 ) THEN
  228            upper = 
lsame( uplo, 
'U' )
 
  229            iarow = 
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
 
  230     $                       nprow )
  231            iacol = 
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
 
  232     $                       npcol )
  233            npmod = 
numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
 
  234     $                      myrow, iarow, nprow )
  235            nqmod = 
numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
 
  236     $                      mycol, iacol, npcol )
  237            lwmin = 2*npmod +
  238     $              
max( 2, 
max( desca( nb_ )*
 
  239     $                   
max( 1, 
iceil( nprow-1, npcol ) ), nqmod +
 
  240     $                   desca( nb_ )*
  241     $                   
max( 1, 
iceil( npcol-1, nprow ) ) ) )
 
  242            work( 1 ) = real( lwmin )
  243            lrwmin = 2*nqmod
  244            rwork( 1 ) = real( lrwmin )
  245            lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
  246
  247            IF( .NOT.upper .AND. .NOT.
lsame( uplo, 
'L' ) ) 
THEN 
  248               info = -1
  249            ELSE IF( anorm.LT.zero ) THEN
  250               info = -7
  251            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  252               info = -10
  253            ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
  254               info = -12
  255            END IF
  256         END IF
  257
  258         IF( upper ) THEN
  259            idum1( 1 ) = ichar( 'U' )
  260         ELSE
  261            idum1( 1 ) = ichar( 'L' )
  262         END IF
  263         idum2( 1 ) = 1
  264         IF( lwork.EQ.-1 ) THEN
  265            idum1( 2 ) = -1
  266         ELSE
  267            idum1( 2 ) = 1
  268         END IF
  269         idum2( 2 ) = 10
  270         IF( lrwork.EQ.-1 ) THEN
  271            idum1( 3 ) = -1
  272         ELSE
  273            idum1( 3 ) = 1
  274         END IF
  275         idum2( 3 ) = 12
  276         CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 3, idum1, idum2,
 
  277     $                  info )
  278      END IF
  279
  280      IF( info.NE.0 ) THEN
  281         CALL pxerbla( ictxt, 
'PCPOCON', -info )
 
  282         RETURN
  283      ELSE IF( lquery ) THEN
  284         RETURN
  285      END IF
  286
  287
  288
  289      rcond = zero
  290      IF( n.EQ.0 ) THEN
  291         rcond = one
  292         RETURN
  293      ELSE IF( anorm.EQ.zero ) THEN
  294         RETURN
  295      ELSE IF( n.EQ.1 ) THEN
  296         rcond = one
  297         RETURN
  298      END IF
  299
  300      CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
  301      CALL pb_topget( ictxt, 'Combine', 'Rowwise',    rowctop )
  302      CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
  303      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    '1-tree' )
  304
  305      smlnum = 
pslamch( ictxt, 
'Safe minimum' )
 
  306      iroff = mod( ia-1, desca( mb_ ) )
  307      icoff = mod( ja-1, desca( nb_ ) )
  308      CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
 
  309     $              iarow, iacol )
  310      np = 
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
 
  311      nq = 
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
 
  312      iv = iroff + 1
  313      ix = iv
  314      jv = icoff + 1
  315      jx = jv
  316
  317      ipx = 1
  318      ipv = ipx + np
  319      ipw = ipv + np
  320      ipnl = 1
  321      ipnu = ipnl + nq
  322
  323      CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  324     $              ictxt, 
max( 1, np ) )
 
  325      CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  326     $              ictxt, 
max( 1, np ) )
 
  327
  328
  329
  330      ainvnm = zero
  331      kase   = 0
  332      normin = 'N'
  333
  334   10 CONTINUE
  335      CALL pclacon( n, work( ipv ), iv, jv, descv, work( ipx ), ix, jx,
 
  336     $              descx, ainvnm, kase )
  337      IF( kase.NE.0 ) THEN
  338         IF( upper ) THEN
  339
  340
  341
  342            descx( csrc_ ) = iacol
  343            CALL pclatrs( 
'Upper', 
'Conjugate transpose', 
'Non-unit',
 
  344     $                    normin, n, a, ia, ja, desca, work( ipx ),
  345     $                    ix, jx, descx, sl, rwork( ipnl ),
  346     $                    work( ipw ) )
  347            descx( csrc_ ) = mycol
  348            normin = 'Y'
  349
  350
  351
  352            descx( csrc_ ) = iacol
  353            CALL pclatrs( 
'Upper', 
'No transpose', 
'Non-unit', normin,
 
  354     $                    n, a, ia, ja, desca, work( ipx ), ix, jx,
  355     $                    descx, su, rwork( ipnu ), work( ipw ) )
  356            descx( csrc_ ) = mycol
  357         ELSE
  358
  359
  360
  361            descx( csrc_ ) = iacol
  362            CALL pclatrs( 
'Lower', 
'No transpose', 
'Non-unit', normin,
 
  363     $                    n, a, ia, ja, desca, work( ipx ), ix, jx,
  364     $                    descx, sl, rwork( ipnl ), work( ipw ) )
  365            descx( csrc_ ) = mycol
  366            normin = 'Y'
  367
  368
  369
  370            descx( csrc_ ) = iacol
  371            CALL pclatrs( 
'Lower', 
'Conjugate transpose', 
'Non-unit',
 
  372     $                    normin, n, a, ia, ja, desca, work( ipx ),
  373     $                    ix, jx, descx, su, rwork( ipnu ),
  374     $                    work( ipw ) )
  375            descx( csrc_ ) = mycol
  376         END IF
  377
  378
  379
  380         scale = sl*su
  381         IF( scale.NE.one ) THEN
  382            CALL pcamax( n, wmax, ixx, work( ipx ), ix, jx, descx, 1 )
  383            IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
  384               CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', cbtop )
  385               IF( myrow.EQ.iarow ) THEN
  386                  CALL cgebs2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1 )
  387               ELSE
  388                  CALL cgebr2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1,
  389     $                          iarow, mycol )
  390               END IF
  391            END IF
  392            IF( scale.LT.cabs1( wmax )*smlnum .OR. scale.EQ.zero )
  393     $         GO TO 20
  394            CALL pcsrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
 
  395         END IF
  396         GO TO 10
  397      END IF
  398
  399
  400
  401      IF( ainvnm.NE.zero )
  402     $   rcond = ( one / ainvnm ) / anorm
  403
  404   20 CONTINUE
  405
  406      CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
  407      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    rowctop )
  408
  409      RETURN
  410
  411
  412
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)