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
  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
  227      CHARACTER          COLBTOP, ROWBTOP
  228      INTEGER            IAROW, ICC, ICCOL, ICOFFC, ICROW, ICTXT, IINFO,
  229     $                   IPW, IROFFA, IROFFC, J, J1, J2, J3, JB, JCC,
  230     $                   LCM, LCMQ, LWMIN, MI, MPC0, MYCOL, MYROW, NI,
  231     $                   NPA0, 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          dble, ichar, 
max, 
min, mod
 
  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         left = 
lsame( side, 
'L' )
 
  262         notran = 
lsame( trans, 
'N' )
 
  263
  264
  265
  266         IF( left ) THEN
  267            nq = m
  268            CALL chk1mat( m, 3, k, 5, ia, ja, desca, 9, info )
 
  269         ELSE
  270            nq = n
  271            CALL chk1mat( n, 4, k, 5, ia, ja, desca, 9, info )
 
  272         END IF
  273         CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
 
  274         IF( info.EQ.0 ) THEN
  275            iroffa = mod( ia-1, desca( mb_ ) )
  276            iroffc = mod( ic-1, descc( mb_ ) )
  277            icoffc = mod( jc-1, descc( nb_ ) )
  278            iarow = 
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
 
  279     $                       nprow )
  280            icrow = 
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
 
  281     $                       nprow )
  282            iccol = 
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
 
  283     $                       npcol )
  284            mpc0 = 
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
 
  285            nqc0 = 
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
 
  286
  287            IF( left ) THEN
  288               lwmin = 
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) ) / 2,
 
  289     $                      ( mpc0 + nqc0 ) * desca( nb_ ) ) +
  290     $                 desca( nb_ ) * desca( nb_ )
  291            ELSE
  292               npa0 = 
numroc( n+iroffa, desca( mb_ ), myrow, iarow,
 
  293     $                        nprow )
  294               lcm = 
ilcm( nprow, npcol )
 
  295               lcmq = lcm / npcol
  296               lwmin =  
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
 
  298     $                  n+icoffc, desca( nb_ ), 0, 0, npcol ),
  299     $                  desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
  300     $                  desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
  301            END IF
  302
  303            work( 1 ) = dble( lwmin )
  304            lquery = ( lwork.EQ.-1 )
  305            IF( .NOT.left .AND. .NOT.
lsame( side, 
'R' ) ) 
THEN 
  306               info = -1
  307            ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans, 
'T' ) ) 
THEN 
  308               info = -2
  309            ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
  310               info = -5
  311            ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
  312               info = -(900+nb_)
  313            ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
  314               info = -12
  315            ELSE IF( left .AND. iarow.NE.icrow ) THEN
  316               info = -12
  317            ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
  318               info = -13
  319            ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
  320               info = -(1400+mb_)
  321            ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
  322               info = -(1400+ctxt_)
  323            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  324               info = -16
  325            END IF
  326         END IF
  327
  328         IF( left ) THEN
  329            idum1( 1 ) = ichar( 'L' )
  330         ELSE
  331            idum1( 1 ) = ichar( 'R' )
  332         END IF
  333         idum2( 1 ) = 1
  334         IF( notran ) THEN
  335            idum1( 2 ) = ichar( 'N' )
  336         ELSE
  337            idum1( 2 ) = ichar( 'T' )
  338         END IF
  339         idum2( 2 ) = 2
  340         idum1( 3 ) = k
  341         idum2( 3 ) = 5
  342         IF( lwork.EQ.-1 ) THEN
  343            idum1( 4 ) = -1
  344         ELSE
  345            idum1( 4 ) = 1
  346         END IF
  347         idum2( 4 ) = 16
  348         IF( left ) THEN
  349            CALL pchk2mat( m, 3, k, 5, ia, ja, desca, 9, m, 3, n, 4, ic,
 
  350     $                     jc, descc, 14, 4, idum1, idum2, info )
  351         ELSE
  352            CALL pchk2mat( n, 4, k, 5, ia, ja, desca, 9, m, 3, n, 4, ic,
 
  353     $                     jc, descc, 14, 4, idum1, idum2, info )
  354         END IF
  355      END IF
  356
  357      IF( info.NE.0 ) THEN
  358         CALL pxerbla( ictxt, 
'PDORMQR', -info )
 
  359         RETURN
  360      ELSE IF( lquery ) THEN
  361         RETURN
  362      END IF
  363
  364
  365
  366      IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
  367     $   RETURN
  368
  369      CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  370      CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  371
  372      IF( ( left .AND. .NOT.notran ) .OR.
  373     $    ( .NOT.left .AND. notran ) ) THEN
  374         j1 = 
min( 
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+k-1 )
 
  375     $                    + 1
  376         j2 = ja+k-1
  377         j3 = desca( nb_ )
  378      ELSE
  379         j1 = 
max( ( (ja+k-2) / desca( nb_ ) ) * desca( nb_ ) + 1, ja )
 
  380         j2 = 
min( 
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+k-1 )
 
  381     $                    + 1
  382         j3 = -desca( nb_ )
  383      END IF
  384
  385      IF( left ) THEN
  386         ni  = n
  387         jcc = jc
  388         IF( notran ) THEN
  389            CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
  390         ELSE
  391            CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
  392         END IF
  393         CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
  394      ELSE
  395         mi  = m
  396         icc = ic
  397      END IF
  398
  399
  400
  401      IF( ( left .AND. .NOT.notran ) .OR. ( .NOT.left .AND. notran ) )
  402     $   
CALL pdorm2r( side, trans, m, n, j1-ja, a, ia, ja, desca, tau,
 
  403     $                 c, ic, jc, descc, work, lwork, iinfo )
  404
  405      ipw = desca( nb_ ) * desca( nb_ ) + 1
  406      DO 10 j = j1, j2, j3
  407         jb = 
min( desca( nb_ ), k-j+ja )
 
  408
  409
  410
  411
  412         CALL pdlarft( 
'Forward', 
'Columnwise', nq-j+ja, jb, a,
 
  413     $                 ia+j-ja, j, desca, tau, work, work( ipw ) )
  414         IF( left ) THEN
  415
  416
  417
  418            mi  = m - j + ja
  419            icc = ic + j - ja
  420         ELSE
  421
  422
  423
  424            ni  = n - j + ja
  425            jcc = jc + j - ja
  426         END IF
  427
  428
  429
  430         CALL pdlarfb( side, trans, 
'Forward', 
'Columnwise', mi, ni,
 
  431     $                jb, a, ia+j-ja, j, desca, work, c, icc, jcc,
  432     $                descc, work( ipw ) )
  433   10 CONTINUE
  434
  435
  436
  437      IF( ( left .AND. notran ) .OR. ( .NOT.left .AND. .NOT.notran ) )
  438     $   
CALL pdorm2r( side, trans, m, n, j2-ja, a, ia, ja, desca, tau,
 
  439     $                 c, ic, jc, descc, work, lwork, iinfo )
  440
  441      CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  442      CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  443
  444      work( 1 ) = dble( lwmin )
  445
  446      RETURN
  447
  448
  449
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 pdlarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
 
subroutine pdlarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
 
subroutine pdorm2r(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
 
subroutine pxerbla(ictxt, srname, info)