1 SUBROUTINE pbctrnv( ICONTXT, XDIST, TRANS, N, NB, NZ, X, INCX,
2 $ BETA, Y, INCY, IXROW, IXCOL, IYROW, IYCOL,
14 CHARACTER*1 TRANS, XDIST
15 INTEGER ICONTXT, INCX, INCY, IXCOL, IXROW, IYCOL,
20 COMPLEX WORK( * ), X( * ), Y( * )
170 PARAMETER ( ONE = ( 1.0e+0, 0.0e+0 ),
171 $ zero = ( 0.0e+0, 0.0e+0 ) )
174 LOGICAL COLFORM, ROWFORM
175 INTEGER I, IDEX, IGD, INFO, JDEX, JYCOL, JYROW, JZ, KZ,
176 $ lcm, lcmp, lcmq, mccol, mcrow, mrcol, mrrow,
177 $ mycol, myrow, nn, np, np0, np1, npcol, nprow,
183 INTEGER ILCM, ICEIL, NUMROC
184 EXTERNAL lsame, ilcm, iceil, numroc
187 EXTERNAL blacs_gridinfo, cgebr2d, cgebs2d, cgerv2d,
200 CALL blacs_gridinfo( icontxt, nprow, npcol, myrow, mycol )
202 colform = lsame( xdist,
'C' )
203 rowform = lsame( xdist,
'R' )
208 IF( ( .NOT.colform ) .AND. ( .NOT.rowform ) )
THEN
210 ELSE IF( n .LT.0 )
THEN
212 ELSE IF( nb .LT.1 )
THEN
214 ELSE IF( nz .LT.0 .OR. nz.GE.nb )
THEN
216 ELSE IF( incx.EQ.0 )
THEN
218 ELSE IF( incy.EQ.0 )
THEN
220 ELSE IF( ixrow.LT.-1 .OR. ixrow.GE.nprow .OR.
221 $ ( ixrow.EQ.-1 .AND. colform ) )
THEN
223 ELSE IF( ixcol.LT.-1 .OR. ixcol.GE.npcol .OR.
224 $ ( ixcol.EQ.-1 .AND. rowform ) )
THEN
226 ELSE IF( iyrow.LT.-1 .OR. iyrow.GE.nprow .OR.
227 $ ( iyrow.EQ.-1 .AND. rowform ) )
THEN
229 ELSE IF( iycol.LT.-1 .OR. iycol.GE.npcol .OR.
230 $ ( iycol.EQ.-1 .AND. colform ) )
THEN
236 CALL pxerbla( icontxt,
'PBCTRNV ', info )
244 lcm = ilcm( nprow, npcol )
264 IF( ixrow.LT.0 .OR. ixrow.GE.nprow )
THEN
266 ELSE IF( ixcol.LT.-1 .OR. ixcol.GE.npcol )
THEN
268 ELSE IF( iyrow.LT.-1 .OR. iyrow.GE.nprow )
THEN
270 ELSE IF( iycol.LT.0 .OR. iycol.GE.npcol )
THEN
273 IF( info.NE.0 )
GO TO 10
278 mrrow = mod( nprow+myrow-ixrow, nprow )
279 mrcol = mod( npcol+mycol-iycol, npcol )
281 IF( iyrow.EQ.-1 ) jyrow = ixrow
283 np = numroc( nn, nb, myrow, ixrow, nprow )
284 IF( mrrow.EQ.0 ) np = np - nz
285 nq = numroc( nn, nb, mycol, iycol, npcol )
286 IF( mrcol.EQ.0 ) nq = nq - nz
287 nq0 = numroc( numroc(nn, nb, 0, 0, npcol), nb, 0, 0, lcmq )
291 IF( ixcol .GE. 0 )
THEN
293 IF( myrow.EQ.jyrow ) tbeta = beta
296 DO 20 i = 0,
min( lcm, iceil(nn,nb) ) - 1
297 mcrow = mod( mod(i, nprow) + ixrow, nprow )
298 mccol = mod( mod(i, npcol) + iycol, npcol )
299 IF( lcmq.EQ.1 ) nq0 = numroc( nn, nb, i, 0, npcol )
300 jdex = (i/npcol) * nb
301 IF( mrcol.EQ.0 ) jdex =
max(0, jdex-nz)
305 IF( myrow.EQ.mcrow .AND. mycol.EQ.ixcol )
THEN
309 idex = (i/nprow) * nb
310 IF( mrrow.EQ.0 ) idex =
max( 0, idex-nz )
311 IF( myrow.EQ.jyrow .AND. mycol.EQ.mccol )
THEN
312 CALL pbctr2b1( icontxt, trans, np-idex, nb, kz,
313 $ x(idex*incx+1), incx, tbeta,
314 $ y(jdex*incy+1), incy, lcmp, lcmq )
319 CALL pbctr2b1( icontxt, trans, np-idex, nb, kz,
320 $ x(idex*incx+1), incx, zero, work, 1,
322 CALL cgesd2d( icontxt, 1, nq0-kz, work, 1,
328 ELSE IF( myrow.EQ.jyrow .AND. mycol.EQ.mccol )
THEN
329 IF( lcmq.EQ.1 .AND. tbeta.EQ.zero )
THEN
330 CALL cgerv2d( icontxt, 1, nq0-kz, y, incy,
333 CALL cgerv2d( icontxt, 1, nq0-kz, work, 1,
335 CALL pbctr2a1( icontxt, nq-jdex, nb, kz, work, 1, tbeta,
336 $ y(jdex*incy+1), incy, lcmq*nb )
344 IF( iyrow.EQ.-1 )
THEN
345 IF( myrow.EQ.jyrow )
THEN
346 CALL cgebs2d( icontxt,
'Col',
'1-tree', 1, nq, y, incy )
348 CALL cgebr2d( icontxt,
'Col',
'1-tree', 1, nq, y, incy,
356 IF( lcmq.EQ.1 ) nq0 = nq
362 IF( mrrow.EQ.0 ) kz = nz
364 IF( mrrow.EQ.0 .AND. mycol.EQ.iycol ) jz = nz
366 DO 30 i = 0, lcmp - 1
367 IF( mrcol.EQ.mod(nprow*i+mrrow, npcol) )
THEN
368 idex =
max( 0, i*nb-kz )
369 IF( lcmq.EQ.1 .AND. (iyrow.EQ.-1.OR.iyrow.EQ.myrow) )
THEN
370 CALL pbctr2b1( icontxt, trans, np-idex, nb, jz,
371 $ x(idex*incx+1), incx, beta, y, incy,
374 CALL pbctr2b1( icontxt, trans, np-idex, nb, jz,
375 $ x(idex*incx+1), incx, zero, work, 1,
383 mcrow = mod( mod(mrcol, nprow) + ixrow, nprow )
385 mccol = mod( npcol+mycol-iycol, npcol )
386 CALL pbctrget( icontxt,
'Row', 1, nq0, iceil( nn, nb ),
387 $ work, 1, mcrow, mccol, igd, myrow, mycol,
393 IF( iyrow.EQ.-1 )
THEN
394 IF( myrow.EQ.mcrow )
THEN
397 IF( mycol.EQ.iycol ) kz = nz
398 CALL pbctrst1( icontxt,
'Row', nq, nb, kz, work, 1,
399 $ beta, y, incy, lcmp, lcmq, nq0 )
401 CALL cgebs2d( icontxt,
'Col',
'1-tree', 1, nq, y, incy )
403 CALL cgebr2d( icontxt,
'Col',
'1-tree', 1, nq, y, incy,
411 IF( myrow.EQ.mcrow )
THEN
413 $
CALL cgesd2d( icontxt, 1, nq0, work, 1, iyrow, mycol )
414 ELSE IF( myrow.EQ.iyrow )
THEN
415 IF( beta.EQ.zero )
THEN
416 CALL cgerv2d( icontxt, 1, nq0, y, incy, mcrow, mycol )
418 CALL cgerv2d( icontxt, 1, nq0, work, 1, mcrow, mycol )
419 CALL pbcvecadd( icontxt,
'G', nq0, one, work, 1,
425 nq1 = nq0 *
min( lcmq,
max( 0, iceil(nn,nb)-mccol ) )
426 IF( myrow.EQ.mcrow )
THEN
428 $
CALL cgesd2d( icontxt, 1, nq1, work, 1, iyrow, mycol )
429 ELSE IF( myrow.EQ.iyrow )
THEN
430 CALL cgerv2d( icontxt, 1, nq1, work, 1, mcrow, mycol )
433 IF( myrow.EQ.iyrow )
THEN
435 IF( mycol.EQ.iycol ) kz = nz
436 CALL pbctrst1( icontxt,
'Row', nq, nb, kz, work, 1,
437 $ beta, y, incy, lcmp, lcmq, nq0 )
457 IF( ixrow.LT.-1 .OR. ixrow.GE.nprow )
THEN
459 ELSE IF( ixcol.LT.0 .OR. ixcol.GE.npcol )
THEN
461 ELSE IF( iyrow.LT.0 .OR. iyrow.GE.nprow )
THEN
463 ELSE IF( iycol.LT.-1 .OR. iycol.GE.npcol )
THEN
466 IF( info.NE.0 )
GO TO 10
471 mrrow = mod( nprow+myrow-iyrow, nprow )
472 mrcol = mod( npcol+mycol-ixcol, npcol )
474 IF( iycol.EQ.-1 ) jycol = ixcol
476 np = numroc( nn, nb, myrow, iyrow, nprow )
477 IF( mrrow.EQ.0 ) np = np - nz
478 nq = numroc( nn, nb, mycol, ixcol, npcol )
479 IF( mrcol.EQ.0 ) nq = nq - nz
480 np0 = numroc( numroc(nn, nb, 0, 0, nprow), nb, 0, 0, lcmp )
484 IF( ixrow .GE. 0 )
THEN
486 IF( mycol.EQ.jycol ) tbeta = beta
489 DO 40 i = 0,
min( lcm, iceil(nn,nb) ) - 1
490 mcrow = mod( mod(i, nprow) + iyrow, nprow )
491 mccol = mod( mod(i, npcol) + ixcol, npcol )
492 IF( lcmp.EQ.1 ) np0 = numroc( nn, nb, i, 0, nprow )
493 jdex = (i/nprow) * nb
494 IF( mrrow.EQ.0 ) jdex =
max(0, jdex-nz)
498 IF( myrow.EQ.ixrow .AND. mycol.EQ.mccol )
THEN
502 idex = (i/npcol) * nb
503 IF( mrcol.EQ.0 ) idex =
max( 0, idex-nz )
504 IF( myrow.EQ.mcrow .AND. mycol.EQ.jycol )
THEN
505 CALL pbctr2b1( icontxt, trans, nq-idex, nb, kz,
506 $ x(idex*incx+1), incx, tbeta,
507 $ y(jdex*incy+1), incy, lcmq, lcmp )
512 CALL pbctr2b1( icontxt, trans, nq-idex, nb, kz,
513 $ x(idex*incx+1), incx, zero, work, 1,
515 CALL cgesd2d( icontxt, 1, np0-kz, work, 1,
521 ELSE IF( myrow.EQ.mcrow .AND. mycol.EQ.jycol )
THEN
522 IF( lcmp.EQ.1 .AND. tbeta.EQ.zero )
THEN
523 CALL cgerv2d( icontxt, 1, np0-kz, y, incy,
526 CALL cgerv2d( icontxt, 1, np0-kz, work, 1,
528 CALL pbctr2a1( icontxt, np-jdex, nb, kz, work, 1, tbeta,
529 $ y(jdex*incy+1), incy, lcmp*nb )
537 IF( iycol.EQ.-1 )
THEN
538 IF( mycol.EQ.jycol )
THEN
539 CALL cgebs2d( icontxt,
'Row',
'1-tree', 1, np, y, incy )
541 CALL cgebr2d( icontxt,
'Row',
'1-tree', 1, np, y, incy,
549 IF( lcmp.EQ.1 ) np0 = np
555 IF( mrcol.EQ.0 ) kz = nz
557 IF( mrcol.EQ.0 .AND. myrow.EQ.iyrow ) jz = nz
560 IF( mrrow.EQ.mod(npcol*i+mrcol, nprow) )
THEN
561 idex =
max( 0, i*nb-kz )
562 IF( lcmp.EQ.1 .AND. (iycol.EQ.-1.OR.iycol.EQ.mycol) )
THEN
563 CALL pbctr2b1( icontxt, trans, nq-idex, nb, jz,
564 $ x(idex*incx+1), incx, beta, y, incy,
567 CALL pbctr2b1( icontxt, trans, nq-idex, nb, jz,
568 $ x(idex*incx+1), incx, zero, work, 1,
576 mccol = mod( mod(mrrow, npcol) + ixcol, npcol )
578 mcrow = mod( nprow+myrow-iyrow, nprow )
579 CALL pbctrget( icontxt,
'Col', 1, np0, iceil( nn, nb ),
580 $ work, 1, mcrow, mccol, igd, myrow, mycol,
586 IF( iycol.EQ.-1 )
THEN
587 IF( mycol.EQ.mccol )
THEN
590 IF( myrow.EQ.iyrow ) kz = nz
591 CALL pbctrst1( icontxt,
'Col', np, nb, kz, work, 1,
592 $ beta, y, incy, lcmp, lcmq, np0 )
594 CALL cgebs2d( icontxt,
'Row',
'1-tree', 1, np, y, incy )
596 CALL cgebr2d( icontxt,
'Row',
'1-tree', 1, np, y, incy,
604 IF( mycol.EQ.mccol )
THEN
606 $
CALL cgesd2d( icontxt, 1, np, work, 1, myrow, iycol )
607 ELSE IF( mycol.EQ.iycol )
THEN
608 IF( beta.EQ.zero )
THEN
609 CALL cgerv2d( icontxt, 1, np, y, incy, myrow, mccol )
611 CALL cgerv2d( icontxt, 1, np, work, 1, myrow, mccol )
612 CALL pbcvecadd( icontxt,
'G', np, one, work, 1, beta,
618 np1 = np0 *
min( lcmp,
max( 0, iceil(nn,nb)-mcrow ) )
619 IF( mycol.EQ.mccol )
THEN
621 $
CALL cgesd2d( icontxt, 1, np1, work, 1, myrow, iycol )
622 ELSE IF( mycol.EQ.iycol )
THEN
623 CALL cgerv2d( icontxt, 1, np1, work, 1, myrow, mccol )
626 IF( mycol.EQ.iycol )
THEN
628 IF( myrow.EQ.iyrow ) kz = nz
629 CALL pbctrst1( icontxt,
'Col', np, nb, kz, work, 1,
630 $ beta, y, incy, lcmp, lcmq, np0 )
647 SUBROUTINE pbctr2a1( ICONTXT, N, NB, NZ, X, INCX, BETA, Y, INCY,
655 INTEGER ICONTXT, N, NB, NZ, INCX, INCY, INTV
659 COMPLEX X( * ), Y( * )
681 PARAMETER ( ONE = ( 1.0e+0, 0.0e+0 ) )
684 INTEGER IX, IY, JZ, K, ITER
689 iter = iceil( n+nz, intv )
692 CALL pbcvecadd( icontxt,
'G', nb-jz, one, x(ix*incx+1), incx,
693 $ beta, y(iy*incy+1), incy )
699 CALL pbcvecadd( icontxt,
'G', nb, one, x(ix*incx+1), incx,
700 $ beta, y(iy*incy+1), incy )
707 $ x(ix*incx+1), incx, beta, y(iy*incy+1), incy )
719 SUBROUTINE pbctr2b1( ICONTXT, TRANS, N, NB, NZ, X, INCX, BETA, Y,
728 INTEGER ICONTXT, N, NB, NZ, INCX, INCY, JINX, JINY
732 COMPLEX X( * ), Y( * )
754 parameter( one = ( 1.0e+0, 0.0e+0 ) )
757 INTEGER IX, IY, JZ, K, ITER, LENX, LENY
759 IF( jinx.EQ.1 .AND. jiny.EQ.1 )
THEN
760 CALL pbcvecadd( icontxt, trans, n, one, x, incx, beta,
769 iter = iceil( n+nz, lenx )
772 CALL pbcvecadd( icontxt, trans, nb-jz, one, x(ix*incx+1),
773 $ incx, beta, y(iy*incy+1), incy )
779 CALL pbcvecadd( icontxt, trans, nb, one, x(ix*incx+1),
780 $ incx, beta, y(iy*incy+1), incy )
786 CALL pbcvecadd( icontxt, trans,
min( n-ix, nb-jz ), one,
787 $ x(ix*incx+1), incx, beta, y(iy*incy+1), incy )