1 SUBROUTINE psgels( 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 REAL 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 )
235 parameter( zero = 0.0e+0, one = 1.0e+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 REAL ANRM, BIGNUM, BNRM, SMLNUM
247 INTEGER IDUM1( 2 ), IDUM2( 2 )
253 INTEGER INDXG2P, NUMROC
254 REAL PSLANGE, PSLAMCH
255 EXTERNAL ilcm, indxg2p, lsame, numroc, pslange,
264 INTRINSIC ichar,
max,
min, mod, real
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 ) = real( 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,
'PSGELS', -info )
379 ELSE IF( lquery )
THEN
385 IF(
min( m, n, nrhs ).EQ.0 )
THEN
386 CALL pslaset(
'Full',
max( m, n ), nrhs, zero, zero, b,
393 smlnum = pslamch( ictxt,
'S' )
394 smlnum = smlnum / pslamch( ictxt,
'P' )
395 bignum = one / smlnum
396 CALL pslabad( ictxt, smlnum, bignum )
400 anrm = pslange(
'M', m, n, a, ia, ja, desca, rwork )
402 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
406 CALL pslascl(
'G', anrm, smlnum, m, n, a, ia, ja, desca,
409 ELSE IF( anrm.GT.bignum )
THEN
413 CALL pslascl(
'G', anrm, bignum, m, n, a, ia, ja, desca,
416 ELSE IF( anrm.EQ.zero )
THEN
420 CALL pslaset(
'F',
max( m, n ), nrhs, zero, zero, b, ib, jb,
429 bnrm = pslange(
'M', brow, nrhs, b, ib, jb, descb, rwork )
432 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
436 CALL pslascl(
'G', bnrm, smlnum, brow, nrhs, b, ib, jb,
439 ELSE IF( bnrm.GT.bignum )
THEN
443 CALL pslascl(
'G', bnrm, bignum, brow, nrhs, b, ib, jb,
454 CALL psgeqrf( m, n, a, ia, ja, desca, work, work( ipw ),
465 CALL psormqr(
'Left',
'Transpose', m, nrhs, n, a, ia, ja,
466 $ desca, work, b, ib, jb, descb, work( ipw ),
474 CALL pstrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', n,
475 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
485 CALL pstrsm(
'Left',
'Upper',
'Transpose',
'Non-unit', n,
486 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
490 CALL pslaset(
'All', m-n, nrhs, zero, zero, b, ib+n, jb,
496 CALL psormqr(
'Left',
'No transpose', m, nrhs, n, a, ia, ja,
497 $ desca, work, b, ib, jb, descb, work( ipw ),
510 CALL psgelqf( m, n, a, ia, ja, desca, work, work( ipw ),
522 CALL pstrsm(
'Left',
'Lower',
'No transpose',
'Non-unit', m,
523 $ nrhs, one, a, ia, ja, desca, b, ib, jb, descb )
527 CALL pslaset(
'All', n-m, nrhs, zero, zero, b, ib+m, jb,
533 CALL psormlq(
'Left',
'Transpose', n, nrhs, m, a, ia, ja,
534 $ desca, work, b, ib, jb, descb, work( ipw ),
547 CALL psormlq(
'Left',
'No transpose', n, nrhs, m, a, ia, ja,
548 $ desca, work, b, ib, jb, descb, work( ipw ),
556 CALL pstrsm(
'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 pslascl(
'G', anrm, smlnum, scllen, nrhs, b, ib, jb,
570 ELSE IF( iascl.EQ.2 )
THEN
571 CALL pslascl(
'G', anrm, bignum, scllen, nrhs, b, ib, jb,
574 IF( ibscl.EQ.1 )
THEN
575 CALL pslascl(
'G', smlnum, bnrm, scllen, nrhs, b, ib, jb,
577 ELSE IF( ibscl.EQ.2 )
THEN
578 CALL pslascl(
'G', bignum, bnrm, scllen, nrhs, b, ib, jb,
584 work( 1 ) = real( lwmin )