1SUBROUTINE pbdtran( ICONTXT, ADIST, TRANS, M, N, NB, A, LDA, BETA,
2 $ C, LDC, IAROW, IACOL, ICROW, ICCOL, WORK )
13 CHARACTER*1 ADIST, TRANS
14 INTEGER IACOL, IAROW, ICCOL, ICONTXT, ICROW, LDA, LDC,
19 DOUBLE PRECISION A( LDA, * ), C( LDC, * ), WORK( * )
180 DOUBLE PRECISION ONE, ZERO
181 parameter( one = 1.0d+0, zero = 0.0d+0 )
184 LOGICAL COLFORM, ROWFORM
185 INTEGER I, , IGD, INFO, JCCOL, JCROW, JDEX, LCM,
186 $ lcmp, lcmq, mccol, mcrow, ml, mp, mq, mq0,
187 $ mrcol, mrrow, mycol, myrow, np, np0, npcol,
189 DOUBLE PRECISION TBETA
193 INTEGER ILCM, ICEIL, NUMROC
194 EXTERNAL ilcm, iceil, lsame, numroc
208 IF( m.EQ.0 .OR. n.EQ.0 )
RETURN
212 colform = lsame( adist,
'C' )
213 rowform = lsame( adist,
'R' )
218 IF( ( .NOT.colform ) .AND. ( .NOT.rowform ) )
THEN
220 ELSE IF( m .LT.0 )
THEN
222 ELSE IF( n .LT.0 )
THEN
224 ELSE IF( nb.LT.1 )
THEN
226 ELSE IF( iarow.LT.-1 .OR. iarow.GE.nprow .OR.
227 $ ( iarow.EQ.-1 .AND. colform ) )
THEN
229 ELSE IF( iacol.LT.-1 .OR. iacol.GE.npcol .OR.
230 $ ( iacol.EQ.-1 .AND. rowform ) )
THEN
232 ELSE IF( icrow.LT.-1 .OR. icrow.GE.nprow .OR.
233 $ ( icrow.EQ.-1 .AND. rowform ) )
THEN
235 ELSE IF( iccol.LT.-1 .OR. iccol.GE.npcol .OR.
236 $ ( iccol.EQ.-1 .AND. colform ) )
THEN
241 IF( info .NE. 0 )
THEN
242 CALL pxerbla( icontxt,
'PBDTRAN ', info )
250 lcm = ilcm( nprow, npcol )
272 mrrow = mod( nprow+myrow-iarow, nprow )
273 mrcol = mod( npcol+mycol-iccol, npcol )
275 IF( icrow.EQ.-1 ) jcrow = iarow
277 mp = numroc( m, nb, myrow, iarow, nprow )
278 mq = numroc( m, nb, mycol, iccol, npcol )
279 mq0 = numroc( numroc(m, nb, 0, 0, npcol), nb, 0, 0, lcmq )
282 $ ( iacol.EQ.mycol .OR. iacol.EQ.-1 ) )
THEN
284 ELSE IF( ldc.LT.n .AND.
285 $ ( icrow.EQ.myrow .OR. icrow.EQ.-1 ) )
THEN
288 IF( info.NE.0 )
GO TO 10
292 IF( iacol.GE.0 )
THEN
294 IF( myrow.EQ.jcrow ) tbeta = beta
296 DO 20 i = 0,
min( lcm, iceil(m,nb) ) - 1
297 mcrow = mod( mod(i, nprow) + iarow, nprow )
298 mccol = mod( mod(i, npcol) + iccol, npcol )
299 IF( lcmq.EQ.1 ) mq0 = numroc( m, nb, i, 0, npcol )
300 jdex = (i/npcol) * nb
304 IF( myrow.EQ.mcrow .AND. mycol.EQ.iacol )
THEN
308 idex = (i/nprow) * nb
309 IF( myrow.EQ.jcrow .AND. mycol.EQ.mccol )
THEN
310 CALL pbdtr2at( icontxt,
'Col', trans, mp-idex, n, nb,
311 $ a(idex+1,1), lda, tbeta, c(1,jdex+1),
317 CALL pbdtr2bt( icontxt,
'Col', trans, mp-idex, n, nb,
318 $ a(idex+1,1), lda, zero, work, n,
320 CALL dgesd2d( icontxt, n, mq0, work, n, jcrow, mccol )
325 ELSE IF( myrow.EQ.jcrow .AND. mycol.EQ.mccol )
THEN
326 IF( lcmq.EQ.1 .AND. tbeta.EQ.zero )
THEN
327 CALL dgerv2d( icontxt, n, mq0, c, ldc, mcrow, iacol )
329 CALL dgerv2d( icontxt, n, mq0, work, n, mcrow, iacol )
330 CALL pbdtr2af( icontxt,
'Row', n, mq-jdex, nb, work, n,
339 IF( icrow.EQ.-1 )
THEN
340 IF( myrow.EQ.jcrow )
THEN
341 CALL dgebs2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc )
343 CALL dgebr2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc,
351 IF( lcmq.EQ.1 ) mq0 = mq
357 IF( mrcol.EQ.mod( nprow*i+mrrow, npcol ) )
THEN
358 IF( lcmq.EQ.1.AND.(icrow.EQ.-1.OR.icrow.EQ.myrow) )
THEN
359 CALL pbdtr2bt( icontxt,
'Col', trans, mp-i*nb, n, nb,
360 $ a(i*nb+1,1), lda, beta, c, ldc,
363 CALL pbdtr2bt( icontxt,
'Col', trans, mp-i*nb, n, nb,
364 $ a(i*nb+1,1), lda, zero, work, n,
372 mcrow = mod( mod(mrcol,nprow)+iarow, nprow )
374 mccol = mod( npcol+mycol-iccol, npcol )
375 CALL pbdtrget( icontxt,
'Row', n, mq0, iceil(m,nb), work, n,
376 $ mcrow, mccol, igd, myrow, mycol, nprow
382 IF( icrow.EQ.-1 )
THEN
383 IF( myrow.EQ.mcrow )
THEN
385 $
CALL pbdtrsrt( icontxt,
'Row', n, mq, nb, work, n, beta,
386 $ c, ldc, lcmp, lcmq, mq0 )
387 CALL dgebs2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc )
389 CALL dgebr2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc,
397 IF( myrow.EQ.mcrow )
THEN
399 $
CALL dgesd2d( icontxt, n, mq, work, n, icrow, mycol )
400 ELSE IF( myrow.EQ.icrow )
THEN
401 IF( beta.EQ.zero )
THEN
402 CALL dgerv2d( icontxt, n, mq, c, ldc, mcrow, mycol )
404 CALL dgerv2d( icontxt, n, mq, work, n, mcrow, mycol )
405 CALL pbdmatadd( icontxt,
'G', n, mq, one, work, n,
411 ml = mq0 *
min( lcmq,
max(0,iceil(m,nb)-mccol) )
412 IF( myrow.EQ.mcrow )
THEN
414 $
CALL dgesd2d( icontxt, n, ml, work, n, icrow, mycol )
415 ELSE IF( myrow.EQ.icrow )
THEN
416 CALL dgerv2d( icontxt, n, ml, work, n, mcrow, mycol )
420 $
CALL pbdtrsrt( icontxt,
'Row', n, mq, nb, work, n, beta,
421 $ c, ldc, lcmp, lcmq, mq0 )
444 mrrow = mod( nprow+myrow-icrow, nprow )
445 mrcol = mod( npcol+mycol-iacol, npcol )
447 IF( iccol.EQ.-1 ) jccol = iacol
449 np = numroc( n, nb, myrow, icrow, nprow )
450 nq = numroc( n, nb, mycol, iacol, npcol )
451 np0 = numroc( numroc(n, nb, 0, 0, nprow), nb, 0, 0, lcmp )
454 $ ( iarow.EQ.myrow .OR. iarow.EQ.-1 ) )
THEN
456 ELSE IF( ldc.LT.np .AND.
457 $ ( iccol.EQ.mycol .OR. iccol.EQ.-1 ) )
THEN
460 IF( info.NE.0 )
GO TO 10
464 IF( iarow.GE.0 )
THEN
466 IF( mycol.EQ.jccol ) tbeta = beta
468 DO 40 i = 0,
min( lcm, iceil(n,nb) ) - 1
469 mcrow = mod( mod(i, nprow) + icrow, nprow )
470 mccol = mod( mod(i, npcol) + iacol, npcol )
471 IF( lcmp.EQ.1 ) np0 = numroc( n, nb, i, 0, nprow )
472 idex = (i/nprow) * nb
476 IF( myrow.EQ.iarow .AND. mycol.EQ.mccol )
THEN
480 jdex = (i/npcol) * nb
481 IF( myrow.EQ.mcrow .AND. mycol.EQ.jccol )
THEN
482 CALL pbdtr2at( icontxt,
'Row', trans, m, nq-jdex, nb,
483 $ a(1,jdex+1), lda, tbeta, c(idex+1,1),
489 CALL pbdtr2bt( icontxt,
'Row', trans, m, nq-jdex, nb,
490 $ a(1,jdex+1), lda, zero, work, np0,
492 CALL dgesd2d( icontxt, np0, m, work, np0,
498 ELSE IF( myrow.EQ.mcrow .AND. mycol.EQ.jccol )
THEN
499 IF( lcmp.EQ.1 .AND. tbeta.EQ.zero )
THEN
500 CALL dgerv2d( icontxt, np0, m, c, ldc, iarow, mccol )
502 CALL dgerv2d( icontxt, np0, m, work, np0, iarow, mccol )
503 CALL pbdtr2af( icontxt,
'Col', np-idex, m, nb, work,
504 $ np0, tbeta, c(idex+1,1), ldc, lcmp, lcmq,
512 IF( iccol.EQ.-1 )
THEN
513 IF( mycol.EQ.jccol )
THEN
514 CALL dgebs2d( icontxt,
'Row',
'1-tree'
516 CALL dgebr2d( icontxt,
'Row',
'1-tree', np, m, c, ldc,
524 IF( lcmp.EQ.1 ) np0 = np
530 IF( mrrow.EQ.mod(npcol*i+mrcol, nprow) )
THEN
531 IF( lcmp.EQ.1.AND.(iccol.EQ.-1.OR.iccol.EQ.mycol) )
THEN
532 CALL pbdtr2bt( icontxt,
'Row', trans, m, nq-i*nb, nb,
533 $ a(1,i*nb+1), lda, beta, c, ldc,
536 CALL pbdtr2bt( icontxt, 'row
', TRANS, M, NQ-I*NB, NB,
537 $ A(1,I*NB+1), LDA, ZERO, WORK, NP0,
545 MCCOL = MOD( MOD(MRROW, NPCOL)+IACOL, NPCOL )
547 MCROW = MOD( NPROW+MYROW-ICROW, NPROW )
548 CALL PBDTRGET( ICONTXT, 'col
', NP0, M, ICEIL(N,NB), WORK,
549 $ NP0, MCROW, MCCOL, IGD, MYROW, MYCOL, NPROW,
555.EQ.
IF( ICCOL-1 ) THEN
556.EQ.
IF( MYCOLMCCOL ) THEN
558 $ CALL PBDTRSRT( ICONTXT, 'col
', NP, M, NB, WORK, NP0,
559 $ BETA, C, LDC, LCMP, LCMQ, NP0 )
560 CALL DGEBS2D( ICONTXT, 'row
', '1-tree
', NP, M, C, LDC )
562 CALL DGEBR2D( ICONTXT, 'row
', '1-tree
', NP, M, C, LDC,
570.EQ.
IF( MYCOLMCCOL ) THEN
572 $ CALL DGESD2D( ICONTXT, NP, M, WORK, NP, MYROW, ICCOL )
573.EQ.
ELSE IF( MYCOLICCOL ) THEN
574.EQ.
IF( BETAZERO ) THEN
575 CALL DGERV2D( ICONTXT, NP, M, C, LDC, MYROW, MCCOL )
577 CALL DGERV2D( ICONTXT, NP, M, WORK, NP, MYROW, MCCOL )
578 CALL PBDMATADD( ICONTXT, 'g
', NP, M, ONE, WORK, NP,
584 ML = M * MIN( LCMP, MAX( 0, ICEIL(N,NB) - MCROW ) )
585.EQ.
IF( MYCOLMCCOL ) THEN
587 $ CALL DGESD2D( ICONTXT, NP0, ML, WORK, NP0,
589.EQ.
ELSE IF( MYCOLICCOL ) THEN
590 CALL DGERV2D( ICONTXT, NP0, ML, WORK, NP0,
595 $ CALL PBDTRSRT( ICONTXT, 'col
', NP, M, NB, WORK, NP0,
596 $ BETA, C, LDC, LCMP, LCMQ, NP0 )