1 SUBROUTINE pzlarz( SIDE, M, N, L, V, IV, JV, DESCV, INCV, TAU, C,
2 $ IC, JC, DESCC, WORK )
11 INTEGER IC, INCV, IV, JC, JV, L, M, N
14 INTEGER DESCC( * ), DESCV( * )
15 COMPLEX*16 C( * ), TAU( * ), V( * ), WORK( * )
236 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
237 $ lld_, mb_, m_, nb_, n_, rsrc_
238 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
239 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
240 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
242 parameter( one = ( 1.0d+0, 0.0d+0 ),
243 $ zero = ( 0.0d+0, 0.0d+0 ) )
246 LOGICAL CCBLCK, CRBLCK, LEFT
247 CHARACTER COLBTOP, ROWBTOP
248 INTEGER ICCOL1, ICCOL2, ICOFFC1, ICOFFC2, ICOFFV,
249 $ icrow1, icrow2, ictxt, iic1, iic2, iiv, ioffc1,
250 $ ioffc2, ioffv, ipw, iroffc1, iroffc2, iroffv,
251 $ ivcol, ivrow, jjc1, jjc2, jjv, ldc, ldv, mpc2,
252 $ mpv, mycol, myrow, ncc, ncv, npcol, nprow,
258 $ zaxpy, zcopy, zgebr2d, zgebs2d,
259 $ zgemv, zgerc, zgerv2d, zgesd2d,
265 EXTERNAL lsame, numroc
274 IF( m.LE.0 .OR. n.LE.0 )
279 ictxt = descc( ctxt_ )
280 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
284 left = lsame( side,
'L' )
285 CALL infog2l( iv, jv, descv, nprow, npcol, myrow, mycol, iiv, jjv,
287 iroffv = mod( iv-1, descv( nb_ ) )
288 mpv = numroc( l+iroffv, descv( mb_ ), myrow, ivrow, nprow )
291 icoffv = mod( jv-1, descv( nb_ ) )
292 nqv = numroc( l+icoffv, descv( nb_ ), mycol, ivcol, npcol )
296 ncv = numroc( descv( n_ ), descv( nb_ ), mycol, descv( csrc_ ),
299 iiv =
min( iiv, ldv )
300 jjv =
min( jjv, ncv )
301 ioffv = iiv+(jjv-1)*ldv
302 ncc = numroc( descc( n_ ), descc( nb_ ), mycol, descc( csrc_ ),
304 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol,
305 $ iic1, jjc1, icrow1, iccol1 )
306 iroffc1 = mod( ic-1, descc( mb_ ) )
307 icoffc1 = mod( jc-1, descc( nb_ ) )
309 iic1 =
min( iic1, ldc )
310 jjc1 =
min( jjc1,
max( 1, ncc ) )
311 ioffc1 = iic1 + ( jjc1-1 ) * ldc
314 CALL infog2l( ic+m-l, jc, descc, nprow, npcol, myrow, mycol,
315 $ iic2, jjc2, icrow2, iccol2 )
316 iroffc2 = mod( ic+m-l-1, descc( mb_ ) )
317 icoffc2 = mod( jc-1, descc( nb_ ) )
318 nqc2 = numroc( n+icoffc2, descc( nb_ ), mycol, iccol2, npcol )
319 IF( mycol.EQ.iccol2 )
320 $ nqc2 = nqc2 - icoffc2
322 CALL infog2l( ic, jc+n-l, descc, nprow, npcol, myrow, mycol,
323 $ iic2, jjc2, icrow2, iccol2 )
324 iroffc2 = mod( ic-1, descc( mb_ ) )
325 mpc2 = numroc( m+iroffc2, descc( mb_ ), myrow, icrow2, nprow )
326 IF( myrow.EQ.icrow2 )
327 $ mpc2 = mpc2 - iroffc2
328 icoffc2 = mod( jc+n-l-1, descc( nb_ ) )
330 iic2 =
min( iic2, ldc )
331 jjc2 =
min( jjc2, ncc )
332 ioffc2 = iic2 + ( jjc2-1 ) * ldc
336 crblck = ( m.LE.(descc( mb_ )-iroffc1) )
340 ccblck = ( n.LE.(descc( nb_ )-icoffc1) )
354 IF( descv( m_ ).EQ.incv )
THEN
359 CALL pbztrnv( ictxt,
'Rowwise',
'Transpose', m,
360 $ descv( nb_ ), iroffc2, v( ioffv ), ldv,
362 $ work, 1, ivrow, ivcol, icrow2, iccol2,
367 IF( mycol.EQ.iccol2 )
THEN
369 IF( myrow.EQ.ivrow )
THEN
371 CALL zgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
377 CALL zgebr2d( ictxt,
'Columnwise',
' ', 1, 1,
378 $ tauloc, 1, ivrow, mycol )
382 IF( tauloc.NE.zero )
THEN
387 CALL zgemv(
'Conjugate transpose', mpv, nqc2,
388 $ one, c( ioffc2 ), ldc, work, 1,
389 $ zero, work( ipw ), 1 )
391 CALL zlaset(
'All', nqc2, 1, zero, zero,
392 $ work( ipw ),
max( 1, nqc2 ) )
394 IF( myrow.EQ.icrow1 )
395 $
CALL zaxpy( nqc2, one, c( ioffc1 ), ldc,
396 $ work( ipw ),
max( 1, nqc2 ) )
398 CALL zgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
399 $ work( ipw ),
max( 1, nqc2 ), rdest,
404 IF( myrow.EQ.icrow1 )
405 $
CALL zaxpy( nqc2, -tauloc, work( ipw ),
406 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
407 CALL zgerc( mpv, nqc2, -tauloc, work, 1,
408 $ work( ipw ), 1, c( ioffc2 ), ldc )
417 IF( ivcol.EQ.iccol2 )
THEN
421 IF( mycol.EQ.iccol2 )
THEN
425 IF( tauloc.NE.zero )
THEN
430 CALL zgemv(
'Conjugate transpose', mpv, nqc2,
431 $ one, c( ioffc2 ), ldc, v( ioffv ),
434 CALL zlaset(
'All', nqc2, 1, zero, zero,
435 $ work,
max( 1, nqc2 ) )
437 IF( myrow.EQ.icrow1 )
438 $
CALL zaxpy( nqc2, one, c( ioffc1 ), ldc,
439 $ work,
max( 1, nqc2 ) )
441 CALL zgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
442 $ work,
max( 1, nqc2 ), rdest,
447 IF( myrow.EQ.icrow1 )
448 $
CALL zaxpy( nqc2, -tauloc, work,
449 $
max( 1, nqc2 ), c( ioffc1 ),
451 CALL zgerc( mpv, nqc2, -tauloc, v( ioffv ), 1,
452 $ work, 1, c( ioffc2 ), ldc )
461 IF( mycol.EQ.ivcol )
THEN
464 CALL zcopy( mpv, v( ioffv ), 1, work, 1 )
465 work( ipw ) = tau( jjv )
466 CALL zgesd2d( ictxt, ipw, 1, work, ipw, myrow,
469 ELSE IF( mycol.EQ.iccol2 )
THEN
472 CALL zgerv2d( ictxt, ipw, 1, work, ipw, myrow,
476 IF( tauloc.NE.zero )
THEN
481 CALL zgemv(
'Conjugate transpose', mpv, nqc2,
482 $ one, c( ioffc2 ), ldc, work, 1,
483 $ zero, work( ipw ), 1 )
485 CALL zlaset(
'All', nqc2, 1, zero, zero,
486 $ work( ipw ),
max( 1, nqc2 ) )
488 IF( myrow.EQ.icrow1 )
489 $
CALL zaxpy( nqc2, one, c( ioffc1 ), ldc,
490 $ work( ipw ),
max( 1, nqc2 ) )
492 CALL zgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
493 $ work( ipw ),
max( 1, nqc2 ),
498 IF( myrow.EQ.icrow1 )
499 $
CALL zaxpy( nqc2, -tauloc, work( ipw ),
500 $
max( 1, nqc2 ), c( ioffc1 ),
502 CALL zgerc( mpv, nqc2, -tauloc, work, 1,
503 $ work( ipw ), 1, c( ioffc2 ), ldc )
516 IF( descv( m_ ).EQ.incv )
THEN
521 CALL pbztrnv( ictxt,
'Rowwise',
'Transpose', m,
522 $ descv( nb_ ), iroffc2, v( ioffv ), ldv,
524 $ work, 1, ivrow, ivcol, icrow2, -1,
529 IF( myrow.EQ.ivrow )
THEN
531 CALL zgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
537 CALL zgebr2d( ictxt,
'Columnwise',
' ', 1, 1, tauloc,
542 IF( tauloc.NE.zero )
THEN
547 CALL zgemv(
'Conjugate transpose', mpv, nqc2, one,
548 $ c( ioffc2 ), ldc, work, 1, zero,
551 CALL zlaset(
'All', nqc2, 1, zero, zero,
552 $ work( ipw ),
max( 1, nqc2 ) )
554 IF( myrow.EQ.icrow1 )
555 $
CALL zaxpy( nqc2, one, c( ioffc1 ), ldc,
556 $ work( ipw ),
max( 1, nqc2 ) )
558 CALL zgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
559 $ work( ipw ),
max( 1, nqc2 ), rdest,
564 IF( myrow.EQ.icrow1 )
565 $
CALL zaxpy( nqc2, -tauloc, work( ipw ),
566 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
567 CALL zgerc( mpv, nqc2, -tauloc, work, 1, work( ipw ),
568 $ 1, c( ioffc2 ), ldc )
575 CALL pb_topget( ictxt,
'Broadcast',
'Rowwise', rowbtop )
576 IF( mycol.EQ.ivcol )
THEN
579 CALL zcopy( mpv, v( ioffv ), 1, work, 1 )
580 work( ipw ) = tau( jjv )
581 CALL zgebs2d( ictxt,
'Rowwise', rowbtop, ipw, 1,
588 CALL zgebr2d( ictxt,
'Rowwise', rowbtop, ipw, 1, work,
589 $ ipw, myrow, ivcol )
594 IF( tauloc.NE.zero )
THEN
599 CALL zgemv(
'Conjugate transpose', mpv, nqc2, one,
600 $ c( ioffc2 ), ldc, work, 1, zero,
603 CALL zlaset(
'All', nqc2, 1, zero, zero,
604 $ work( ipw ),
max( 1, nqc2 ) )
606 IF( myrow.EQ.icrow1 )
607 $
CALL zaxpy( nqc2, one, c( ioffc1 ), ldc,
608 $ work( ipw ),
max( 1, nqc2 ) )
610 CALL zgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
611 $ work( ipw ),
max( 1, nqc2 ), rdest,
616 IF( myrow.EQ.icrow1 )
617 $
CALL zaxpy( nqc2, -tauloc, work( ipw ),
618 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
619 CALL zgerc( mpv, nqc2, -tauloc, work, 1, work( ipw ),
620 $ 1, c( ioffc2 ), ldc )
639 IF( descv( m_ ).EQ.incv )
THEN
643 IF( ivrow.EQ.icrow2 )
THEN
647 IF( myrow.EQ.icrow2 )
THEN
651 IF( tauloc.NE.zero )
THEN
656 CALL zgemv(
'No transpose', mpc2, nqv, one,
657 $ c( ioffc2 ), ldc, v( ioffv ),
658 $ ldv, zero, work, 1 )
660 CALL zlaset(
'All', mpc2, 1, zero, zero,
661 $ work,
max( 1, mpc2 ) )
663 IF( mycol.EQ.iccol1 )
664 $
CALL zaxpy( mpc2, one, c( ioffc1 ), 1,
667 CALL zgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
668 $ work,
max( 1, mpc2 ), rdest,
671 IF( mycol.EQ.iccol1 )
672 $
CALL zaxpy( mpc2, -tauloc, work, 1,
677 IF( mpc2.GT.0 .AND. nqv.GT.0 )
678 $
CALL zgerc( mpc2, nqv, -tauloc, work, 1,
679 $ v( ioffv ), ldv, c( ioffc2 ),
689 IF( myrow.EQ.ivrow )
THEN
692 CALL zcopy( nqv, v( ioffv ), ldv, work, 1 )
693 work( ipw ) = tau( iiv )
694 CALL zgesd2d( ictxt, ipw, 1, work, ipw, icrow2,
697 ELSE IF( myrow.EQ.icrow2 )
THEN
700 CALL zgerv2d( ictxt, ipw, 1, work, ipw, ivrow,
704 IF( tauloc.NE.zero )
THEN
709 CALL zgemv(
'No transpose', mpc2, nqv, one,
710 $ c( ioffc2 ), ldc, work, 1, zero,
713 CALL zlaset(
'All', mpc2, 1, zero, zero,
714 $ work( ipw ),
max( 1, mpc2 ) )
716 IF( mycol.EQ.iccol1 )
717 $
CALL zaxpy( mpc2, one, c( ioffc1 ), 1,
719 CALL zgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
720 $ work( ipw ),
max( 1, mpc2 ),
722 IF( mycol.EQ.iccol1 )
723 $
CALL zaxpy( mpc2, -tauloc, work( ipw ), 1,
728 CALL zgerc( mpc2, nqv, -tauloc, work( ipw ), 1,
729 $ work, 1, c( ioffc2 ), ldc )
741 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
742 $ descv( mb_ ), icoffc2, v( ioffv ), 1, zero,
743 $ work, 1, ivrow, ivcol, icrow2, iccol2,
748 IF( myrow.EQ.icrow2 )
THEN
750 IF( mycol.EQ.ivcol )
THEN
752 CALL zgebs2d( ictxt,
'Rowwise',
' ', 1, 1,
758 CALL zgebr2d( ictxt,
'Rowwise',
' ', 1, 1, tauloc,
763 IF( tauloc.NE.zero )
THEN
768 CALL zgemv(
'No transpose', mpc2, nqv, one,
769 $ c( ioffc2 ), ldc, work, 1, zero,
772 CALL zlaset(
'All', mpc2, 1, zero, zero,
773 $ work( ipw ),
max( 1, mpc2 ) )
775 IF( mycol.EQ.iccol1 )
776 $
CALL zaxpy( mpc2, one, c( ioffc1 ), 1,
778 CALL zgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
779 $ work( ipw ),
max( 1, mpc2 ), rdest,
781 IF( mycol.EQ.iccol1 )
782 $
CALL zaxpy( mpc2, -tauloc, work( ipw ), 1,
787 CALL zgerc( mpc2, nqv, -tauloc, work( ipw ), 1,
788 $ work, 1, c( ioffc2 ), ldc )
799 IF( descv( m_ ).EQ.incv )
THEN
803 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise',
805 IF( myrow.EQ.ivrow )
THEN
808 CALL zcopy( nqv, v( ioffv ), ldv, work, 1 )
809 work( ipw ) = tau( iiv )
810 CALL zgebs2d( ictxt,
'Columnwise', colbtop, ipw, 1,
817 CALL zgebr2d( ictxt,
'Columnwise', colbtop, ipw, 1,
818 $ work, ipw, ivrow, mycol )
823 IF( tauloc.NE.zero )
THEN
828 CALL zgemv(
'No Transpose', mpc2, nqv, one,
829 $ c( ioffc2 ), ldc, work, 1, zero,
832 CALL zlaset(
'All', mpc2, 1, zero, zero,
833 $ work( ipw ),
max( 1, mpc2 ) )
835 IF( mycol.EQ.iccol1 )
836 $
CALL zaxpy( mpc2, one, c( ioffc1 ), 1,
839 CALL zgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
840 $ work( ipw ),
max( 1, mpc2 ), rdest,
842 IF( mycol.EQ.iccol1 )
843 $
CALL zaxpy( mpc2, -tauloc, work( ipw ), 1,
848 CALL zgerc( mpc2, nqv, -tauloc, work( ipw ), 1, work,
849 $ 1, c( ioffc2 ), ldc )
857 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
858 $ descv( mb_ ), icoffc2, v( ioffv ), 1, zero,
859 $ work, 1, ivrow, ivcol, -1, iccol2,
864 IF( mycol.EQ.ivcol )
THEN
866 CALL zgebs2d( ictxt,
'Rowwise',
' ', 1, 1, tau( jjv ),
872 CALL zgebr2d( ictxt,
'Rowwise',
' ', 1, 1, tauloc, 1,
877 IF( tauloc.NE.zero )
THEN
882 CALL zgemv(
'No transpose', mpc2, nqv, one,
883 $ c( ioffc2 ), ldc, work, 1, zero,
886 CALL zlaset(
'All', mpc2, 1, zero, zero,
887 $ work( ipw ),
max( 1, mpc2 ) )
889 IF( mycol.EQ.iccol1 )
890 $
CALL zaxpy( mpc2, one, c( ioffc1 ), 1,
892 CALL zgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
893 $ work( ipw ),
max( 1, mpc2 ), rdest,
895 IF( mycol.EQ.iccol1 )
896 $
CALL zaxpy( mpc2, -tauloc, work( ipw ), 1,
901 CALL zgerc( mpc2, nqv, -tauloc, work( ipw ), 1, work,
902 $ 1, c( ioffc2 ), ldc )