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      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*16         ONE
  215      parameter( one  = ( 1.0d+0, 0.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      COMPLEX*16         AJJ
  225
  226
  230     $                   zgerv2d, zgesd2d, zscal
  231
  232
  233      LOGICAL            LSAME
  234      INTEGER            ILCM, INDXG2P, NUMROC
  236
  237
  238      INTRINSIC          dble, dcmplx, dconjg, 
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 ) = dcmplx( 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, 
'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
  315      IF( info.NE.0 ) THEN
  316         CALL pxerbla( ictxt, 
'PZUNM2R', -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                  IF( notran ) THEN
  339                     ajj = one - tau( jj )
  340                  ELSE
  341                     ajj = one - dconjg( tau( jj ) )
  342                  END IF
  343                  CALL zgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
  344                  CALL zscal( nq-jcc+1, ajj,
  345     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  346     $                        descc( lld_ ) )
  347               ELSE
  348                  CALL zgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
  349     $                          iarow, iacol )
  350                  CALL zscal( nq-jcc+1, ajj,
  351     $                        c( icc+(jcc-1)*descc( lld_ ) ),
  352     $                        descc( lld_ ) )
  353               END IF
  354            END IF
  355         ELSE
  356            IF( mycol.EQ.iacol ) THEN
  357               IF( notran ) THEN
  358                  ajj = one - tau( jj )
  359               ELSE
  360                  ajj = one - dconjg( tau( jj ) )
  361               END IF
  362            END IF
  363
  364            IF( iacol.NE.iccol ) THEN
  365               IF( mycol.EQ.iacol )
  366     $            CALL zgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
  367               IF( mycol.EQ.iccol )
  368     $            CALL zgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
  369            END IF
  370
  371            IF( mycol.EQ.iccol ) THEN
  372               mp = 
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
 
  373     $                      nprow )
  374               CALL zscal( mp-icc+1, ajj, c( icc+(jcc-1)*
  375     $                     descc( lld_ ) ), 1 )
  376            END IF
  377
  378         END IF
  379
  380      ELSE
  381
  382         CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  383         CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  384
  385         IF( left .AND. .NOT.notran .OR. .NOT.left .AND. notran ) THEN
  386            j1 = ja
  387            j2 = ja+k-1
  388            j3 = 1
  389         ELSE
  390            j1 = ja+k-1
  391            j2 = ja
  392            j3 = -1
  393         END IF
  394
  395         IF( left ) THEN
  396            ni  = n
  397            jcc = jc
  398            IF( notran ) THEN
  399               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
  400            ELSE
  401               CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
  402            END IF
  403            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
  404         ELSE
  405            mi  = m
  406            icc = ic
  407         END IF
  408
  409         DO 10 j = j1, j2, j3
  410            IF( left ) THEN
  411
  412
  413
  414               mi  = m - j + ja
  415               icc = ic + j - ja
  416            ELSE
  417
  418
  419
  420               ni  = n - j + ja
  421               jcc = jc + j - ja
  422            END IF
  423
  424
  425
  426            CALL pzelset2( ajj, a, ia+j-ja, j, desca, one )
 
  427            IF( notran ) THEN
  428               CALL pzlarf( side, mi, ni, a, ia+j-ja, j, desca, 1, tau,
 
  429     $                      c, icc, jcc, descc, work )
  430            ELSE
  431               CALL pzlarfc( side, mi, ni, a, ia+j-ja, j, desca, 1, tau,
 
  432     $                    c, icc, jcc, descc, work )
  433            END IF
  434            CALL pzelset( a, ia+j-ja, j, desca, ajj )
 
  435
  436   10    CONTINUE
  437
  438         CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  439         CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  440
  441      END IF
  442
  443      work( 1 ) = dcmplx( dble( lwmin ) )
  444
  445      RETURN
  446
  447
  448
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 pxerbla(ictxt, srname, info)
 
subroutine pzelset2(alpha, a, ia, ja, desca, beta)
 
subroutine pzelset(a, ia, ja, desca, alpha)
 
subroutine pzlarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
 
subroutine pzlarfc(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)