1 SUBROUTINE pdgels( TRANS, M, N, NRHS, A, IA, JA, DESCA, B, IB, JB,
2 $ DESCB, WORK, LWORK, INFO )
11 INTEGER IA, IB, INFO, JA, JB, LWORK, M, N, NRHS
14 INTEGER DESCA( * ), DESCB( * )
15 DOUBLE PRECISION A( * ), B( * ), WORK( * )
229 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
230 $ lld_, mb_, m_, nb_, n_, rsrc_
231 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
232 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
233 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
234 DOUBLE PRECISION ZERO, ONE
235 parameter( zero = 0.0d+0, one = 1.0d+0 )
239 INTEGER BROW, IACOL, IAROW, IASCL, IBCOL, IBROW, IBSCL,
240 $ icoffa, icoffb, ictxt, ipw, iroffa, iroffb,
241 $ lcm, lcmp, ltau, lwf, lwmin, lws, mpa0, mpb0,
242 $ mycol, myrow, npb0, npcol, nprow, nqa0,
244 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
247 INTEGER IDUM1( 2 ), IDUM2( 2 )
248 DOUBLE PRECISION RWORK( 1 )
253 INTEGER INDXG2P, NUMROC
254 DOUBLE PRECISION PDLAMCH, PDLANGE
255 EXTERNAL ilcm, indxg2p, lsame, numroc, pdlamch,
264 INTRINSIC dble, ichar,
max,
min, mod
270 ictxt = desca( ctxt_ )
271 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
276 IF( nprow.EQ.-1 )
THEN
277 info = -( 800 + ctxt_ )
279 CALL chk1mat( m, 2, n, 3, ia, ja, desca, 8, info )
281 CALL chk1mat( m, 2, nrhs, 4, ib, jb, descb, 12, info )
283 CALL chk1mat( n, 3, nrhs, 4, ib, jb, descb, 12, info )
286 iroffa = mod( ia-1, desca( mb_ ) )
287 icoffa = mod( ja-1, desca( nb_ ) )
288 iroffb = mod( ib-1, descb( mb_ ) )
289 icoffb = mod( jb-1, descb( nb_ ) )
290 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
292 iacol = indxg2p( ia, desca( nb_ ), mycol, desca( csrc_ ),
294 mpa0 = numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
295 nqa0 = numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
297 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
299 ibcol = indxg2p( ib, descb( nb_ ), mycol, descb( csrc_ ),
301 nrhsqb0 = numroc( nrhs+icoffb, descb( nb_ ), mycol, ibcol,
304 mpb0 = numroc( m+iroffb, descb( mb_ ), myrow, ibrow,
306 ltau = numroc( ja+
min(m,n)-1, desca( nb_ ), mycol,
307 $ desca( csrc_ ), npcol )
308 lwf = desca( nb_ ) * ( mpa0 + nqa0 + desca( nb_ ) )
309 lws =
max( ( desca( nb_ )*( desca( nb_ ) - 1 ) ) / 2,
310 $ ( mpb0 + nrhsqb0 ) * desca( nb_ ) ) +
311 $ desca( nb_ )*desca( nb_ )
313 lcm = ilcm( nprow, npcol )
315 npb0 = numroc( n+iroffb, descb( mb_ ), myrow, ibrow,
317 ltau = numroc( ia+
min(m,n)-1, desca( mb_ ), myrow,
318 $ desca( rsrc_ ), nprow )
319 lwf = desca( mb_ ) * ( mpa0 + nqa0 + desca( mb_ ) )
320 lws =
max( ( desca( mb_ )*( desca( mb_ ) - 1 ) ) / 2,
321 $ ( npb0 +
max( nqa0 + numroc( numroc( n+iroffb,
322 $ desca( mb_ ), 0, 0, nprow ), desca( mb_ ), 0, 0,
323 $ lcmp ), nrhsqb0 ) )*desca( mb_ ) ) +
324 $ desca( mb_ ) * desca( mb_ )
326 lwmin = ltau +
max( lwf, lws )
327 work( 1 ) = dble( lwmin )
328 lquery = ( lwork.EQ.-1 )
331 IF( lsame( trans,
'N' ) )
334 IF( .NOT.( lsame( trans,
'N' ) .OR.
335 $ lsame( trans,
'T' ) ) )
THEN
337 ELSE IF( m.LT.0 )
THEN
339 ELSE IF( n.LT.0 )
THEN
341 ELSE IF( nrhs.LT.0 )
THEN
343 ELSE IF( m.GE.n .AND. iroffa.NE.iroffb )
THEN
345 ELSE IF( m.GE.n .AND. iarow.NE.ibrow )
THEN
347 ELSE IF( m.LT.n .AND. icoffa.NE.iroffb )
THEN
349 ELSE IF( m.GE.n .AND. desca( mb_ ).NE.descb( mb_ ) )
THEN
350 info = -( 1200 + mb_ )
351 ELSE IF( m.LT.n .AND. desca( nb_ ).NE.descb( mb_ ) )
THEN
352 info = -( 1200 + mb_ )
353 ELSE IF( ictxt.NE.descb( ctxt_ ) )
THEN
354 info = -( 1200 + ctxt_ )
355 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
361 idum1( 1 ) = ichar(
'N' )
363 idum1( 1 ) = ichar(
'T' )
366 IF( lwork.EQ.-1 )
THEN
372 CALL pchk2mat( m, 2, n, 3, ia, ja, desca, 8, n, 3, nrhs, 4,
373 $ ib, jb, descb, 12, 2, idum1, idum2, info )
377 CALL pxerbla( ictxt,
'PDGELS', -info )
379 ELSE IF( lquery )
THEN
385 IF(
min( m, n, nrhs ).EQ.0 )
THEN
386 CALL pdlaset(
'Full',
max( m, n ), nrhs, zero, zero, b,
393 smlnum = pdlamch( ictxt,
'S' )
394 smlnum = smlnum / pdlamch( ictxt,
'P' )
395 bignum = one / smlnum
396 CALL pdlabad( ictxt, smlnum, bignum )
400 anrm = pdlange(
'M', m, n, a, ia, ja, desca, rwork )
402 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
406 CALL pdlascl(
'G', anrm, smlnum, m, n, a, ia, ja, desca,
409 ELSE IF( anrm.GT.bignum )
THEN
413 CALL pdlascl(
'G', anrm, bignum, m, n, a, ia, ja, desca,
416 ELSE IF( anrm.EQ.zero )
THEN
420 CALL pdlaset(
'F',
max( m, n ), nrhs, zero, zero, b, ib, jb,
429 bnrm = pdlange(
'M', brow, nrhs, b, ib, jb, descb, rwork )
432 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
436 CALL pdlascl(
'G', bnrm, smlnum, brow, nrhs, b, ib, jb,
439 ELSE IF( bnrm.GT.bignum )
THEN
443 CALL pdlascl(
'G', bnrm, bignum, brow, nrhs, b, ib, jb,
454 CALL pdgeqrf( m, n, a, ia, ja, desca, work, work( ipw ),
465 CALL pdormqr(
'Left',
'Transpose', m, nrhs, n, a, ia, ja,
466 $ desca, work, b, ib, jb, descb, work( ipw ),
474 CALL pdtrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', n,
475 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
485 CALL pdtrsm(
'Left',
'Upper',
'Transpose',
'Non-unit', n,
486 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
490 CALL pdlaset(
'All', m-n, nrhs, zero, zero, b, ib+n, jb,
496 CALL pdormqr(
'Left',
'No transpose', m, nrhs, n, a, ia, ja,
497 $ desca, work, b, ib, jb, descb, work( ipw ),
510 CALL pdgelqf( m, n, a, ia, ja, desca, work, work( ipw ),
522 CALL pdtrsm(
'Left',
'Lower',
'No transpose',
'Non-unit', m,
523 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
527 CALL pdlaset(
'All', n-m, nrhs, zero, zero, b, ib+m, jb,
533 CALL pdormlq(
'Left',
'Transpose', n, nrhs, m, a, ia, ja,
534 $ desca, work, b, ib, jb, descb, work( ipw ),
547 CALL pdormlq(
'Left',
'No transpose', n, nrhs, m, a, ia, ja,
548 $ desca, work, b, ib, jb, descb, work( ipw ),
556 CALL pdtrsm(
'Left',
'Lower',
'Transpose',
'Non-unit', m,
557 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
567 IF( iascl.EQ.1 )
THEN
568 CALL pdlascl(
'G', anrm, smlnum, scllen, nrhs, b, ib, jb,
570 ELSE IF( iascl.EQ.2 )
THEN
571 CALL pdlascl(
'G', anrm, bignum, scllen, nrhs, b, ib, jb,
574 IF( ibscl.EQ.1 )
THEN
575 CALL pdlascl(
'G', smlnum, bnrm, scllen, nrhs, b, ib, jb,
577 ELSE IF( ibscl.EQ.2 )
THEN
578 CALL pdlascl(
'G', bignum, bnrm, scllen, nrhs, b, ib, jb,
584 work( 1 ) = dble( lwmin )