1 SUBROUTINE pslarz( 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 REAL 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 )
245 LOGICAL , 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,
264 EXTERNAL lsame, numroc
273 IF( m.LE.0 .OR. n.LE.0 )
278 ictxt = descc( ctxt_ )
283 left = lsame( side,
'L' )
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 pbstrnv( 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 sgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
372 tauloc( 1 ) = tau( iiv )
376 CALL sgebr2d( ictxt,
'Columnwise',
' ', 1, 1,
377 $ tauloc, 1, ivrow, mycol )
381 IF( tauloc( 1 ).NE.zero )
THEN
386 CALL sgemv(
'Transpose', mpv, nqc2, one,
387 $ c( ioffc2 ), ldc, work, 1, zero,
390 CALL slaset(
'All', nqc2, 1, zero, zero,
391 $ work( ipw ),
max( 1, nqc2 ) )
393 IF( myrow.EQ.icrow1 )
394 $
CALL saxpy( nqc2, one, c( ioffc1 ), ldc,
395 $ work( ipw ),
max( 1, nqc2 ) )
397 CALL sgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
398 $ work( ipw ),
max( 1, nqc2 ), rdest,
403 IF( myrow.EQ.icrow1 )
404 $
CALL saxpy( nqc2, -tauloc( 1 ), work( ipw ),
405 $
max( 1, nqc2 ), c( ioffc1 ), ldc )
406 CALL sger( mpv, nqc2, -tauloc( 1 ), work, 1,
407 $ work( ipw ), 1, c( ioffc2 ), ldc )
416 IF( ivcol.EQ.iccol2 )
THEN
420 IF( mycol.EQ.iccol2 )
THEN
422 tauloc( 1 ) = tau( jjv )
424 IF( tauloc( 1 ).NE.zero )
THEN
429 CALL sgemv(
'Transpose', mpv, nqc2, one,
430 $ c( ioffc2 ), ldc, v( ioffv ), 1,
433 CALL slaset(
'All', nqc2, 1, zero, zero,
434 $ work,
max( 1, nqc2 ) )
436 IF( myrow.EQ.icrow1 )
437 $
CALL saxpy( nqc2, one, c( ioffc1 ), ldc,
438 $ work,
max( 1, nqc2 ) )
440 CALL sgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
441 $ work,
max( 1, nqc2 ), rdest,
446 IF( myrow.EQ.icrow1 )
447 $
CALL saxpy( nqc2, -tauloc( 1 ), work,
448 $
max( 1, nqc2 ), c( ioffc1 ),
450 CALL sger( mpv, nqc2, -tauloc( 1 ), v( ioffv ),
451 $ 1, work, 1, c( ioffc2 ), ldc )
460 IF( mycol.EQ.ivcol )
THEN
463 CALL scopy( mpv, v( ioffv ), 1, work, 1 )
464 work( ipw ) = tau( jjv )
465 CALL sgesd2d( ictxt, ipw, 1, work, ipw, myrow,
468 ELSE IF( mycol.EQ.iccol2 )
THEN
471 CALL sgerv2d( ictxt, ipw, 1, work, ipw, myrow,
473 tauloc( 1 ) = work( ipw )
475 IF( tauloc( 1 ).NE.zero )
THEN
480 CALL sgemv(
'Transpose', mpv, nqc2, one,
481 $ c( ioffc2 ), ldc, work, 1, zero,
484 CALL slaset(
'All', nqc2, 1, zero, zero,
485 $ work( ipw ),
max( 1, nqc2 ) )
487 IF( myrow.EQ.icrow1 )
488 $
CALL saxpy( nqc2, one, c( ioffc1 ), ldc,
489 $ work( ipw ),
max( 1, nqc2 ) )
491 CALL sgsum2d( ictxt,
'Columnwise',
' ', nqc2, 1,
492 $ work( ipw ),
max( 1, nqc2 ),
497 IF( myrow.EQ.icrow1 )
498 $
CALL saxpy( nqc2, -tauloc( 1 ), work( ipw ),
499 $
max( 1, nqc2 ), c( ioffc1 ),
501 CALL sger( mpv, nqc2, -tauloc( 1 ), work, 1,
502 $ work( ipw ), 1, c( ioffc2 ), ldc )
515 IF( descv( m_ ).EQ.incv )
THEN
520 CALL pbstrnv( ictxt,
'Rowwise',
'Transpose', m,
521 $ descv( nb_ ), iroffc2, v( ioffv ), ldv,
523 $ work, 1, ivrow, ivcol, icrow2
528 IF( myrow.EQ.ivrow )
THEN
530 CALL sgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
532 tauloc( 1 ) = tau( iiv )
536 CALL sgebr2d( ictxt, 'columnwise
', ' ', 1, 1, TAULOC,
541.NE.
IF( TAULOC( 1 )ZERO ) THEN
546 CALL SGEMV( 'transpose
', MPV, NQC2, ONE,
547 $ C( IOFFC2 ), LDC, WORK, 1, ZERO,
550 CALL SLASET( 'all
', NQC2, 1, ZERO, ZERO,
551 $ WORK( IPW ), MAX( 1, NQC2 ) )
553.EQ.
IF( MYROWICROW1 )
554 $ CALL SAXPY( NQC2, ONE, C( IOFFC1 ), LDC,
555 $ WORK( IPW ), MAX( 1, NQC2 ) )
557 CALL SGSUM2D( ICTXT, 'columnwise
', ' ', NQC2, 1,
558 $ WORK( IPW ), MAX( 1, NQC2 ), RDEST,
563.EQ.
IF( MYROWICROW1 )
564 $ CALL SAXPY( NQC2, -TAULOC( 1 ), WORK( IPW ),
565 $ MAX( 1, NQC2 ), C( IOFFC1 ), LDC )
566 CALL SGER( MPV, NQC2, -TAULOC( 1 ), WORK, 1,
567 $ WORK( IPW ), 1, C( IOFFC2 ), LDC )
574 CALL PB_TOPGET( ICTXT, 'broadcast
', 'rowwise
', ROWBTOP )
575.EQ.
IF( MYCOLIVCOL ) THEN
578 CALL SCOPY( MPV, V( IOFFV ), 1, WORK, 1 )
579 WORK( IPW ) = TAU( JJV )
580 CALL SGEBS2D( ICTXT, 'rowwise
', ROWBTOP, IPW, 1,
582 TAULOC( 1 ) = TAU( JJV )
587 CALL SGEBR2D( ICTXT, 'rowwise', rowbtop, ipw, 1, work,
588 $ ipw, myrow, ivcol )
589 tauloc( 1 ) = work( ipw )
593 IF( tauloc( 1 ).NE.zero )
THEN
598 CALL sgemv(
'Transpose', mpv, nqc2, one,
599 $ c( ioffc2 ), ldc, work, 1, zero,
602 CALL slaset( 'all
', NQC2, 1, ZERO, ZERO,
603 $ WORK( IPW ), MAX( 1, NQC2 ) )
605.EQ.
IF( MYROWICROW1 )
606 $ CALL SAXPY( NQC2, ONE, C( IOFFC1 ), LDC,
607 $ WORK( IPW ), MAX( 1, NQC2 ) )
609 CALL SGSUM2D( ICTXT, 'columnwise
', ' ', NQC2, 1,
610 $ WORK( IPW ), MAX( 1, NQC2 ), RDEST,
615.EQ.
IF( MYROWICROW1 )
616 $ CALL SAXPY( NQC2, -TAULOC( 1 ), WORK( IPW ),
617 $ MAX( 1, NQC2 ), C( IOFFC1 ), LDC )
618 CALL SGER( MPV, NQC2, -TAULOC( 1 ), WORK, 1,
619 $ WORK( IPW ), 1, C( IOFFC2 ), LDC )
638.EQ.
IF( DESCV( M_ )INCV ) THEN
642.EQ.
IF( IVROWICROW2 ) THEN
646.EQ.
IF( MYROWICROW2 ) THEN
648 TAULOC( 1 ) = TAU( IIV )
650.NE.
IF( TAULOC( 1 )ZERO ) THEN
655 CALL SGEMV( 'no transpose
', MPC2, NQV, ONE,
656 $ C( IOFFC2 ), LDC, V( IOFFV ),
657 $ LDV, ZERO, WORK, 1 )
659 CALL SLASET( 'all
', MPC2, 1, ZERO, ZERO,
660 $ WORK, MAX( 1, MPC2 ) )
662.EQ.
IF( MYCOLICCOL1 )
663 $ CALL SAXPY( MPC2, ONE, C( IOFFC1 ), 1,
666 CALL SGSUM2D( ICTXT, 'rowwise
', '', MPC2, 1,
667 $ WORK, MAX( 1, MPC2 ), RDEST,
670.EQ.
IF( MYCOLICCOL1 )
671 $ CALL SAXPY( MPC2, -TAULOC( 1 ), WORK, 1,
676.GT..AND..GT.
IF( MPC20 NQV0 )
677 $ CALL SGER( MPC2, NQV, -TAULOC( 1 ), WORK, 1,
678 $ V( IOFFV ), LDV, C( IOFFC2 ),
688.EQ.
IF( MYROWIVROW ) THEN
691 CALL SCOPY( NQV, V( IOFFV ), LDV, WORK, 1 )
692 WORK( IPW ) = TAU( IIV )
693 CALL SGESD2D( ICTXT, IPW, 1, WORK, IPW, ICROW2,
696.EQ.
ELSE IF( MYROWICROW2 ) THEN
699 CALL SGERV2D( ICTXT, IPW, 1, WORK, IPW, IVROW,
701 TAULOC( 1 ) = WORK( IPW )
703.NE.
IF( TAULOC( 1 )ZERO ) THEN
708 CALL SGEMV( 'no transpose
', MPC2, NQV, ONE,
709 $ C( IOFFC2 ), LDC, WORK, 1, ZERO,
712 CALL SLASET( 'all
', MPC2, 1, ZERO, ZERO,
713 $ WORK( IPW ), MAX( 1, MPC2 ) )
715.EQ.
IF( MYCOLICCOL1 )
716 $ CALL SAXPY( MPC2, ONE, C( IOFFC1 ), 1,
718 CALL SGSUM2D( ICTXT, 'rowwise
', ' ', MPC2, 1,
719 $ WORK( IPW ), MAX( 1, MPC2 ),
721.EQ.
IF( MYCOLICCOL1 )
722 $ CALL SAXPY( MPC2, -TAULOC( 1 ), WORK( IPW ),
723 $ 1, C( IOFFC1 ), 1 )
727 CALL SGER( MPC2, NQV, -TAULOC( 1 ), WORK( IPW ),
728 $ 1, WORK, 1, C( IOFFC2 ), LDC )
740 CALL PBSTRNV( ICTXT, 'columnwise
', 'transpose
', N,
741 $ DESCV( MB_ ), ICOFFC2, V( IOFFV ), 1, ZERO,
742 $ WORK, 1, IVROW, IVCOL, ICROW2, ICCOL2,
747.EQ.
IF( MYROWICROW2 ) THEN
749.EQ.
IF( MYCOLIVCOL ) THEN
751 CALL SGEBS2D( ICTXT, 'rowwise
', ' ', 1, 1,
753 TAULOC( 1 ) = TAU( JJV )
757 CALL SGEBR2D( ICTXT, 'rowwise
', ' ', 1, 1, TAULOC,
762.NE.
IF( TAULOC( 1 )ZERO ) THEN
767 CALL SGEMV( 'no transpose
', MPC2, NQV, ONE,
768 $ C( IOFFC2 ), LDC, WORK, 1, ZERO,
771 CALL SLASET( 'all
', MPC2, 1, ZERO, ZERO,
772 $ WORK( IPW ), MAX( 1, MPC2 ) )
774.EQ.
IF( MYCOLICCOL1 )
775 $ CALL SAXPY( MPC2, ONE, C( IOFFC1 ), 1,
777 CALL SGSUM2D( ICTXT, 'rowwise
', ' ', MPC2, 1,
778 $ WORK( IPW ), MAX( 1, MPC2 ), RDEST,
780.EQ.
IF( MYCOLICCOL1 )
781 $ CALL SAXPY( MPC2, -TAULOC( 1 ), WORK( IPW ), 1,
786 CALL SGER( MPC2, NQV, -TAULOC( 1 ), WORK( IPW ), 1,
787 $ WORK, 1, C( IOFFC2 ), LDC )
798.EQ.
IF( DESCV( M_ )INCV ) THEN
802 CALL PB_TOPGET( ICTXT, 'broadcast
', 'columnwise
',
804.EQ.
IF( MYROWIVROW ) THEN
807 CALL SCOPY( NQV, V( IOFFV ), LDV, WORK, 1 )
808 WORK( IPW ) = TAU( IIV )
809 CALL SGEBS2D( ICTXT, 'columnwise
', COLBTOP, IPW, 1,
811 TAULOC( 1 ) = TAU( IIV )
816 CALL SGEBR2D( ICTXT, 'columnwise
', COLBTOP, IPW, 1,
817 $ WORK, IPW, IVROW, MYCOL )
818 TAULOC( 1 ) = WORK( IPW )
822.NE.
IF( TAULOC( 1 )ZERO ) THEN
827 CALL SGEMV( 'no transpose
', MPC2, NQV, ONE,
828 $ C( IOFFC2 ), LDC, WORK, 1, ZERO,
831 CALL SLASET( 'all
', MPC2, 1, ZERO, ZERO,
832 $ WORK( IPW ), MAX( 1, MPC2 ) )
834.EQ.
IF( MYCOLICCOL1 )
835 $ CALL SAXPY( MPC2, ONE, C( IOFFC1 ), 1,
838 CALL SGSUM2D( ICTXT, 'rowwise
', ' ', MPC2, 1,
839 $ WORK( IPW ), MAX( 1, MPC2 ), RDEST,
841.EQ.
IF( MYCOLICCOL1 )
842 $ CALL SAXPY( MPC2, -TAULOC( 1 ), WORK( IPW ), 1,
847 CALL SGER( MPC2, NQV, -TAULOC( 1 ), WORK( IPW ), 1,
848 $ WORK, 1, C( IOFFC2 ), LDC )
856 CALL PBSTRNV( ICTXT, 'columnwise
', 'transpose
', N,
857 $ DESCV( MB_ ), ICOFFC2, V( IOFFV ), 1, ZERO,
858 $ WORK, 1, IVROW, IVCOL, -1, ICCOL2,
863.EQ.
IF( MYCOLIVCOL ) THEN
865 CALL SGEBS2D( ICTXT, 'rowwise
', ' ', 1, 1, TAU( JJV ),
867 TAULOC( 1 ) = TAU( JJV )
871 CALL SGEBR2D( ICTXT, 'rowwise
', ' ', 1, 1, TAULOC, 1,
876.NE.
IF( TAULOC( 1 )ZERO ) THEN
881 CALL SGEMV( 'no transpose
', MPC2, NQV, ONE,
882 $ C( IOFFC2 ), LDC, WORK, 1, ZERO,
885 CALL SLASET( 'all
', MPC2, 1, ZERO, ZERO,
886 $ WORK( IPW ), MAX( 1, MPC2 ) )
888.EQ.
IF( MYCOLICCOL1 )
889 $ CALL SAXPY( MPC2, ONE, C( IOFFC1 ), 1,
891 CALL SGSUM2D( ICTXT, 'rowwise
', ' ', MPC2, 1,
892 $ WORK( IPW ), MAX( 1, MPC2 ), RDEST,
894.EQ.
IF( MYCOLICCOL1 )
895 $ CALL SAXPY( MPC2, -TAULOC( 1 ), WORK( IPW ), 1,
900 CALL SGER( MPC2, NQV, -TAULOC( 1 ), WORK( IPW ), 1,
901 $ WORK, 1, C( IOFFC2 ), LDC )