1 SUBROUTINE pcunmql( 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 COMPLEX A( * ), C( * ), TAU( * ), WORK( * )
219 INTEGER BLOCK_CYCLIC_2D, , CTXT_, , DTYPE_,
220 $ lld_, mb_, m_, nb_, n_, rsrc_
221 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
226 LOGICAL LEFT, LQUERY, NOTRAN
228INTEGER IAROW, ICCOL, ICOFFC, ICROW, ICTXT, IINFO, IPW,
229 $ iroffa, iroffc, j, j1, j2, j3, jb, lcm, lcmq,
234 INTEGER IDUM1( 4 ), IDUM2( 4 )
242 INTEGER ICEIL, ILCM, INDXG2P, NUMROC
243 EXTERNAL iceil, ilcm, indxg2p
252 ictxt = desca( ctxt_ )
258 IF( nprow.EQ.-1 )
THEN
261 left =
lsame( side,
'L' )
262 notran =
lsame( trans,
'N' )
268 CALL chk1mat( m, 3, k, 5, ia, ja, desca, 9, info )
275 iroffa = mod( ia-1, desca( mb_ ) )
276 iroffc = mod( ic-1, descc( mb_ ) )
277 icoffc = mod( jc-1, descc( nb_ ) )
278 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
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
288 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) ) / 2,
289 $ ( mpc0 + nqc0 ) * desca( nb_ ) ) +
290 $ desca( nb_ ) * desca( nb_ )
292 npa0 = numroc( n+iroffa, desca( mb_ ), myrow, iarow,
294 lcm = ilcm( nprow, npcol )
296 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
297 $ / 2, ( nqc0 +
max( npa0 + numroc( numroc(
298 $ n+icoffc, desca( nb_ ), 0, 0, npcol ),
299 $ desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
300 $ desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
303 work( 1 ) =
cmplx( real( 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,
'C' ) )
THEN
309 ELSE IF( k.LT.0 .OR. k.GT.nq )
THEN
311 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) )
THEN
313 ELSE IF( left .AND. iroffa.NE.iroffc )
THEN
315 ELSE IF( left .AND. iarow.NE.icrow )
THEN
317 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc )
THEN
319 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) )
THEN
321 ELSE IF( ictxt.NE.descc( ctxt_ ) )
THEN
323 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
329 idum1( 1 ) = ichar(
'L' )
331 idum1( 1 ) = ichar(
'R' )
335 idum1( 2 ) = ichar(
'N' )
337 idum1( 2 ) = ichar(
'C' )
342 IF( lwork.EQ.-1 )
THEN
349 CALL pchk2mat( m, 3, k, 5, ia, ja, desca, 9, m, 3, n, 4, ic,
350 $ jc, descc, 14, 4, idum1, idum2, info )
352 CALL pchk2mat( n, 4, k, 5, ia, ja, desca, 9, m, 3, n, 4, ic,
353 $ jc, descc, 14, 4, idum1, idum2, info )
358 CALL pxerbla( ictxt,
'PCUNMQL', -info )
360 ELSE IF( lquery )
THEN
366 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
369 CALL pb_topget( ictxt,
'Broadcast', 'rowwise
', ROWBTOP )
370 CALL PB_TOPGET( ICTXT, 'broadcast
', 'columnwise
', COLBTOP )
372.AND..OR.
IF( ( LEFT NOTRAN )
373.NOT..AND..NOT.
$ ( LEFT NOTRAN ) ) THEN
374 J1 = MIN( ICEIL( JA, DESCA( NB_ ) )*DESCA( NB_ ), JA+K-1 ) + 1
378 J1 = MAX( ( (JA+K-2) / DESCA( NB_ ) ) * DESCA( NB_ ) + 1, JA )
379 J2 = MIN( ICEIL( JA, DESCA( NB_ ) )*DESCA( NB_ ), JA+K-1 ) + 1
386 CALL PB_TOPSET( ICTXT, 'broadcast
', 'rowwise
', 'i-ring
' )
388 CALL PB_TOPSET( ICTXT, 'broadcast',
'Rowwise',
'D-ring' )
390 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise',
' ' )
397 IF( ( left .AND. notran ) .OR.
398 $ ( .NOT.left .AND. .NOT.notran ) )
THEN
405 CALL pcunm2l( side, trans, mi, ni, jb, a, ia, ja, desca, tau,
406 $ c, ic, jc, descc, work, lwork, iinfo )
409 ipw = desca( nb_ ) * desca( nb_ ) + 1
411 jb =
min( desca( nb_ ), k-j+ja )
416 CALL pclarft(
'Backward',
'Columnwise', nq-k+j+jb-ja, jb,
417 $ a, ia, j, desca, tau, work, work( ipw ) )
422 mi = m - k + j + jb - ja
427 ni = n - k + j + jb - ja
432 CALL pclarfb( side, trans,
'Backward',
'Columnwise', mi, ni,
433 $ jb, a, ia, j, desca, work, c, ic, jc, descc,
437 IF( ( left .AND. .NOT.notran ) .OR.
438 $ ( .NOT.left .AND. notran ) )
THEN
445 CALL pcunm2l( side, trans, mi, ni, jb, a, ia, ja, desca, tau,
446 $ c, ic, jc, descc, work, lwork, iinfo )
449 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise', rowbtop )
450 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise', colbtop )
452 work( 1 ) =
cmplx( real( lwmin ) )