3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          SIDE, TRANS
   11      INTEGER            IA, IC, INFO, JA, JC, K, LWORK, M, N
   12
   13
   14      INTEGER            DESCA( * ), DESCC( * )
   15      REAL               A( * ), C( * ), TAU( * ), WORK( * )
   16
   17
   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
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  220     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  221      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  222     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  223     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  224
  225
  226      LOGICAL            LEFT, LQUERY, NOTRAN, RIGHT, TRAN
  227      CHARACTER          COLBTOP, ROWBTOP, TRANST
  228      INTEGER            I, I1, I2, I3, IACOL, IB, ICCOL, ICOFFA,
  229     $                   ICOFFC, ICROW, ICTXT, IINFO, IPW, IROFFC, LCM,
  230     $                   LCMP, LWMIN, MI, MPC0, MQA0, MYCOL, MYROW, NI,
  231     $                   NPCOL, NPROW, NQ, NQC0
  232
  233
  234      INTEGER            IDUM1( 4 ), IDUM2( 4 )
  235
  236
  239
  240
  241      LOGICAL            LSAME
  242      INTEGER            ICEIL, ILCM, INDXG2P, NUMROC
  244
  245
  246      INTRINSIC          ichar, 
max, 
min, mod, real
 
  247
  248
  249
  250
  251
  252      ictxt = desca( ctxt_ )
  253      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  254
  255
  256
  257      info = 0
  258      IF( nprow.EQ.-1 ) THEN
  259         info = -(900+ctxt_)
  260      ELSE
  261         IF( 
lsame( side, 
'L' ) ) 
THEN 
  262            left = .true.
  263            right = .false.
  264         ELSE
  265            left = .false.
  266            right = .true.
  267         END IF
  268         IF( 
lsame( trans, 
'N' ) ) 
THEN 
  269            notran = .true.
  270            tran = .false.
  271         ELSE
  272            notran = .false.
  273            tran = .true.
  274         END IF
  275
  276
  277
  278         IF( left ) THEN
  279            nq = m
  280            CALL chk1mat( k, 5, m, 3, ia, ja, desca, 9, info )
 
  281         ELSE
  282            nq = n
  283            CALL chk1mat( k, 5, n, 4, ia, ja, desca, 9, info )
 
  284         END IF
  285         CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
 
  286         IF( info.EQ.0 ) THEN
  287            icoffa = mod( ja-1, desca( nb_ ) )
  288            iroffc = mod( ic-1, descc( mb_ ) )
  289            icoffc = mod( jc-1, descc( nb_ ) )
  290            iacol = 
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
 
  291     $                       npcol )
  292            icrow = 
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
 
  293     $                       nprow )
  294            iccol = 
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
 
  295     $                       npcol )
  296            mpc0 = 
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
 
  297            nqc0 = 
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
 
  298
  299            IF( left ) THEN
  300               mqa0 = 
numroc( m+icoffa, desca( nb_ ), mycol, iacol,
 
  301     $                        npcol )
  302               lcm = 
ilcm( nprow, npcol )
 
  303               lcmp = lcm / nprow
  304               lwmin =  
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
 
  306     $                  m+iroffc, desca( mb_ ), 0, 0, nprow ),
  307     $                  desca( mb_ ), 0, 0, lcmp ), nqc0 ) ) *
  308     $                  desca( mb_ ) ) + desca( mb_ ) * desca( mb_ )
  309            ELSE
  310               lwmin = 
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) ) / 2,
 
  311     $                      ( mpc0 + nqc0 ) * desca( mb_ ) ) +
  312     $                 desca( mb_ ) * desca( mb_ )
  313            END IF
  314
  315            work( 1 ) = real( lwmin )
  316            lquery = ( lwork.EQ.-1 )
  317            IF( .NOT.left .AND. .NOT.
lsame( side, 
'R' ) ) 
THEN 
  318               info = -1
  319            ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans, 
