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