1 SUBROUTINE 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, IDEX, 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
197 EXTERNAL blacs_gridinfo, dgebr2d, dgebs2d, dgerv2d,
208 IF( m.EQ.0 .OR. n.EQ.0 )
RETURN
210 CALL blacs_gridinfo( icontxt, nprow, npcol, myrow, mycol )
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,
331 $ tbeta, c(1,jdex+1), ldc, lcmp, lcmq,
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', np, m, c, ldc )
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 IF( iccol.EQ.-1 )
THEN
556 IF( mycol.EQ.mccol )
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 IF( mycol.EQ.mccol )
THEN
572 $
CALL dgesd2d( icontxt, np, m, work, np, myrow, iccol )
573 ELSE IF( mycol.EQ.iccol )
THEN
574 IF( beta.EQ.zero )
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 IF( mycol.EQ.mccol )
THEN
587 $
CALL dgesd2d( icontxt, np0, ml, work, np0,
589 ELSE IF( mycol.EQ.iccol )
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 )
613 SUBROUTINE pbdtr2at( ICONTXT, ADIST, TRANS, M, N, NB, A, LDA,
614 $ BETA, B, LDB, LCMP, LCMQ )
621 CHARACTER*1 ADIST, TRANS
622 INTEGER ICONTXT, LCMP, LCMQ, LDA, LDB, M, N, NB
623 DOUBLE PRECISION BETA
626 DOUBLE PRECISION A( LDA, * ), B( LDB, * )
640 PARAMETER ( ONE = 1.0d+0 )
643 INTEGER IA, IB, K, INTV, JNTV
651 EXTERNAL lsame, iceil
658 IF( lcmp.EQ.lcmq )
THEN
659 CALL pbdmatadd( icontxt, trans, n, m, one, a, lda, beta, b,
666 IF( lsame( adist,
'C' ) )
THEN
671 DO 10 k = 1, iceil( m, intv )
673 $ one, a(ia,1), lda, beta, b(1,ib), ldb )
685 DO 20 k = 1, iceil( n, jntv )
687 $ one, a(1,ia), lda, beta, b(ib,1), ldb )
704 SUBROUTINE pbdtr2bt( ICONTXT, ADIST, TRANS, M, N, NB, A, LDA,
705 $ BETA, B, LDB, INTV )
712 CHARACTER*1 ADIST, TRANS
713 INTEGER ICONTXT, INTV, LDA, LDB, M, N, NB
714 DOUBLE PRECISION BETA
717 DOUBLE PRECISION A( LDA, * ), B( LDB, * )
731 PARAMETER ( ONE = 1.0d+0 )
739 EXTERNAL LSAME, ICEIL
749 IF( intv.EQ.nb )
THEN
750 CALL pbdmatadd( icontxt, trans, n, m, one, a, lda, beta, b,
757 IF( lsame( adist,
'C' ) )
THEN
760 DO 10 k = 1, iceil( m, intv )
762 $ one, a(ia,1), lda, beta, b(1,ib), ldb )
772 DO 20 k = 1, iceil( n, intv )
774 $ one, a(1,ia), lda, beta, b(ib,1), ldb )
791 SUBROUTINE pbdtr2af( ICONTXT, ADIST, M, N, NB, A, LDA, BETA, B,
792 $ LDB, LCMP, LCMQ, NINT )
800 INTEGER ICONTXT, M, N, NB, LDA, LDB, LCMP, LCMQ, NINT
801 DOUBLE PRECISION BETA
804 DOUBLE PRECISION A( LDA, * ), B( LDB, * )
817 PARAMETER ( ONE = 1.0d+0 )
820 INTEGER JA, JB, K, INTV
825 EXTERNAL LSAME, ICEIL
832 IF( lsame( adist,
'R' ) )
THEN
836 DO 10 k = 1, iceil( nint, nb )
837 CALL pbdmatadd( icontxt,
'G', m,
min( n-jb+1, nb ), one,
838 $ a(1,ja), lda, beta, b(1,jb), ldb )
849 DO 20 k = 1, iceil( nint, nb )
850 CALL pbdmatadd( icontxt,
'G',
min( m-jb+1, nb ), n, one,
851 $ a(ja,1), lda, beta, b(jb,1), ldb )