1 SUBROUTINE pzunmrz( SIDE, TRANS, M, N, K, L, A, IA, JA, DESCA,
2 $ TAU, C, IC, JC, DESCC, WORK, LWORK, INFO )
11 INTEGER IA, IC, INFO, JA, JC, K, L, LWORK, M, N
14 INTEGER DESCA( * ), DESCC( * )
15 COMPLEX*16 A( * ), C( * ), TAU( * ), WORK( * )
224 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
225 $ lld_, mb_, m_, nb_, n_, rsrc_
226 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
227 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
228 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
231 LOGICAL LEFT, LQUERY, NOTRAN
232 CHARACTER COLBTOP, ROWBTOP, TRANST
233 INTEGER I, I1, I2, I3, IACOL, IB, ICC, ICCOL, ICOFFA,
234 $ icoffc, icrow, ictxt, iinfo, ipw, iroffc, jaa,
235 $ jcc, lcm, lcmp, lwmin, mi, mpc0, mqa0, mycol,
236 $ myrow, ni, npcol, nprow, nq, nqc0
239 INTEGER IDUM1( 5 ), IDUM2( 5 )
248 INTEGER ICEIL, ILCM, INDXG2P, NUMROC
249 EXTERNAL iceil, ilcm, indxg2p, lsame, numroc
252 INTRINSIC dble, dcmplx, ichar,
max,
min, mod
258 ictxt = desca( ctxt_ )
259 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
264 IF( nprow.EQ.-1 )
THEN
267 left = lsame( side,
'L' )
268 notran = lsame( trans,
'N' )
274 CALL chk1mat( k, 5, m, 3, ia, ja, desca, 10, info )
277 CALL chk1mat( k, 5, n, 4, ia, ja, desca, 10, info )
279 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 15, info )
281 icoffa = mod( ja-1, desca( nb_ ) )
282 iroffc = mod( ic-1, descc( mb_ ) )
283 icoffc = mod( jc-1, descc( nb_ ) )
284 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
286 icrow = indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
288 iccol = indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
290 mpc0 = numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
291 nqc0 = numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
294 mqa0 = numroc( m+icoffa, desca( nb_ ), mycol, iacol,
296 lcm = ilcm( nprow, npcol )
298 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
299 $ / 2, ( mpc0 +
max( mqa0 + numroc( numroc(
300 $ m+iroffc, desca( mb_ ), 0, 0, nprow ),
301 $ desca( mb_ ), 0, 0, lcmp ), nqc0 ) ) *
302 $ desca( mb_ ) ) + desca( mb_ ) * desca( mb_ )
304 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) ) / 2,
305 $ ( mpc0 + nqc0 ) * desca( mb_ ) ) +
306 $ desca( mb_ ) * desca( mb_ )
309 work( 1 ) = dcmplx( dble( lwmin ) )
310 lquery = ( lwork.EQ.-1 )
311 IF( .NOT.left .AND. .NOT.lsame( side,
'R' ) )
THEN
313 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans,
'C' ) )
THEN
315 ELSE IF( k.LT.0 .OR. k.GT.nq )
THEN
317 ELSE IF( k.LT.0 .OR. k.GT.nq )
THEN
319 ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) )
THEN
321 ELSE IF( left .AND. icoffa.NE.iroffc )
THEN
323 ELSE IF( .NOT.left .AND. icoffa.NE.icoffc )
THEN
325 ELSE IF( .NOT.left .AND. iacol.NE.iccol )
THEN
327 ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) )
THEN
329 ELSE IF( ictxt.NE.descc( ctxt_ ) )
THEN
331 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
336 idum1( 1 ) = ichar(
'L' )
338 idum1( 1 ) = ichar(
'R' )
342 idum1( 2 ) = ichar(
'N' )
344 idum1( 2 ) = ichar(
'C' )
351 IF( lwork.EQ.-1 )
THEN
358 CALL pchk2mat( k, 5, m, 3, ia, ja, desca, 10, m, 3, n, 4,
359 $ ic, jc, descc, 15, 5, idum1, idum2, info )
361 CALL pchk2mat( k, 5, n, 4, ia, ja, desca, 10, m, 3, n, 4,
362 $ ic, jc, descc, 15, 5, idum1, idum2, info )
367 CALL pxerbla( ictxt,
'PZUNMRZ', -info )
369 ELSE IF( lquery )
THEN
375 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
378 CALL pb_topget( ictxt,
'Broadcast',
'Rowwise', rowbtop )
379 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise', colbtop )
381 IF( ( left .AND. .NOT.notran ) .OR.
382 $ ( .NOT.left .AND. notran ) )
THEN
383 i1 =
min( iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
388 i1 =
max( ( (ia+k-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
389 i2 =
min( iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
402 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise',
' ' )
404 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise',
'I-ring' )
406 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise',
'D-ring' )
416 IF( ( left .AND. .NOT.notran ) .OR.
417 $ ( .NOT.left .AND. notran ) )
THEN
424 CALL pzunmr3( side, trans, mi, ni, ib, l, a, ia, ja, desca,
425 $ tau, c, ic, jc, descc, work, lwork, iinfo )
428 ipw = desca( mb_ )*desca( mb_ ) + 1
430 ib =
min( desca( mb_ ), k-i+ia )
435 CALL pzlarzt(
'Backward',
'Rowwise', l, ib, a, i, jaa, desca,
436 $ tau, work, work( ipw ) )
453 CALL pzlarzb( side, transt,
'Backward',
'Rowwise', mi, ni, ib,
454 $ l, a, i, jaa, desca, work, c, icc, jcc, descc,
458 IF( ( left .AND. .NOT.notran ) .OR.
459 $ ( .NOT.left .AND. notran ) )
THEN
466 CALL pzunmr3( side, trans, mi, ni, ib, l, a, ia, ja, desca,
467 $ tau, c, ic, jc, descc, work, lwork, iinfo )
470 CALL pb_topset( ictxt,
'Broadcast',
'Rowwise', rowbtop )
471 CALL pb_topset( ictxt,
'Broadcast',
'Columnwise', colbtop )
473 work( 1 ) = dcmplx( dble( lwmin ) )