3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          SIDE, TRANS, UPLO
   11      INTEGER            IA, IC, INFO, JA, JC, 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
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  236     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  237      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  238     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  239     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  240
  241
  242      LOGICAL            LEFT, LQUERY, NOTRAN, UPPER
  243      INTEGER            IAA, IAROW, ICC, ICCOL, ICOFFC, ICROW, ICTXT,
  244     $                   IINFO, IROFFA, IROFFC, JAA, JCC, LCM, LCMQ,
  245     $                   LWMIN, MI, MPC0, MYCOL, MYROW, NI, NPA0, NPCOL,
  246     $                   NPROW, NQ, NQC0
  247
  248
  249      INTEGER            IDUM1( 4 ), IDUM2( 4 )
  250
  251
  254
  255
  256      LOGICAL            LSAME
  257      INTEGER            ILCM, INDXG2P, NUMROC
  259
  260
  261      INTRINSIC          dble, ichar, 
max, mod
 
  262
  263
  264
  265
  266
  267      ictxt = desca( ctxt_ )
  268      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  269
  270
  271
  272      info = 0
  273      IF( nprow.EQ.-1 ) THEN
  274         info = -(900+ctxt_)
  275      ELSE
  276         left = 
lsame( side, 
'L' )
 
  277         notran = 
lsame( trans, 
'N' )
 
  278         upper = 
lsame( uplo, 
'U' )
 
  279
  280         IF( upper ) THEN
  281            iaa = ia
  282            jaa = ja+1
  283            icc = ic
  284            jcc = jc
  285         ELSE
  286            iaa = ia+1
  287            jaa = ja
  288            IF( left ) THEN
  289               icc = ic + 1
  290               jcc = jc
  291            ELSE
  292               icc = ic
  293               jcc = jc + 1
  294            END IF
  295         END IF
  296
  297
  298
  299         IF( left ) THEN
  300            nq = m
  301            mi = m - 1
  302            ni = n
  303            CALL chk1mat( mi, 4, nq-1, 4, iaa, jaa, desca, 9, info )
 
  304         ELSE
  305            nq = n
  306            mi = m
  307            ni = n - 1
  308            CALL chk1mat( ni, 5, nq-1, 5, iaa, jaa, desca, 9, info )
 
  309         END IF
  310         CALL chk1mat( mi, 4, ni, 5, icc, jcc, descc, 14, info )
 
  311         IF( info.EQ.0 ) THEN
  312            iroffa = mod( iaa-1, desca( mb_ ) )
  313            iroffc = mod( icc-1, descc( mb_ ) )
  314            icoffc = mod( jcc-1, descc( nb_ ) )
  315            iarow = 
indxg2p( iaa, desca( mb_ ), myrow, desca( rsrc_ ),
 
  316     $                       nprow )
  317            icrow = 
indxg2p( icc, descc( mb_ ), myrow, descc( rsrc_ ),
 
  318     $                       nprow )
  319            iccol = 
indxg2p( jcc, descc( nb_ ), mycol, descc( csrc_ ),
 
  320     $                       npcol )
  321            mpc0 = 
numroc( mi+iroffc, descc( mb_ ), myrow, icrow,
 
  322     $                     nprow )
  323            nqc0 = 
numroc( ni+icoffc, descc( nb_ ), mycol, iccol,
 
  324     $                     npcol )
  325
  326            IF( left ) THEN
  327               lwmin = 
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) ) / 2,
 
  328     $                      ( mpc0 + nqc0 ) * desca( nb_ ) ) +
  329     $                 desca( nb_ ) * desca( nb_ )
  330            ELSE
  331               npa0 = 
numroc( ni+iroffa, desca( mb_ ), myrow, iarow,
 
  332     $                        nprow )
  333               lcm = 
ilcm( nprow, npcol )
 
  334               lcmq = lcm / npcol
  335               lwmin =  
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
 
  337     $                  ni+icoffc, desca( nb_ ), 0, 0, npcol ),
  338     $                  desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
  339     $                  desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
  340            END IF
  341
  342            work( 1 ) = dble( lwmin )
  343            lquery = ( lwork.EQ.-1 )
  344            IF( .NOT.left .AND. .NOT.
lsame( side, 
'R' ) ) 
THEN 
  345               info = -1
  346            ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo, 
'L' ) ) 
THEN 
  347               info = -2
  348            ELSE IF( .NOT.
lsame( trans, 
'N' ) .AND.
 
  349     $               .NOT.
lsame( trans, 
'T' ) ) 
THEN 
  350               info = -3
  351            ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
  352               info = -(900+nb_)
  353            ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
  354               info = -12
  355            ELSE IF( left .AND. iarow.NE.icrow ) THEN
  356               info = -12
  357            ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
  358               info = -13
  359            ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
  360               info = -(1400+mb_)
  361            ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
  362               info = -(1400+ctxt_)
  363            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  364               info = -16
  365            END IF
  366         END IF
  367
  368         IF( left ) THEN
  369            idum1( 1 ) = ichar( 'L' )
  370         ELSE
  371            idum1( 1 ) = ichar( 'R' )
  372         END IF
  373         idum2( 1 ) = 1
  374         IF( upper ) THEN
  375            idum1( 2 ) = ichar( 'U' )
  376         ELSE
  377            idum1( 2 ) = ichar( 'L' )
  378         END IF
  379         idum2( 2 ) = 2
  380         IF( notran ) THEN
  381            idum1( 3 ) = ichar( 'N' )
  382         ELSE
  383            idum1( 3 ) = ichar( 'T' )
  384         END IF
  385         idum2( 3 ) = 3
  386         IF( lwork.EQ.-1 ) THEN
  387            idum1( 4 ) = -1
  388         ELSE
  389            idum1( 4 ) = 1
  390         END IF
  391         idum2( 4 ) = 16
  392         IF( left ) THEN
  393            CALL pchk2mat( mi, 4, nq-1, 4, iaa, jaa, desca, 9, mi, 4,
 
  394     $                     ni, 5, icc, jcc, descc, 14, 4, idum1, idum2,
  395     $                     info )
  396         ELSE
  397            CALL pchk2mat( ni, 5, nq-1, 5, iaa, jaa, desca, 9, mi, 4,
 
  398     $                     ni, 5, icc, jcc, descc, 14, 4, idum1, idum2,
  399     $                     info )
  400         END IF
  401      END IF
  402
  403      IF( info.NE.0 ) THEN
  404         CALL pxerbla( ictxt, 
'PDORMTR', -info )
 
  405         RETURN
  406      ELSE IF( lquery ) THEN
  407         RETURN
  408      END IF
  409
  410
  411
  412      IF( m.EQ.0 .OR. n.EQ.0 .OR. nq.EQ.1 )
  413     $   RETURN
  414
  415      IF( upper ) THEN
  416
  417
  418
  419         CALL pdormql( side, trans, mi, ni, nq-1, a, iaa, jaa, desca,
 
  420     $                 tau, c, icc, jcc, descc, work, lwork, iinfo )
  421
  422      ELSE
  423
  424
  425
  426         CALL pdormqr( side, trans, mi, ni, nq-1, a, iaa, jaa, desca,
 
  427     $                 tau, c, icc, jcc, descc, work, lwork, iinfo )
  428
  429      END IF
  430
  431      work( 1 ) = dble( lwmin )
  432
  433      RETURN
  434
  435
  436
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 pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
 
subroutine pdormql(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
 
subroutine pdormqr(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
 
subroutine pxerbla(ictxt, srname, info)