1 SUBROUTINE pdormql( 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( * ), C( * ), TAU( * ), WORK( * )
219 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
220 $ lld_, mb_, m_, nb_, n_, rsrc_
221 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
222 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
223 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
226 LOGICAL LEFT, LQUERY, NOTRAN
227 CHARACTER COLBTOP, ROWBTOP
228 INTEGER IAROW, ICCOL, ICOFFC, ICROW, ICTXT, IINFO, IPW,
229 $ iroffa, iroffc, j, j1, j2, j3, jb, lcm, lcmq,
230 $ lwmin, mi, mpc0, mycol, myrow, ni, npa0, npcol,
234 INTEGER IDUM1( 4 ), IDUM2( 4 )
242 INTEGER ICEIL, ILCM, 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( m, 3, k, 5, ia, ja, desca, 9, info )
271 CALL chk1mat( n, 4, k, 5, ia, ja, desca, 9, info )
273 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, 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, npcol )
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 ) = 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( .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(
'T' )
342 IF( lwork.EQ.-1 )
THEN
349 CALL pchk2mat( m, 3, k, 5, ia, ja, desca, 9, m, 3, n, 4, ic,
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,
'PDORMQL', -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 IF( ( left .AND. notran ) .OR.
373 $ ( .NOT.left .AND. .NOT.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 pdorm2l( 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 pdlarft(
'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 pdlarfb( 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 pdorm2l( 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 ) = dble( lwmin )