void UUnb ( AbstractDistMatrix<F>& APre, AbstractDistMatrix<F>& householderScalarsPre ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,STAR,STAR> householderScalarsProx( householderScalarsPre ); auto& A = AProx.Get(); auto& householderScalars = householderScalarsProx.Get(); const Grid& g = A.Grid(); const Int n = A.Height(); const Int householderScalarsHeight = Max(n-1,0); householderScalars.SetGrid( g ); householderScalars.Resize( householderScalarsHeight, 1 ); DistMatrix<F,MC,STAR> a21_MC(g); DistMatrix<F,MR,STAR> a21_MR(g); DistMatrix<F,MC,STAR> x1_MC(g); DistMatrix<F,MR,STAR> x12Adj_MR(g); for( Int k=0; k<n-1; ++k ) { const Range<Int> ind1( k, k+1 ), ind2( k+1, n ); auto a21 = A( ind2, ind1 ); auto A22 = A( ind2, ind2 ); auto A2 = A( IR(0,n), ind2 ); auto alpha21T = A( IR(k+1,k+2), ind1 ); auto a21B = A( IR(k+2,n), ind1 ); // Find tau and v such that // / I - tau | 1 | | 1, v^H | \ | alpha21T | = | beta | // \ | v | / | a21B | | 0 | const F tau = LeftReflector( alpha21T, a21B ); householderScalars.Set(k,0,tau); // Temporarily set a21 := | 1 | // | v | F beta=0; if( alpha21T.IsLocal(0,0) ) beta = alpha21T.GetLocal(0,0); alpha21T.Set(0,0,F(1)); // A2 := A2 Hous(a21,tau)^H // = A2 (I - conj(tau) a21 a21^H) // = A2 - conj(tau) (A2 a21) a21^H // ----------------------------------- // x1 := A2 a21 a21_MR.AlignWith( A2 ); a21_MR = a21; x1_MC.AlignWith( A2 ); Zeros( x1_MC, n, 1 ); LocalGemv( NORMAL, F(1), A2, a21_MR, F(0), x1_MC ); El::AllReduce( x1_MC, A2.RowComm() ); // A2 := A2 - conj(tau) x1 a21^H LocalGer( -Conj(tau), x1_MC, a21_MR, A2 ); // A22 := Hous(a21,tau) A22 // = (I - tau a21 a21^H) A22 // = A22 - tau a21 (A22^H a21)^H // ---------------------------------- // x12^H := (a21^H A22)^H = A22^H a21 a21_MC.AlignWith( A22 ); a21_MC = a21; x12Adj_MR.AlignWith( A22 ); Zeros( x12Adj_MR, A22.Width(), 1 ); LocalGemv( ADJOINT, F(1), A22, a21_MC, F(0), x12Adj_MR ); El::AllReduce( x12Adj_MR, A22.ColComm() ); // A22 := A22 - tau a21 x12 LocalGer( -tau, a21_MC, x12Adj_MR, A22 ); // Put beta back if( alpha21T.IsLocal(0,0) ) alpha21T.SetLocal(0,0,beta); } }
void LowerBlocked ( AbstractDistMatrix<F>& APre, AbstractDistMatrix<F>& householderScalarsPre ) { DEBUG_CSE DEBUG_ONLY(AssertSameGrids( APre, householderScalarsPre )) DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,STAR,STAR> householderScalarsProx( householderScalarsPre ); auto& A = AProx.Get(); auto& householderScalars = householderScalarsProx.Get(); const Grid& g = A.Grid(); const Int n = A.Height(); householderScalars.Resize( Max(n-1,0), 1 ); DistMatrix<F,MC,STAR> UB1_MC_STAR(g), V21_MC_STAR(g); DistMatrix<F,MR,STAR> V01_MR_STAR(g), VB1_MR_STAR(g), UB1_MR_STAR(g); DistMatrix<F,STAR,STAR> G11_STAR_STAR(g); const Int bsize = Blocksize(); for( Int k=0; k<n-1; k+=bsize ) { const Int nb = Min(bsize,n-1-k); const Range<Int> ind0( 0, k ), ind1( k, k+nb ), indB( k, n ), indR( k, n ), ind2( k+nb, n ); auto ABR = A( indB, indR ); auto A22 = A( ind2, ind2 ); auto householderScalars1 = householderScalars( ind1, ALL ); UB1_MC_STAR.AlignWith( ABR ); UB1_MR_STAR.AlignWith( ABR ); VB1_MR_STAR.AlignWith( ABR ); UB1_MC_STAR.Resize( n-k, nb ); UB1_MR_STAR.Resize( n-k, nb ); VB1_MR_STAR.Resize( n-k, nb ); G11_STAR_STAR.Resize( nb, nb ); hessenberg::LowerPanel ( ABR, householderScalars1, UB1_MC_STAR, UB1_MR_STAR, VB1_MR_STAR, G11_STAR_STAR ); auto AB0 = A( indB, ind0 ); auto A2R = A( ind2, indR ); auto U21_MC_STAR = UB1_MC_STAR( IR(nb,END), ALL ); // AB0 := AB0 - (UB1 inv(G11)^H UB1^H AB0) // = AB0 - (UB1 ((AB0^H UB1) inv(G11))^H) // ------------------------------------------- V01_MR_STAR.AlignWith( AB0 ); Zeros( V01_MR_STAR, k, nb ); LocalGemm( ADJOINT, NORMAL, F(1), AB0, UB1_MC_STAR, F(0), V01_MR_STAR ); El::AllReduce( V01_MR_STAR, AB0.ColComm() ); LocalTrsm ( RIGHT, UPPER, NORMAL, NON_UNIT, F(1), G11_STAR_STAR, V01_MR_STAR ); LocalGemm ( NORMAL, ADJOINT, F(-1), UB1_MC_STAR, V01_MR_STAR, F(1), AB0 ); // A2R := (A2R - U21 inv(G11)^H VB1^H)(I - UB1 inv(G11) UB1^H) // ----------------------------------------------------------- // A2R := A2R - U21 inv(G11)^H VB1^H // (note: VB1 is overwritten) LocalTrsm ( RIGHT, UPPER, NORMAL, NON_UNIT, F(1), G11_STAR_STAR, VB1_MR_STAR ); LocalGemm ( NORMAL, ADJOINT, F(-1), U21_MC_STAR, VB1_MR_STAR, F(1), A2R ); // A2R := A2R - ((A2R UB1) inv(G11)) UB1^H V21_MC_STAR.AlignWith( A2R ); Zeros( V21_MC_STAR, A2R.Height(), nb ); LocalGemm( NORMAL, NORMAL, F(1), A2R, UB1_MR_STAR, F(0), V21_MC_STAR ); El::AllReduce( V21_MC_STAR, A2R.RowComm() ); LocalTrsm ( RIGHT, UPPER, NORMAL, NON_UNIT, F(1), G11_STAR_STAR, V21_MC_STAR ); LocalGemm ( NORMAL, ADJOINT, F(-1), V21_MC_STAR, UB1_MR_STAR, F(1), A2R ); } }