1 SUBROUTINE pdlarz( 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 DOUBLE PRECISION 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 )
241 DOUBLE PRECISION ONE, ZERO
242 parameter( one = 1.0d+0, zero = 0.0d+0 )
245 LOGICAL CCBLCK, CRBLCK, LEFT
246 CHARACTER COLBTOP, ROWBTOP
247 INTEGER ICCOL1, ICCOL2, ICOFFC1, ICOFFC2, ICOFFV,
248 $ icrow1, icrow2, ictxt, iic1, iic2, iiv, ioffc1,
249 $ ioffc2, ioffv, ipw, iroffc1, iroffc2, iroffv,
250 $ ivcol, ivrow, jjc1, jjc2, jjv, ldc, ldv, mpc2,
251 $ mpv, mycol, myrow, ncc, ncv, npcol, nprow,
253 DOUBLE PRECISION TAULOC
256 EXTERNAL blacs_gridinfo, daxpy, dcopy, dgebr2d,
257 $ dgebs2d, dgemv, dger, dgerv2d,
258 $ dgesd2d, dgsum2d, dlaset,
infog2l,
264 EXTERNAL lsame, numroc
273 IF( m.LE.0 .OR. n.LE.0 )
278 ictxt = descc( ctxt_ )
279 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
283 left = lsame( side,
'L' )
284 CALL infog2l( iv, jv, descv, nprow, npcol, myrow, mycol, iiv, jjv,
286 iroffv = mod( iv-1, descv( nb_ ) )
287 mpv = numroc( l+iroffv, descv( mb_ ), myrow, ivrow, nprow )
290 icoffv = mod( jv-1, descv( nb_ ) )
291 nqv = numroc( l+icoffv, descv( nb_ ), mycol, ivcol, npcol )
295 ncv = numroc( descv( n_ ), descv( nb_ ), mycol, descv( csrc_ ),
298 iiv =
min( iiv, ldv )
299 jjv =
min( jjv, ncv )
300 ioffv = iiv+(jjv-1)*ldv
301 ncc = numroc( descc( n_ ), descc( nb_ ), mycol, descc( csrc_ ),
303 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol,
304 $ iic1, jjc1, icrow1, iccol1 )
305 iroffc1 = mod( ic-1, descc( mb_ ) )
306 icoffc1 = mod( jc-1, descc( nb_ ) )
308 iic1 =
min( iic1, ldc )
309 jjc1 =
min( jjc1,
max( 1, ncc ) )
310 ioffc1 = iic1 + ( jjc1-1 ) * ldc
313 CALL infog2l( ic+m-l, jc, descc, nprow, npcol, myrow, mycol,
314 $ iic2, jjc2, icrow2, iccol2 )
315 iroffc2 = mod( ic+m-l-1, descc( mb_ ) )
316 icoffc2 = mod( jc-1, descc( nb_ ) )
317 nqc2 = numroc( n+icoffc2, descc( nb_ ), mycol, iccol2, npcol )
318 IF( mycol.EQ.iccol2 )
319 $ nqc2 = nqc2 - icoffc2
321 CALL infog2l( ic, jc+n-l, descc, nprow, npcol, myrow, mycol,
322 $ iic2, jjc2, icrow2, iccol2 )
323 iroffc2 = mod( ic-1, descc( mb_ ) )
324 mpc2 = numroc( m+iroffc2, descc( mb_ ), myrow, icrow2, nprow )
325 IF( myrow.EQ.icrow2 )
326 $ mpc2 = mpc2 - iroffc2
327 icoffc2 = mod( jc+n-l-1, descc( nb_ ) )
329 iic2 =
min( iic2, ldc )
330 jjc2 =
min( jjc2, ncc )
331 ioffc2 = iic2 + ( jjc2-1 ) * ldc
335 crblck = ( m.LE.(descc( mb_ )-iroffc1) )
339 ccblck = ( n.LE.(descc( nb_ )-icoffc1) )
353 IF( descv( m_ ).EQ.incv )
THEN
358 CALL pbdtrnv( ictxt,
'Rowwise',
'Transpose', m,
359 $ descv( nb_ ), iroffc2, v( ioffv ), ldv,
361 $ work, 1, ivrow, ivcol, icrow2, iccol2,
366 IF( mycol.EQ.iccol2 )
THEN
368 IF( myrow.EQ.ivrow )
THEN
370 CALL dgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
376 CALL dgebr2d( ictxt,
'Columnwise',
' ', 1, 1,
377 $ tauloc, 1, ivrow, mycol )
381 IF( tauloc.NE.zero )
THEN
386 CALL dgemv(
'Transpose', mpv, nqc2, one,
387 $ c( ioffc2 ), ldc, work, 1, zero,
390 CALL dlaset(
'All', nqc2, 1, zero, zero,
391 $ work( ipw ),
max( 1, nqc2 ) )
393 IF( myrow.EQ.icrow1 )
394 $
CALL daxpy( nqc2, one, c( ioffc1 ), ldc,
395 $ work( ipw ),
max( 1, nqc2 ) )
397 CALL dgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
398 $ work( ipw ),
max( 1, nqc2 ), rdest,
403 IF( myrow.EQ.icrow1 )
404 $
CALL daxpy( nqc2, -tauloc, work( ipw ),
405 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
406 CALL dger( mpv, nqc2, -tauloc, work, 1,
407 $ work( ipw ), 1, c( ioffc2 ), ldc )
416 IF( ivcol.EQ.iccol2 )
THEN
420 IF( mycol.EQ.iccol2 )
THEN
424 IF( tauloc.NE.zero )
THEN
429 CALL dgemv(
'Transpose', mpv, nqc2, one,
430 $ c( ioffc2 ), ldc, v( ioffv ), 1,
433 CALL dlaset(
'All', nqc2, 1, zero, zero,
434 $ work,
max( 1, nqc2 ) )
436 IF( myrow.EQ.icrow1 )
437 $
CALL daxpy( nqc2, one, c( ioffc1 ), ldc,
438 $ work,
max( 1, nqc2 ) )
440 CALL dgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
441 $ work,
max( 1, nqc2 ), rdest,
446 IF( myrow.EQ.icrow1 )
447 $
CALL daxpy( nqc2, -tauloc, work,
448 $
max( 1, nqc2 ), c( ioffc1 ),
450 CALL dger( mpv, nqc2, -tauloc, v( ioffv ), 1,
451 $ work, 1, c( ioffc2 ), ldc )
460 IF( mycol.EQ.ivcol )
THEN
463 CALL dcopy( mpv, v( ioffv ), 1, work, 1 )
464 work( ipw ) = tau( jjv )
465 CALL dgesd2d( ictxt, ipw, 1, work, ipw, myrow,
468 ELSE IF( mycol.EQ.iccol2 )
THEN
471 CALL dgerv2d( ictxt, ipw, 1, work, ipw, myrow,
475 IF( tauloc.NE.zero )
THEN
480 CALL dgemv(
'Transpose', mpv, nqc2, one,
481 $ c( ioffc2 ), ldc, work, 1, zero,
484 CALL dlaset(
'All', nqc2, 1, zero, zero,
485 $ work( ipw ),
max( 1, nqc2 ) )
487 IF( myrow.EQ.icrow1 )
488 $
CALL daxpy( nqc2, one, c( ioffc1 ), ldc,
489 $ work( ipw ),
max( 1, nqc2 ) )
491 CALL dgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
492 $ work( ipw ),
max( 1, nqc2 ),
497 IF( myrow.EQ.icrow1 )
498 $
CALL daxpy( nqc2, -tauloc, work( ipw ),
499 $
max( 1, nqc2 ), c( ioffc1 ),
501 CALL dger( mpv, nqc2, -tauloc, work, 1,
502 $ work( ipw ), 1, c( ioffc2 ), ldc )
515 IF( descv( m_ ).EQ.incv )
THEN
520 CALL pbdtrnv( ictxt,
'Rowwise',
'Transpose', m,
521 $ descv( nb_ ), iroffc2, v( ioffv ), ldv,
523 $ work, 1, ivrow, ivcol, icrow2, -1,
528 IF( myrow.EQ.ivrow )
THEN
530 CALL dgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
536 CALL dgebr2d( ictxt,
'Columnwise',
' ', 1, 1, tauloc,
541 IF( tauloc.NE.zero )
THEN
546 CALL dgemv(
'Transpose', mpv, nqc2, one,
547 $ c( ioffc2 ), ldc, work, 1, zero,
550 CALL dlaset(
'All', nqc2, 1, zero, zero,
551 $ work( ipw ),
max( 1, nqc2 ) )
553 IF( myrow.EQ.icrow1 )
554 $
CALL daxpy( nqc2, one, c( ioffc1 ), ldc,
555 $ work( ipw ),
max( 1, nqc2 ) )
557 CALL dgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
558 $ work( ipw ),
max( 1, nqc2 ), rdest,
563 IF( myrow.EQ.icrow1 )
564 $
CALL daxpy( nqc2, -tauloc, work( ipw ),
565 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
566 CALL dger( mpv, nqc2, -tauloc, work, 1, work( ipw ),
567 $ 1, c( ioffc2 ), ldc )
574 CALL pb_topget( ictxt,
'Broadcast',
'Rowwise', rowbtop )
575 IF( mycol.EQ.ivcol )
THEN
578 CALL dcopy( mpv, v( ioffv ), 1, work, 1 )
579 work( ipw ) = tau( jjv )
580 CALL dgebs2d( ictxt,
'Rowwise', rowbtop, ipw, 1,
587 CALL dgebr2d( ictxt,
'Rowwise', rowbtop, ipw, 1, work,
588 $ ipw, myrow, ivcol )
593 IF( tauloc.NE.zero )
THEN
598 CALL dgemv(
'Transpose', mpv, nqc2, one,
599 $ c( ioffc2 ), ldc, work, 1, zero,
602 CALL dlaset(
'All', nqc2, 1, zero, zero,
603 $ work( ipw ),
max( 1, nqc2 ) )
605 IF( myrow.EQ.icrow1 )
606 $
CALL daxpy( nqc2, one, c( ioffc1 ), ldc,
607 $ work( ipw ),
max( 1, nqc2 ) )
609 CALL dgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
610 $ work( ipw ),
max( 1, nqc2 ), rdest,
615 IF( myrow.EQ.icrow1 )
616 $
CALL daxpy( nqc2, -tauloc, work( ipw ),
617 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
618 CALL dger( mpv, nqc2, -tauloc, work, 1, work( ipw ),
619 $ 1, c( ioffc2 ), ldc )
638 IF( descv( m_ ).EQ.incv )
THEN
642 IF( ivrow.EQ.icrow2 )
THEN
646 IF( myrow.EQ.icrow2 )
THEN
650 IF( tauloc.NE.zero )
THEN
655 CALL dgemv(
'No transpose', mpc2, nqv, one,
656 $ c( ioffc2 ), ldc, v( ioffv ),
657 $ ldv, zero, work, 1 )
659 CALL dlaset(
'All', mpc2, 1, zero, zero,
660 $ work,
max( 1, mpc2 ) )
662 IF( mycol.EQ.iccol1 )
663 $
CALL daxpy( mpc2, one, c( ioffc1 ), 1,
666 CALL dgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
667 $ work,
max( 1, mpc2 ), rdest,
670 IF( mycol.EQ.iccol1 )
671 $
CALL daxpy( mpc2, -tauloc, work, 1,
676 IF( mpc2.GT.0 .AND. nqv.GT.0 )
677 $
CALL dger( mpc2, nqv, -tauloc, work, 1,
678 $ v( ioffv ), ldv, c( ioffc2 ),
688 IF( myrow.EQ.ivrow )
THEN
691 CALL dcopy( nqv, v( ioffv ), ldv, work, 1 )
692 work( ipw ) = tau( iiv )
693 CALL dgesd2d( ictxt, ipw, 1, work, ipw, icrow2,
696 ELSE IF( myrow.EQ.icrow2 )
THEN
699 CALL dgerv2d( ictxt, ipw, 1, work, ipw, ivrow,
703 IF( tauloc.NE.zero )
THEN
708 CALL dgemv(
'No transpose', mpc2, nqv, one,
709 $ c( ioffc2 ), ldc, work, 1, zero,
712 CALL dlaset(
'All', mpc2, 1, zero, zero,
713 $ work( ipw ),
max( 1, mpc2 ) )
715 IF( mycol.EQ.iccol1 )
716 $
CALL daxpy( mpc2, one, c( ioffc1 ), 1,
718 CALL dgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
719 $ work( ipw ),
max( 1, mpc2 ),
721 IF( mycol.EQ.iccol1 )
722 $
CALL daxpy( mpc2, -tauloc, work( ipw ), 1,
727 CALL dger( mpc2, nqv, -tauloc, work( ipw ), 1,
728 $ work, 1, c( ioffc2 ), ldc )
740 CALL pbdtrnv( ictxt,
'Columnwise',
'Transpose', n,
741 $ descv( mb_ ), icoffc2, v( ioffv ), 1, zero,
742 $ work, 1, ivrow, ivcol, icrow2, iccol2,
747 IF( myrow.EQ.icrow2 )
THEN
749 IF( mycol.EQ.ivcol )
THEN
751 CALL dgebs2d( ictxt,
'Rowwise',
' ', 1, 1,
757 CALL dgebr2d( ictxt,
'Rowwise',
' ', 1, 1, tauloc,
762 IF( tauloc.NE.zero )
THEN
767 CALL dgemv(
'No transpose', mpc2, nqv, one,
768 $ c( ioffc2 ), ldc, work, 1, zero,
771 CALL dlaset(
'All', mpc2, 1, zero, zero,
772 $ work( ipw ),
max( 1, mpc2 ) )
774 IF( mycol.EQ.iccol1 )
775 $
CALL daxpy( mpc2, one, c( ioffc1 ), 1,
777 CALL dgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
778 $ work( ipw ),
max( 1, mpc2 ), rdest,
780 IF( mycol.EQ.iccol1 )
781 $
CALL daxpy( mpc2, -tauloc, work( ipw ), 1,
786 CALL dger( mpc2, nqv, -tauloc, work( ipw ), 1,
787 $ work, 1, c( ioffc2 ), ldc )
798 IF( descv( m_ ).EQ.incv )
THEN
802 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise',
804 IF( myrow.EQ.ivrow )
THEN
807 CALL dcopy( nqv, v( ioffv ), ldv, work, 1 )
808 work( ipw ) = tau( iiv )
809 CALL dgebs2d( ictxt,
'Columnwise', colbtop, ipw, 1,
816 CALL dgebr2d( ictxt,
'Columnwise', colbtop, ipw, 1,
817 $ work, ipw, ivrow, mycol )
822 IF( tauloc.NE.zero )
THEN
827 CALL dgemv(
'No Transpose', mpc2, nqv, one,
828 $ c( ioffc2 ), ldc, work, 1, zero,
831 CALL dlaset(
'All', mpc2, 1, zero, zero,
832 $ work( ipw ),
max( 1, mpc2 ) )
834 IF( mycol.EQ.iccol1 )
835 $
CALL daxpy( mpc2, one, c( ioffc1 ), 1,
838 CALL dgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
839 $ work( ipw ),
max( 1, mpc2 ), rdest,
841 IF( mycol.EQ.iccol1 )
842 $
CALL daxpy( mpc2, -tauloc, work( ipw ), 1,
847 CALL dger( mpc2, nqv, -tauloc, work( ipw ), 1, work,
848 $ 1, c( ioffc2 ), ldc )
856 CALL pbdtrnv( ictxt,
'Columnwise',
'Transpose', n,
857 $ descv( mb_ ), icoffc2, v( ioffv ), 1, zero,
858 $ work, 1, ivrow, ivcol, -1, iccol2,
863 IF( mycol.EQ.ivcol )
THEN
865 CALL dgebs2d( ictxt,
'Rowwise',
' ', 1, 1, tau( jjv ),
871 CALL dgebr2d( ictxt,
'Rowwise',
' ', 1, 1, tauloc, 1,
876 IF( tauloc.NE.zero )
THEN
881 CALL dgemv(
'No transpose', mpc2, nqv, one,
882 $ c( ioffc2 ), ldc, work, 1, zero,
885 CALL dlaset(
'All', mpc2, 1, zero, zero,
886 $ work( ipw ),
max( 1, mpc2 ) )
888 IF( mycol.EQ.iccol1 )
889 $
CALL daxpy( mpc2, one, c( ioffc1 ), 1,
891 CALL dgsum2d( ictxt,
'Rowwise',
' ', mpc2, 1,
892 $ work( ipw ),
max( 1, mpc2 ), rdest,
894 IF( mycol.EQ.iccol1 )
895 $
CALL daxpy( mpc2, -tauloc, work( ipw ), 1,
900 CALL dger( mpc2, nqv, -tauloc, work( ipw ), 1, work,
901 $ 1, c( ioffc2 ), ldc )