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            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      COMPLEX            ONE
  215      parameter( one  = ( 1.0e+0, 0.0e+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      COMPLEX            AJJ
  225
  226
  227      EXTERNAL           blacs_abort, blacs_gridinfo, cgebr2d,
  228     $                   cgebs2d, cgerv2d, cgesd2d, 
chk1mat,
 
  231
  232
  233      LOGICAL            LSAME
  234      INTEGER            ILCM, INDXG2P, NUMROC
  236
  237
  238      INTRINSIC          cmplx, conjg, 
max, mod, real
 
  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 ) = 
cmplx( real( 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, 
'C' ) ) 
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      IF( info.NE.0 ) THEN
  315         CALL pxerbla( ictxt, 
'PCUNM2L', -info )
 
  316         CALL blacs_abort( ictxt, 1 )
  317         RETURN
  318      ELSE IF( lquery ) THEN
  319         RETURN
  320      END IF
  321
  322
  323
  324      IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
  325     $   RETURN
  326
  327      IF( desca( m_ ).EQ.1 ) THEN
  328         CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii,
 
  329     $                 jj, iarow, iacol )
  330         CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, icc,
 
  331     $                 jcc, icrow, iccol )
  332         IF( left ) THEN
  333            IF( myrow.EQ.iarow ) THEN
  334               nq = 
numroc( jc+n-1, descc( nb_ ), mycol, descc( csrc_ ),
 
  335     $                      npcol )
  336               IF( mycol.EQ.iacol ) THEN
  337                  IF( notran ) THEN
  338                     ajj = one - tau( jj )
  339                  ELSE
  340                     ajj = one - conjg( tau( jj ) )
  341                  END IF
  342                  CALL cgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
  343                  CALL cscal( nq-jcc+1, ajj,
  344     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  345     $                        descc( lld_ ) )
  346               ELSE
  347                  CALL cgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
  348     $                          iarow, iacol )
  349                  CALL cscal( nq-jcc+1, ajj,
  350     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  351     $                        descc( lld_ ) )
  352               END IF
  353            END IF
  354         ELSE
  355            IF( mycol.EQ.iacol ) THEN
  356               IF( notran ) THEN
  357                  ajj = one - tau( jj )
  358               ELSE
  359                  ajj = one - conjg( tau( jj ) )
  360               END IF
  361            END IF
  362
  363            IF( iacol.NE.iccol ) THEN
  364               IF( mycol.EQ.iacol )
  365     $            CALL cgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
  366               IF( mycol.EQ.iccol )
  367     $            CALL cgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
  368            END IF
  369
  370            IF( mycol.EQ.iccol ) THEN
  371               mp = 
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
 
  372     $                      nprow )
  373               CALL cscal( mp-icc+1, ajj, c( icc+(jcc-1)*
  374     $                     descc( lld_ ) ), 1 )
  375            END IF
  376
  377         END IF
  378
  379      ELSE
  380
  381         CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  382         CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  383
  384         IF( left .AND. notran .OR. .NOT.left .AND. .NOT.notran ) THEN
  385            j1 = ja
  386            j2 = ja+k-1
  387            j3 = 1
  388         ELSE
  389            j1 = ja+k-1
  390            j2 = ja
  391            j3 = -1
  392         END IF
  393
  394         IF( left ) THEN
  395            ni = n
  396            IF( notran ) THEN
  397               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
  398            ELSE
  399               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
  400            END IF
  401            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
  402         ELSE
  403            mi = m
  404         END IF
  405
  406         DO 10 j = j1, j2, j3
  407
  408            IF( left ) THEN
  409
  410
  411
  412               mi = m - k + j - ja + 1
  413            ELSE
  414
  415
  416
  417               ni = n - k + j - ja + 1
  418            END IF
  419
  420
  421
  422            CALL pcelset2( ajj, a, ia+nq-k+j-ja, j, desca, one )
 
  423            IF( notran ) THEN
  424               CALL pclarf( side, mi, ni, a, ia, j, desca, 1, tau, c,
 
  425     $                      ic, jc, descc, work )
  426            ELSE
  427               CALL pclarfc( side, mi, ni, a, ia, j, desca, 1, tau, c,
 
  428     $                       ic, jc, descc, work )
  429            END IF
  430            CALL pcelset( a, ia+nq-k+j-ja, j, desca, ajj )
 
  431
  432   10    CONTINUE
  433
  434         CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  435         CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  436
  437      END IF
  438
  439      work( 1 ) = 
cmplx( real( lwmin ) )
 
  440
  441      RETURN
  442
  443
  444
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 pcelset2(alpha, a, ia, ja, desca, beta)
 
subroutine pcelset(a, ia, ja, desca, alpha)
 
subroutine pclarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
 
subroutine pclarfc(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
 
subroutine pxerbla(ictxt, srname, info)