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      DOUBLE PRECISION   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      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  210     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  211      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  212     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  213     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  214      DOUBLE PRECISION   ONE
  215      parameter( one = 1.0d+0 )
  216
  217
  218      LOGICAL            LEFT, LQUERY, NOTRAN
  219      CHARACTER          COLBTOP, ROWBTOP
  220      INTEGER            IACOL, IAROW, ICCOL, ICOFFC, ICROW, ICTXT, ICC,
  221     $                   II, IROFFA, IROFFC, J, J1, J2, J3, JCC, JJ,
  222     $                   LCM, LCMQ, LWMIN, MI, MP, MPC0, MYCOL, MYROW,
  223     $                   NI, NPCOL, NPROW, NQ, NQC0
  224      DOUBLE PRECISION   AJJ
  225
  226
  227      EXTERNAL           blacs_abort, blacs_gridinfo, 
chk1mat, dgebr2d,
 
  228     $                   dgebs2d, dgerv2d, dgesd2d, dscal,
  230     $                   pb_topget, pb_topset, 
pxerbla 
  231
  232
  233      LOGICAL            LSAME
  234      INTEGER            ILCM, INDXG2P, NUMROC
  236
  237
  238      INTRINSIC          dble, 
max, mod
 
  239
  240
  241
  242
  243
  244      ictxt = desca( ctxt_ )
  245      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  246
  247
  248
  249      info = 0
  250      IF( nprow.EQ.-1 ) THEN
  251         info = -(900+ctxt_)
  252      ELSE
  253         left = 
lsame( side, 
'L' )
 
  254         notran = 
lsame( trans, 
'N' )
 
  255
  256
  257
  258         IF( left ) THEN
  259            nq = m
  260            CALL chk1mat( m, 3, k, 5, ia, ja, desca, 9, info )
 
  261         ELSE
  262            nq = n
  263            CALL chk1mat( n, 4, k, 5, ia, ja, desca, 9, info )
 
  264         END IF
  265         CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
 
  266         IF( info.EQ.0 ) THEN
  267            iroffa = mod( ia-1, desca( mb_ ) )
  268            iroffc = mod( ic-1, descc( mb_ ) )
  269            icoffc = mod( jc-1, descc( nb_ ) )
  270            iarow = 
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
 
  271     $                       nprow )
  272            icrow = 
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
 
  273     $                       nprow )
  274            iccol = 
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
 
  275     $                       npcol )
  276            mpc0 = 
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
 
  277            nqc0 = 
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
 
  278
  279            IF( left ) THEN
  280               lwmin = mpc0 + 
max( 1, nqc0 )
 
  281            ELSE
  282               lcm = 
ilcm( nprow, npcol )
 
  283               lcmq = lcm / npcol
  285     $                 n+icoffc, desca( nb_ ), 0, 0, npcol ),
  286     $                 desca( nb_ ), 0, 0, lcmq ) )
  287            END IF
  288
  289            work( 1 ) = dble( lwmin )
  290            lquery = ( lwork.EQ.-1 )
  291            IF( .NOT.left .AND. .NOT.
lsame( side, 
'R' ) ) 
THEN 
  292               info = -1
  293            ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans, 
'T' ) ) 
THEN 
  294               info = -2
  295            ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
  296               info = -5
  297            ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
  298               info = -(900+nb_)
  299            ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
  300               info = -12
  301            ELSE IF( left .AND. iarow.NE.icrow ) THEN
  302               info = -12
  303            ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
  304               info = -13
  305            ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
  306               info = -(1400+mb_)
  307            ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
  308               info = -(1400+ctxt_)
  309            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  310               info = -16
  311            END IF
  312         END IF
  313      END IF
  314
  315      IF( info.NE.0 ) THEN
  316         CALL pxerbla( ictxt, 
'PDORM2R', -info )
 
  317         CALL blacs_abort( ictxt, 1 )
  318         RETURN
  319      ELSE IF( lquery ) THEN
  320         RETURN
  321      END IF
  322
  323
  324
  325      IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
  326     $   RETURN
  327
  328      IF( desca( m_ ).EQ.1 ) THEN
  329         CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii,
 
  330     $                 jj, iarow, iacol )
  331         CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, icc,
 
  332     $                 jcc, icrow, iccol )
  333         IF( left ) THEN
  334            IF( myrow.EQ.iarow ) THEN
  335               nq = 
numroc( jc+n-1, descc( nb_ ), mycol, descc( csrc_ ),
 
  336     $                      npcol )
  337               IF( mycol.EQ.iacol ) THEN
  338                  ajj = one - tau( jj )
  339                  CALL dgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
  340                  CALL dscal( nq-jcc+1, ajj,
  341     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  342     $                        descc( lld_ ) )
  343               ELSE
  344                  CALL dgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
  345     $                          iarow, iacol )
  346                  CALL dscal( nq-jcc+1, ajj,
  347     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  348     $                        descc( lld_ ) )
  349               END IF
  350            END IF
  351         ELSE
  352            IF( mycol.EQ.iacol ) THEN
  353               ajj = one - tau( jj )
  354            END IF
  355
  356            IF( iacol.NE.iccol ) THEN
  357               IF( mycol.EQ.iacol )
  358     $            CALL dgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
  359               IF( mycol.EQ.iccol )
  360     $            CALL dgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
  361            END IF
  362
  363            IF( mycol.EQ.iccol ) THEN
  364               mp = 
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
 
  365     $                      nprow )
  366               CALL dscal( mp-icc+1, ajj, c( icc+(jcc-1)*
  367     $                     descc( lld_ ) ), 1 )
  368            END IF
  369
  370         END IF
  371
  372      ELSE
  373
  374         CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  375         CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  376
  377         IF( left .AND. .NOT.notran .OR. .NOT.left .AND. notran ) THEN
  378            j1 = ja
  379            j2 = ja+k-1
  380            j3 = 1
  381         ELSE
  382            j1 = ja+k-1
  383            j2 = ja
  384            j3 = -1
  385         END IF
  386
  387         IF( left ) THEN
  388            ni  = n
  389            jcc = jc
  390            IF( notran ) THEN
  391               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
  392            ELSE
  393               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
  394            END IF
  395            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
  396         ELSE
  397            mi  = m
  398            icc = ic
  399         END IF
  400
  401         DO 10 j = j1, j2, j3
  402            IF( left ) THEN
  403
  404
  405
  406               mi  = m - j + ja
  407               icc = ic + j - ja
  408            ELSE
  409
  410
  411
  412               ni  = n - j + ja
  413               jcc = jc + j - ja
  414            END IF
  415
  416
  417
  418            CALL pdelset2( ajj, a, ia+j-ja, j, desca, one )
 
  419            CALL pdlarf( side, mi, ni, a, ia+j-ja, j, desca, 1, tau, c,
 
  420     $                   icc, jcc, descc, work )
  421            CALL pdelset( a, ia+j-ja, j, desca, ajj )
 
  422
  423   10    CONTINUE
  424
  425         CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  426         CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  427
  428      END IF
  429
  430      work( 1 ) = dble( lwmin )
  431
  432      RETURN
  433
  434
  435
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
 
integer function ilcm(m, n)
 
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)
 
subroutine pdelset2(alpha, a, ia, ja, desca, beta)
 
subroutine pdelset(a, ia, ja, desca, alpha)
 
subroutine pdlarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
 
subroutine pxerbla(ictxt, srname, info)