1 SUBROUTINE pdormlq( SIDE, TRANS, M, N, K, A, IA, JA, DESCA, TAU,
2 $ C, IC, JC, DESCC, WORK, LWORK, INFO )
11 INTEGER IA, IC, INFO, JA, JC, K, LWORK, M, N
14 INTEGER DESCA( * ), DESCC( * )
15 DOUBLE PRECISION A( * ), ( * ), TAU( * ), WORK( * )
219 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
221 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
222 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_
223 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
226 LOGICAL LEFT, LQUERY, NOTRAN
227 CHARACTER COLBTOP, ROWBTOP, TRANST
228 INTEGER I, I1, I2, I3, IACOL, IB, ICC, ICCOL, ICOFFA,
229 $ icoffc, icrow, ictxt, iinfo, ipw, iroffc, jcc,
230 $ lcm, lcmp, lwmin, mi, mpc0, mqa0, mycol, myrow,
231 $ ni, npcol, nprow, nq, nqc0
234 INTEGER IDUM1( 4 ), IDUM2( 4 )
242 INTEGER ICEIL, , INDXG2P, NUMROC
243 EXTERNAL iceil,
ilcm, indxg2p, lsame, numroc
246 INTRINSIC dble, ichar,
max,
min, mod
252 ictxt = desca( ctxt_ )
258 IF( nprow.EQ.-1 )
THEN
261 left = lsame( side,
'L' )
262 notran = lsame( trans,
'N' )
268 CALL chk1mat( k, 5, m, 3, ia, ja, desca, 9, info )
271 CALL chk1mat( k, 5, n, 4, ia, ja, desca, 9, info )
273 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
275 icoffa = mod( ja-1, desca( nb_ ) )
276 iroffc = mod( ic-1, descc( mb_ ) )
277 icoffc = mod( jc-1, descc( nb_ ) )
278 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
280 icrow = indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
282 iccol = indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
284 mpc0 = numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
285 nqc0 = numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
288 mqa0 = numroc( m+icoffa, desca( nb_ ), mycol, iacol,
290 lcm =
ilcm( nprow, npcol )
292 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
293 $ / 2, ( mpc0 +
max( mqa0 + numroc( numroc(
294 $ m+iroffc, desca( mb_ ), 0, 0, nprow ),
295 $ desca( mb_ ), 0, 0, lcmp ), nqc0 ) ) *
296 $ desca( mb_ ) ) + desca( mb_ ) * desca( mb_ )
298 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) ) / 2,
299 $ ( mpc0 + nqc0 ) * desca( mb_ ) ) +
300 $ desca( mb_ ) * desca( mb_ )
303 work( 1 ) = dble( lwmin )
304 lquery = ( lwork.EQ.-1 )
305 IF( .NOT.left .AND. .NOT.lsame( side,
'R' ) )
THEN
307 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'T' ) )
THEN
309 ELSE IF( k.LT.0 .OR. k.GT.nq )
THEN
311 ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) )
THEN
313 ELSE IF( left .AND. icoffa.NE.iroffc )
THEN
315 ELSE IF( .NOT.left .AND. icoffa.NE.icoffc )
THEN
317 ELSE IF( .NOT.left .AND. iacol.NE.iccol )
THEN
319 ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) )
THEN
321 ELSE IF( ictxt.NE.descc( ctxt_ ) )
THEN
323 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
328 idum1( 1 ) = ichar(
'L' )
330 idum1( 1 ) = ichar(
'R' )
334 idum1( 2 ) = ichar(
'N' )
336 idum1( 2 ) = ichar( 't
' )
341.EQ.
IF( LWORK-1 ) THEN
348 CALL PCHK2MAT( K, 5, M, 3, IA, JA, DESCA, 9, M, 3, N, 4, IC,
349 $ JC, DESCC, 14, 4, IDUM1, IDUM2, INFO )
351 CALL PCHK2MAT( K, 5, N, 4, IA, JA, DESCA, 9, M, 3, N, 4, IC,
352 $ JC, DESCC, 14, 4, IDUM1, IDUM2, INFO )
357 CALL PXERBLA( ICTXT, 'pdormlq', -INFO )
359 ELSE IF( LQUERY ) THEN
365.EQ..OR..EQ..OR..EQ.
IF( M0 N0 K0 )
368 CALL PB_TOPGET( ICTXT, 'broadcast
', 'rowwise
', ROWBTOP )
369 CALL PB_TOPGET( ICTXT, 'broadcast
', 'columnwise
', COLBTOP )
371.AND..OR.
IF( ( LEFT NOTRAN )
372.NOT..AND..NOT.
$ ( LEFT NOTRAN ) ) THEN
373 I1 = MIN( ICEIL( IA, DESCA( MB_ ) ) * DESCA( MB_ ), IA+K-1 )
378 I1 = MAX( ( (IA+K-2) / DESCA( MB_ ) ) * DESCA( MB_ ) + 1, IA )
379 I2 = MIN( ICEIL( IA, DESCA( MB_ ) ) * DESCA( MB_ ), IA+K-1 )
390 CALL PB_TOPSET( ICTXT, 'broadcast
', 'rowwise
', ' ' )
392 CALL PB_TOPSET( ICTXT, 'broadcast
', 'columnwise
', 'd-ring
' )
394 CALL PB_TOPSET( ICTXT, 'broadcast
', 'columnwise',
'I-ring' )
404 IF( ( left .AND. notran ) .OR. ( .NOT.left .AND. .NOT.notran ) )
405 $
CALL pdorml2( side, trans, m, n, i1-ia, a, ia, ja, desca, tau,
406 $ c, ic, jc, descc, work, lwork, iinfo )
408 ipw = desca( mb_ ) * desca( mb_ ) + 1
410 ib =
min( desca( mb_ ), k-i+ia )
415 CALL pdlarft(
'Forward',
'Rowwise', nq-i+ia, ib, a, i, ja+i-ia,
416 $ desca, tau, work, work( ipw ) )
433 CALL pdlarfb( side, transt,
'Forward',
'Rowwise', mi, ni, ib,
434 $ a, i, ja+i-ia, desca, work, c, icc, jcc, descc,
438 IF( ( left .AND. .NOT.notran ) .OR. ( .NOT.left .AND. notran ) )
439 $
CALL pdorml2( side, trans, m, n, i2-ia, a, ia, ja, desca, tau,
440 $ c, ic, jc, descc, work, lwork, iinfo )
442 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise', rowbtop )
443 CALL pb_topset( ictxt, 'broadcast
', 'columnwise
', COLBTOP )
445 WORK( 1 ) = DBLE( LWMIN )