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            I, I1, I2, I3, IACOL, ICCOL, ICOFFA, ICOFFC,
  221     $                   ICROW, ICTXT, IROFFC, LCM, LCMP, LWMIN, MI,
  222     $                   MPC0, MYCOL, MYROW, NI, NPCOL, NPROW, NQ, NQC0
  223      COMPLEX*16         AII
  224
  225
  226      EXTERNAL           blacs_abort, blacs_gridinfo, 
chk1mat,
 
  229
  230
  231      LOGICAL            LSAME
  232      INTEGER            ILCM, INDXG2P, NUMROC
  234
  235
  236      INTRINSIC          dble, dcmplx, 
max, mod
 
  237
  238
  239
  240
  241
  242      ictxt = desca( ctxt_ )
  243      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  244
  245
  246
  247      info = 0
  248      IF( nprow.EQ.-1 ) THEN
  249         info = -(900+ctxt_)
  250      ELSE
  251         left = 
lsame( side, 
'L' )
 
  252         notran = 
lsame( trans, 
'N' )
 
  253
  254
  255
  256         IF( left ) THEN
  257            nq = m
  258            CALL chk1mat( k, 5, m, 3, ia, ja, desca, 9, info )
 
  259         ELSE
  260            nq = n
  261            CALL chk1mat( k, 5, n, 4, ia, ja, desca, 9, info )
 
  262         END IF
  263         CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
 
  264         IF( info.EQ.0 ) THEN
  265            icoffa = mod( ja-1, desca( nb_ ) )
  266            iroffc = mod( ic-1, descc( mb_ ) )
  267            icoffc = mod( jc-1, descc( nb_ ) )
  268            iacol = 
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
 
  269     $                       npcol )
  270            icrow = 
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
 
  271     $                       nprow )
  272            iccol = 
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
 
  273     $                       npcol )
  274            mpc0 = 
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
 
  275            nqc0 = 
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
 
  276
  277            IF( left ) THEN
  278               lcm = 
ilcm( nprow, npcol )
 
  279               lcmp = lcm / nprow
  281     $                 m+iroffc, desca( mb_ ), 0, 0, nprow ),
  282     $                 desca( mb_ ), 0, 0, lcmp ) )
  283            ELSE
  284               lwmin = nqc0 + 
max( 1, mpc0 )
 
  285            END IF
  286
  287            work( 1 ) = dcmplx( dble( lwmin ) )
  288            lquery = ( lwork.EQ.-1 )
  289            IF( .NOT.left .AND. .NOT.
lsame( side, 
'R' ) ) 
THEN 
  290               info = -1
  291            ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans, 
'C' ) ) 
THEN 
  292               info = -2
  293            ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
  294               info = -5
  295            ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) ) THEN
  296               info = -(900+nb_)
  297            ELSE IF( left .AND. icoffa.NE.iroffc ) THEN
  298               info = -12
  299            ELSE IF( .NOT.left .AND. icoffa.NE.icoffc ) THEN
  300               info = -13
  301            ELSE IF( .NOT.left .AND. iacol.NE.iccol ) THEN
  302               info = -13
  303            ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) ) THEN
  304               info = -(1400+nb_)
  305            ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
  306               info = -(1400+ctxt_)
  307            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  308               info = -16
  309            END IF
  310         END IF
  311      END IF
  312
  313      IF( info.NE.0 ) THEN
  314         CALL pxerbla( ictxt, 
'PZUNMR2', -info )
 
  315         CALL blacs_abort( ictxt, 1 )
  316         RETURN
  317      ELSE IF( lquery ) THEN
  318         RETURN
  319      END IF
  320
  321
  322
  323      IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
  324     $   RETURN
  325
  326      CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  327      CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
  328
  329      IF( ( left .AND. .NOT.notran .OR. .NOT.left .AND. notran ) ) THEN
  330         i1 = ia
  331         i2 = ia + k - 1
  332         i3 = 1
  333      ELSE
  334         i1 = ia + k - 1
  335         i2 = ia
  336         i3 = -1
  337      END IF
  338
  339      IF( left ) THEN
  340         ni = n
  341      ELSE
  342         mi = m
  343         CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
  344         IF( notran ) THEN
  345            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'I-ring' )
  346         ELSE
  347            CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
  348         END IF
  349      END IF
  350
  351      DO 10 i = i1, i2, i3
  352         IF( left ) THEN
  353
  354
  355
  356            mi = m - k + i - ia + 1
  357         ELSE
  358
  359
  360
  361            ni = n - k + i - ia + 1
  362         END IF
  363
  364
  365
  366         CALL pzlacgv( nq-k+i-ia, a, i, ja, desca, desca( m_ ) )
 
  367         CALL pzelset2( aii, a, i, ja+nq-k+i-ia, desca, one )
 
  368         IF( notran ) THEN
  369            CALL pzlarfc( side, mi, ni, a, i, ja, desca, desca( m_ ),
 
  370     $                    tau, c, ic, jc, descc, work )
  371         ELSE
  372            CALL pzlarf( side, mi, ni, a, i, ja, desca, desca( m_ ),
 
  373     $                   tau, c, ic, jc, descc, work )
  374         END IF
  375         CALL pzelset( a, i, ja+nq-k+i-ia, desca, aii )
 
  376         CALL pzlacgv( nq-k+i-ia, a, i, ja, desca, desca( m_ ) )
 
  377
  378   10 CONTINUE
  379
  380      CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
  381      CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
  382
  383      work( 1 ) = dcmplx( dble( lwmin ) )
  384
  385      RETURN
  386
  387
  388
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
 
integer function ilcm(m, n)
 
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
 
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 pzlacgv(n, x, ix, jx, descx, incx)
 
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)