'T' ) ) 
THEN 
  320               info = -2
  321            ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
  322               info = -5
  323            ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) ) THEN
  324               info = -(900+nb_)
  325            ELSE IF( left .AND. icoffa.NE.iroffc ) THEN
  326               info = -12
  327            ELSE IF( .NOT.left .AND. icoffa.NE.icoffc ) THEN
  328               info = -13
  329            ELSE IF( .NOT.left .AND. iacol.NE.iccol ) THEN
  330               info = -13
  331            ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) ) THEN
  332               info = -(1400+nb_)
  333            ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
  334               info = -(1400+ctxt_)
  335            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  336               info = -16
  337            END IF
  338         END IF
  339         IF( left ) THEN
  340            idum1( 1 ) = ichar( 'L' )
  341         ELSE
  342            idum1( 1 ) = ichar( 'R' )
  343         END IF
  344         idum2( 1 ) = 1
  345         IF( notran ) THEN
  346            idum1( 2 ) = ichar( 'N' )
  347         ELSE
  348            idum1( 2 ) = ichar( 'T' )
  349         END IF
  350         idum2( 2 ) = 2
  351         idum1( 3 ) = k
  352         idum2( 3 ) = 5
  353         IF( lwork.EQ.-1 ) THEN
  354            idum1( 4 ) = -1
  355         ELSE
  356            idum1( 4 ) = 1
  357         END IF
  358         idum2( 4 ) = 16
  359         IF( left ) THEN
  360            CALL pchk2mat( k, 5, m, 3, ia, ja, desca, 9, m, 3, n, 4,
 
  361     $                     ic, jc, descc, 14, 4, idum1, idum2, info )
  362         ELSE
  363            CALL pchk2mat( k, 5, n, 4, ia, ja, desca, 9, m, 3, n, 4,
 
  364     $                     ic, jc, descc, 14, 4, idum1, idum2, info )
  365         END IF
  366      END IF
  367
  368      IF( info.NE.0 ) THEN
  369         CALL pxerbla( ictxt, 
'PSORMRQ', -info )
 
  370         RETURN
  371      ELSE IF( lquery ) THEN
  372         RETURN
  373      END IF
  374
  375
  376
  377      IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
  378     $   RETURN
  379
  380      CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  381      CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  382
  383      IF( ( left .AND. .NOT.notran ) .OR.
  384     $    ( .NOT.left .AND. notran ) ) THEN
  385         i1 = 
min( 
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
 
  386     $                    + 1
  387         i2 = ia + k - 1
  388         i3 = desca( mb_ )
  389      ELSE
  390         i1 = 
max( ( (ia+k-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
 
  391         i2 = 
min( 
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
 
  392     $                    + 1
  393         i3 = -desca( mb_ )
  394      END IF
  395
  396      IF( left ) THEN
  397         ni = n
  398      ELSE
  399         mi = m
  400         CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
  401         IF( notran ) THEN
  402            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'I-ring' )
  403         ELSE
  404            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
  405         END IF
  406      END IF
  407
  408      IF( notran ) THEN
  409         transt = 'T'
  410      ELSE
  411         transt = 'N'
  412      END IF
  413
  414      IF( ( left .AND. .NOT.notran ) .OR.
  415     $    ( .NOT.left .AND. notran ) ) THEN
  416         ib = i1 - ia
  417         IF( left ) THEN
  418            mi = m - k + ib
  419         ELSE
  420            ni = n - k + ib
  421         END IF
  422         CALL psormr2( side, trans, mi, ni, ib, a, ia, ja, desca, tau,
 
  423     $                 c, ic, jc, descc, work, lwork, iinfo )
  424      END IF
  425
  426      ipw = desca( mb_ )*desca( mb_ ) + 1
  427      DO 10 i = i1, i2, i3
  428         ib = 
min( desca( mb_ ), k-i+ia )
 
  429
  430
  431
  432
  433         CALL pslarft( 
'Backward', 
'Rowwise', nq-k+i+ib-ia, ib,
 
  434     $                 a, i, ja, desca, tau, work, work( ipw ) )
  435         IF( left ) THEN
  436
  437
  438
  439            mi = m - k + i + ib - ia
  440         ELSE
  441
  442
  443
  444            ni = n - k + i + ib - ia
  445         END IF
  446
  447
  448
  449         CALL pslarfb( side, transt, 
'Backward', 
'Rowwise', mi, ni,
 
  450     $                ib, a, i, ja, desca, work, c, ic, jc, descc,
  451     $                work( ipw ) )
  452   10 CONTINUE
  453
  454      IF( ( right .AND. tran ) .OR.
  455     $    ( left .AND. notran ) ) THEN
  456         ib = i2 - ia
  457         IF( left ) THEN
  458            mi = m - k + ib
  459         ELSE
  460            ni = n - k + ib
  461         END IF
  462         CALL psormr2( side, trans, mi, ni, ib, a, ia, ja, desca, tau,
 
  463     $                 c, ic, jc, descc, work, lwork, iinfo )
  464      END IF
  465
  466      CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  467      CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  468
  469      work( 1 ) = real( lwmin )
  470
  471      RETURN
  472
  473
  474
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
 
integer function iceil(inum, idenom)
 
integer function ilcm(m, n)
 
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
 
integer function numroc(n, nb, iproc, isrcproc, nprocs)
 
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
 
subroutine pslarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
 
subroutine pslarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
 
subroutine psormr2(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
 
subroutine pxerbla(ictxt, srname, info)