1 SUBROUTINE pcunmbr( VECT, SIDE, TRANS, M, N, K, A, IA, JA, DESCA,
2 $ TAU, C, IC, JC, DESCC, WORK, LWORK, INFO )
10 CHARACTER SIDE, TRANS, VECT
11 INTEGER IA, IC, INFO, JA, JC, K, LWORK, M, N
14 INTEGER DESCA( * ), DESCC( * )
15 COMPLEX A( * ), C( * ), TAU( * ), WORK( * )
283 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
284 $ lld_, mb_, m_, nb_, n_, rsrc_
285 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
286 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
287 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
290 LOGICAL APPLYQ, LEFT, LQUERY, NOTRAN
292 INTEGER IAA, IACOL, IAROW, ICC, ICCOL, ICOFFA, ICOFFC,
293 $ icrow, ictxt, iinfo, iroffa, iroffc, jaa, jcc,
294 $ lcm, lcmp, lcmq, lwmin, mi, mpc0, mqa0, mycol,
295 $ myrow, ni, npa0, npcol, nprow, nq, nqc0
298 INTEGER IDUM1( 5 ), IDUM2( 5 )
306 INTEGER ILCM, INDXG2P, NUMROC
307 EXTERNAL ilcm, indxg2p, lsame, numroc
310 INTRINSIC cmplx, ichar,
max, mod, real
316 ictxt = desca( ctxt_ )
317 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
322 IF( nprow.EQ.-1 )
THEN
325 applyq = lsame( vect,
'Q' )
326 left = lsame( side,
'L' )
327 notran = lsame( trans,
'N' )
333 IF( ( applyq .AND. nq.GE.k ) .OR.
334 $ ( .NOT.applyq .AND. nq.GT.k ) )
THEN
351 CALL chk1mat( m, 4, k, 6, ia, ja, desca, 10, info )
353 CALL chk1mat( k, 6, m, 4, ia, ja, desca, 10, info )
357 IF( ( applyq .AND. nq.GE.k ) .OR.
358 $ ( .NOT.applyq .AND. nq.GT.k ) )
THEN
375 CALL chk1mat( n, 5, k, 6, ia, ja, desca, 10, info )
377 CALL chk1mat( k, 6, n, 5, ia, ja, desca, 10, info )
380 CALL chk1mat( m, 4, n, 5, ic, jc, descc, 15, info )
383 iroffa = mod( iaa-1, desca( mb_ ) )
384 icoffa = mod( jaa-1, desca( nb_ ) )
385 iroffc = mod( icc-1, descc( mb_ ) )
386 icoffc = mod( jcc-1, descc( nb_ ) )
387 iacol = indxg2p( jaa, desca( nb_ ), mycol, desca( csrc_ ),
389 iarow = indxg2p( iaa, desca( mb_ ), myrow, desca( rsrc_ ),
391 icrow = indxg2p( icc, descc( mb_ ), myrow, descc( rsrc_ ),
393 iccol = indxg2p( jcc, descc( nb_ ), mycol, descc( csrc_ ),
395 mpc0 = numroc( mi+iroffc, descc( mb_ ), myrow, icrow,
397 nqc0 = numroc( ni+icoffc, descc( nb_ ), mycol, iccol,
402 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
403 $ / 2, ( mpc0 + nqc0 ) * desca( nb_ ) ) +
404 $ desca( nb_ ) * desca( nb_ )
406 npa0 = numroc( ni+iroffa, desca( mb_ ), myrow, iarow,
408 lcm = ilcm( nprow, npcol )
410 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
411 $ / 2, ( nqc0 +
max( npa0 + numroc( numroc(
412 $ ni+icoffc, desca( nb_ ), 0, 0, npcol ),
413 $ desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
414 $ desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
419 mqa0 = numroc( mi+icoffa, desca( nb_ ), mycol, iacol,
421 lcm = ilcm( nprow, npcol )
423 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
424 $ / 2, ( mpc0 +
max( mqa0 + numroc( numroc(
425 $ mi+iroffc, desca( mb_ ), 0, 0, nprow ),
426 $ desca( mb_ ), 0, 0, lcmp ), nqc0 ) ) *
427 $ desca( mb_ ) ) + desca( mb_ ) * desca( mb_ )
429 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
430 $ / 2, ( mpc0 + nqc0 ) * desca( mb_ ) ) +
431 $ desca( mb_ ) * desca( mb_ )
436 work( 1 ) =
cmplx( real( lwmin ) )
437 lquery = ( lwork.EQ.-1 )
438 IF( .NOT.applyq .AND. .NOT.lsame( vect,
'P' ) )
THEN
440 ELSE IF( .NOT.left .AND. .NOT.lsame( side,
'R' ) )
THEN
442 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'C' ) )
THEN
444 ELSE IF( k.LT.0 )
THEN
446 ELSE IF( applyq .AND. .NOT.left .AND.
447 $ desca( mb_ ).NE.descc( nb_ ) )
THEN
449 ELSE IF( applyq .AND. left .AND. iroffa.NE.iroffc )
THEN
451 ELSE IF( applyq .AND. left .AND. iarow.NE.icrow )
THEN
453 ELSE IF( .NOT.applyq .AND. left .AND.
454 $ icoffa.NE.iroffc )
THEN
456 ELSE IF( .NOT.applyq .AND. .NOT.left .AND.
457 $ iacol.NE.iccol )
THEN
459 ELSE IF( applyq .AND. .NOT.left .AND.
460 $ iroffa.NE.icoffc )
THEN
462 ELSE IF( .NOT.applyq .AND. .NOT.left .AND.
463 $ icoffa.NE.icoffc )
THEN
465 ELSE IF( applyq .AND. left .AND.
466 $ desca( mb_ ).NE.descc( mb_ ) )
THEN
468 ELSE IF( .NOT.applyq .AND. left .AND.
469 $ desca( mb_ ).NE.descc( mb_ ) )
THEN
471 ELSE IF( applyq .AND. .NOT.left .AND.
472 $ desca( mb_ ).NE.descc( nb_ ) )
THEN
474 ELSE IF( .NOT.applyq .AND. .NOT.left .AND.
475 $ desca( nb_ ).NE.descc( nb_ ) )
THEN
477 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
483 idum1( 1 ) = ichar(
'Q' )
485 idum1( 1 ) = ichar(
'P' )
489 idum1( 2 ) = ichar(
'L' )
491 idum1( 2 ) = ichar(
'R' )
495 idum1( 3 ) = ichar(
'N' )
497 idum1( 3 ) = ichar(
'C' )
502 IF( lwork.EQ.-1 )
THEN
510 CALL pchk2mat( m, 4, k, 6, ia, ja, desca, 10, m, 4, n,
511 $ 5, ic, jc, descc, 15, 5, idum1, idum2,
514 CALL pchk2mat( n, 5, k, 6, ia, ja, desca, 10, m, 4, n,
515 $ 5, ic, jc, descc, 15, 5, idum1, idum2,
520 CALL pchk2mat( k, 6, m, 4, ia, ja, desca, 10, m, 4, n,
521 $ 5, ic, jc, descc, 15, 5, idum1, idum2,
524 CALL pchk2mat( k, 6, n, 5, ia, ja, desca, 10, m, 4, n,
525 $ 5, ic, jc, descc, 15, 5, idum1, idum2,
532 CALL pxerbla( ictxt,
'PCUNMBR', -info )
534 ELSE IF( lquery )
THEN
540 IF( m.EQ.0 .OR. n.EQ.0 )
551 CALL pcunmqr( side, trans, m, n, k, a, ia, ja, desca, tau,
552 $ c, ic, jc, descc, work, lwork, iinfo )
553 ELSE IF( nq.GT.1 )
THEN
557 CALL pcunmqr( side, trans, mi, ni, nq-1, a, ia+1, ja, desca,
558 $ tau, c, icc, jcc, descc, work, lwork, iinfo )
573 CALL pcunmlq( side, transt, m, n, k, a, ia, ja, desca, tau,
574 $ c, ic, jc, descc, work, lwork, iinfo )
575 ELSE IF( nq.GT.1 )
THEN
579 CALL pcunmlq( side, transt, mi, ni, nq-1, a, ia, ja+1,
580 $ desca, tau, c, icc, jcc, descc, work, lwork,
585 work( 1 ) =
cmplx( real( lwmin ) )