1 SUBROUTINE pbstran( 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 REAL A( LDA, * ), C( LDC, * ), WORK( * )
180 parameter( one = 1.0e+0, zero = 0.0e+0 )
183 LOGICAL COLFORM, ROWFORM
184 INTEGER I, IDEX, IGD, INFO, JCCOL, JCROW, JDEX, LCM,
185 $ lcmp, lcmq, mccol, mcrow, ml, mp, mq, mq0,
186 $ mrcol, mrrow, mycol, myrow, np, np0, npcol,
192 INTEGER ILCM, ICEIL, NUMROC
193 EXTERNAL ilcm, iceil, lsame, numroc
198 $ sgebs2d, sgerv2d, sgesd2d
207 IF( m.EQ.0 .OR. n.EQ.0 )
RETURN
209 CALL blacs_gridinfo( icontxt, nprow, npcol, myrow, mycol )
211 colform = lsame( adist,
'C' )
212 rowform = lsame( adist,
'R' )
217 IF( ( .NOT.colform ) .AND. ( .NOT.rowform ) )
THEN
219 ELSE IF( m .LT.0 )
THEN
221 ELSE IF( n .LT.0 )
THEN
223 ELSE IF( nb.LT.1 )
THEN
225 ELSE IF( iarow.LT.-1 .OR. iarow.GE.nprow .OR.
226 $ ( iarow.EQ.-1 .AND. colform ) )
THEN
228 ELSE IF( iacol.LT.-1 .OR. iacol.GE.npcol .OR.
229 $ ( iacol.EQ.-1 .AND. rowform ) )
THEN
231 ELSE IF( icrow.LT.-1 .OR. icrow.GE.nprow .OR.
232 $ ( icrow.EQ.-1 .AND. rowform ) )
THEN
234 ELSE IF( iccol.LT.-1 .OR. iccol.GE.npcol .OR.
235 $ ( iccol.EQ.-1 .AND. colform ) )
THEN
240 IF( info .NE. 0 )
THEN
241 CALL pxerbla( icontxt,
'PBSTRAN ', info )
249 lcm = ilcm( nprow, npcol )
271 mrrow = mod( nprow+myrow-iarow, nprow )
272 mrcol = mod( npcol+mycol-iccol, npcol )
274 IF( icrow.EQ.-1 ) jcrow = iarow
276 mp = numroc( m, nb, myrow, iarow, nprow )
277 mq = numroc( m, nb, mycol, iccol, npcol )
278 mq0 = numroc( numroc(m, nb, 0, 0, npcol), nb, 0, 0, lcmq )
281 $ ( iacol.EQ.mycol .OR. iacol.EQ.-1 ) )
THEN
283 ELSE IF( ldc.LT.n .AND.
284 $ ( icrow.EQ.myrow .OR. icrow.EQ.-1 ) )
THEN
287 IF( info.NE.0 )
GO TO 10
291 IF( iacol.GE.0 )
THEN
293 IF( myrow.EQ.jcrow ) tbeta = beta
295 DO 20 i = 0,
min( lcm, iceil(m,nb) ) - 1
296 mcrow = mod( mod(i, nprow) + iarow, nprow )
297 mccol = mod( mod(i, npcol) + iccol, npcol )
298 IF( lcmq.EQ.1 ) mq0 = numroc( m, nb, i, 0, npcol )
299 jdex = (i/npcol) * nb
303 IF( myrow.EQ.mcrow .AND. mycol.EQ.iacol )
THEN
307 idex = (i/nprow) * nb
308 IF( myrow.EQ.jcrow .AND. mycol.EQ.mccol )
THEN
309 CALL pbstr2at( icontxt,
'Col', trans, mp-idex, n, nb,
310 $ a(idex+1,1), lda, tbeta, c(1,jdex+1),
316 CALL pbstr2bt( icontxt,
'Col', trans, mp-idex, n, nb,
317 $ a(idex+1,1), lda, zero, work, n,
319 CALL sgesd2d( icontxt, n, mq0, work, n, jcrow, mccol )
324 ELSE IF( myrow.EQ.jcrow .AND. mycol.EQ.mccol )
THEN
325 IF( lcmq.EQ.1 .AND. tbeta.EQ.zero )
THEN
326 CALL sgerv2d( icontxt, n, mq0, c, ldc, mcrow, iacol )
328 CALL sgerv2d( icontxt, n, mq0, work, n, mcrow, iacol )
329 CALL pbstr2af( icontxt,
'Row', n, mq-jdex, nb, work, n,
330 $ tbeta, c(1,jdex+1), ldc, lcmp, lcmq,
338 IF( icrow.EQ.-1 )
THEN
339 IF( myrow.EQ.jcrow )
THEN
340 CALL sgebs2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc )
342 CALL sgebr2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc,
350 IF( lcmq.EQ.1 ) mq0 = mq
356 IF( mrcol.EQ.mod( nprow*i+mrrow, npcol ) )
THEN
357 IF( lcmq.EQ.1.AND.(icrow.EQ.-1.OR.icrow.EQ.myrow) )
THEN
358 CALL pbstr2bt( icontxt,
'Col', trans, mp-i*nb, n, nb,
359 $ a(i*nb+1,1), lda, beta, c, ldc,
362 CALL pbstr2bt( icontxt,
'Col', trans, mp-i*nb, n, nb,
363 $ a(i*nb+1,1), lda, zero, work, n,
371 mcrow = mod( mod(mrcol,nprow)+iarow, nprow )
373 mccol = mod( npcol+mycol-iccol, npcol )
374 CALL pbstrget( icontxt,
'Row', n, mq0, iceil(m,nb), work, n,
375 $ mcrow, mccol, igd, myrow, mycol, nprow,
381 IF( icrow.EQ.-1 )
THEN
382 IF( myrow.EQ.mcrow )
THEN
384 $
CALL pbstrsrt( icontxt,
'Row', n, mq, nb, work, n, beta,
385 $ c, ldc, lcmp, lcmq, mq0 )
386 CALL sgebs2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc )
388 CALL sgebr2d( icontxt,
'Col',
'1-tree', n, mq, c, ldc,
396 IF( myrow.EQ.mcrow )
THEN
398 $
CALL sgesd2d( icontxt, n, mq, work, n, icrow, mycol )
399 ELSE IF( myrow.EQ.icrow )
THEN
400 IF( beta.EQ.zero )
THEN
401 CALL sgerv2d( icontxt, n, mq, c, ldc, mcrow, mycol )
403 CALL sgerv2d( icontxt, n, mq, work, n, mcrow, mycol )
404 CALL pbsmatadd( icontxt,
'G', n, mq, one, work, n,
410 ml = mq0 *
min( lcmq,
max(0,iceil(m,nb)-mccol) )
411 IF( myrow.EQ.mcrow )
THEN
413 $
CALL sgesd2d( icontxt, n, ml, work, n, icrow, mycol )
414 ELSE IF( myrow.EQ.icrow )
THEN
415 CALL sgerv2d( icontxt, n, ml, work, n, mcrow, mycol )
419 $
CALL pbstrsrt( icontxt,
'Row', n, mq, nb, work, n, beta,
420 $ c, ldc, lcmp, lcmq, mq0 )
443 mrrow = mod( nprow+myrow-icrow, nprow )
444 mrcol = mod( npcol+mycol-iacol, npcol )
446 IF( iccol.EQ.-1 ) jccol = iacol
448 np = numroc( n, nb, myrow, icrow, nprow )
449 nq = numroc( n, nb, mycol, iacol, npcol )
450 np0 = numroc( numroc(n, nb, 0, 0, nprow), nb, 0, 0, lcmp )
453 $ ( iarow.EQ.myrow .OR. iarow.EQ.-1 ) )
THEN
455 ELSE IF( ldc.LT.np .AND.
456 $ ( iccol.EQ.mycol .OR. iccol.EQ.-1 ) )
THEN
459 IF( info.NE.0 )
GO TO 10
463 IF( iarow.GE.0 )
THEN
465 IF( mycol.EQ.jccol ) tbeta = beta
467 DO 40 i = 0,
min( lcm, iceil(n,nb) ) - 1
468 mcrow = mod( mod(i, nprow) + icrow, nprow )
469 mccol = mod( mod(i, npcol) + iacol, npcol )
470 IF( lcmp.EQ.1 ) np0 = numroc( n, nb, i, 0, nprow )
471 idex = (i/nprow) * nb
475 IF( myrow.EQ.iarow .AND. mycol.EQ.mccol )
THEN
479 jdex = (i/npcol) * nb
480 IF( myrow.EQ.mcrow .AND. mycol.EQ.jccol )
THEN
481 CALL pbstr2at( icontxt,
'Row', trans, m, nq-jdex, nb,
482 $ a(1,jdex+1), lda, tbeta, c(idex+1,1),
488 CALL pbstr2bt( icontxt,
'Row', trans, m, nq-jdex, nb,
489 $ a(1,jdex+1), lda, zero, work, np0,
491 CALL sgesd2d( icontxt, np0, m, work, np0,
497 ELSE IF( myrow.EQ.mcrow .AND. mycol.EQ.jccol )
THEN
498 IF( lcmp.EQ.1 .AND. tbeta.EQ.zero )
THEN
499 CALL sgerv2d( icontxt, np0, m, c, ldc, iarow, mccol )
501 CALL sgerv2d( icontxt, np0, m, work, np0, iarow, mccol )
502 CALL pbstr2af( icontxt,
'Col', np-idex, m, nb, work,
503 $ np0, tbeta, c(idex+1,1), ldc, lcmp, lcmq,
511 IF( iccol.EQ.-1 )
THEN
512 IF( mycol.EQ.jccol )
THEN
513 CALL sgebs2d( icontxt,
'Row',
'1-tree', np, m, c, ldc )
515 CALL sgebr2d( icontxt,
'Row',
'1-tree', np, m, c, ldc,
523 IF( lcmp.EQ.1 ) np0 = np
529 IF( mrrow.EQ.mod(npcol*i+mrcol, nprow) )
THEN
530 IF( lcmp.EQ.1.AND.(iccol.EQ.-1.OR.iccol.EQ.mycol) )
THEN
531 CALL pbstr2bt( icontxt,
'Row', trans, m, nq-i*nb, nb,
532 $ a(1,i*nb+1), lda, beta, c, ldc,
535 CALL pbstr2bt( icontxt,
'Row', trans, m, nq-i*nb, nb,
536 $ a(1,i*nb+1), lda, zero, work, np0,
544 mccol = mod( mod(mrrow, npcol)+iacol, npcol )
546 mcrow = mod( nprow+myrow-icrow, nprow )
547 CALL pbstrget( icontxt,
'Col', np0, m, iceil(n,nb), work,
548 $ np0, mcrow, mccol, igd, myrow, mycol, nprow,
554 IF( iccol.EQ.-1 )
THEN
555 IF( mycol.EQ.mccol )
THEN
557 $
CALL pbstrsrt( icontxt,
'Col', np, m, nb, work, np0,
558 $ beta, c, ldc, lcmp, lcmq, np0 )
559 CALL sgebs2d( icontxt,
'Row',
'1-tree', np, m, c, ldc )
561 CALL sgebr2d( icontxt,
'Row',
'1-tree', np, m, c, ldc,
569 IF( mycol.EQ.mccol )
THEN
571 $
CALL sgesd2d( icontxt, np, m, work, np, myrow, iccol )
572 ELSE IF( mycol.EQ.iccol )
THEN
573 IF( beta.EQ.zero )
THEN
574 CALL sgerv2d( icontxt, np, m, c, ldc, myrow, mccol )
576 CALL sgerv2d( icontxt, np, m, work, np, myrow, mccol )
577 CALL pbsmatadd( icontxt,
'G', np, m, one, work, np,
583 ml = m *
min( lcmp,
max( 0, iceil(n,nb) - mcrow ) )
584 IF( mycol.EQ.mccol )
THEN
586 $
CALL sgesd2d( icontxt, np0, ml, work, np0,
588 ELSE IF( mycol.EQ.iccol )
THEN
589 CALL sgerv2d( icontxt, np0, ml, work, np0,
594 $
CALL pbstrsrt( icontxt,
'Col', np, m, nb, work, np0,
595 $ beta, c, ldc, lcmp, lcmq, np0 )
612 SUBROUTINE pbstr2at( ICONTXT, ADIST, TRANS, M, N, NB, A, LDA,
613 $ BETA, B, LDB, LCMP, LCMQ )
620 CHARACTER*1 ADIST, TRANS
621 INTEGER ICONTXT, LCMP, LCMQ, LDA, LDB, M, N, NB
625 REAL A( LDA, * ), B( LDB, * )
639 PARAMETER ( ONE = 1.0e+0 )
642 INTEGER IA, IB, K, INTV, JNTV
650 EXTERNAL lsame, iceil
657 IF( lcmp.EQ.lcmq )
THEN
658 CALL pbsmatadd( icontxt, trans, n, m, one, a, lda, beta, b,
665 IF( lsame( adist,
'C' ) )
THEN
670 DO 10 k = 1, iceil( m, intv )
672 $ one, a(ia,1), lda, beta, b(1,ib), ldb )
684 DO 20 k = 1, iceil( n, jntv )
686 $ one, a(1,ia), lda, beta, b(ib,1), ldb )
703 SUBROUTINE pbstr2bt( ICONTXT, ADIST, TRANS, M, N, NB, A, LDA,
704 $ BETA, B, LDB, INTV )
711 CHARACTER*1 ADIST, TRANS
712 INTEGER ICONTXT, INTV, LDA, LDB, M, N, NB
716 REAL A( LDA, * ), B( LDB, * )
730 PARAMETER ( ONE = 1.0e+0 )
738 EXTERNAL LSAME, ICEIL
748 IF( intv.EQ.nb )
THEN
749 CALL pbsmatadd( icontxt, trans, n, m, one, a, lda, beta, b,
756 IF( lsame( adist,
'C' ) )
THEN
759 DO 10 k = 1, iceil( m, intv )
761 $ one, a(ia,1), lda, beta, b(1,ib), ldb )
771 DO 20 k = 1, iceil( n, intv )
773 $ one, a(1,ia), lda, beta, b(ib,1), ldb )
790 SUBROUTINE pbstr2af( ICONTXT, ADIST, M, N, NB, A, LDA, BETA, B,
791 $ LDB, LCMP, LCMQ, NINT )
799 INTEGER ICONTXT, M, N, NB, LDA, LDB, LCMP, LCMQ, NINT
803 REAL A( LDA, * ), B( LDB, * )
816 PARAMETER ( ONE = 1.0e+0 )
819 INTEGER JA, JB, K, INTV
824 EXTERNAL LSAME, ICEIL
831 IF( lsame( adist,
'R' ) )
THEN
835 DO 10 k = 1, iceil( nint, nb )
836 CALL pbsmatadd( icontxt,
'G', m,
min( n-jb+1, nb ), one,
837 $ a(1,ja), lda, beta, b(1,jb), ldb )
848 DO 20 k = 1, iceil( nint, nb )
849 CALL pbsmatadd( icontxt,
'G',
min( m-jb+1, nb ), n, one,
850 $ a(ja,1), lda, beta, b(jb,1), ldb )