inline void ReformHermitianMatrix ( UpperOrLower uplo, DistMatrix<Complex<R>,MC,MR >& A, const DistMatrix<R, VR,STAR>& w, const DistMatrix<Complex<R>,MC,MR >& Z, const RealFunctor& f ) { #ifndef RELEASE PushCallStack("hermitian_function::ReformHermitianMatrix"); #endif const Grid& g = A.Grid(); typedef Complex<R> C; DistMatrix<C,MC,MR> ZL(g), ZR(g), Z0(g), Z1(g), Z2(g); DistMatrix<R,VR,STAR> wT(g), w0(g), wB(g), w1(g), w2(g); DistMatrix<C,MC, STAR> Z1_MC_STAR(g); DistMatrix<C,VR, STAR> Z1_VR_STAR(g); DistMatrix<C,STAR,MR > Z1Adj_STAR_MR(g); DistMatrix<R,STAR,STAR> w1_STAR_STAR(g); if( uplo == LOWER ) MakeTrapezoidal( LEFT, UPPER, 1, A ); else MakeTrapezoidal( LEFT, LOWER, -1, A ); LockedPartitionRight( Z, ZL, ZR, 0 ); LockedPartitionDown ( w, wT, wB, 0 ); while( ZL.Width() < Z.Width() ) { LockedRepartitionRight ( ZL, /**/ ZR, Z0, /**/ Z1, Z2 ); LockedRepartitionDown ( wT, w0, /**/ /**/ w1, wB, w2 ); Z1_MC_STAR.AlignWith( A ); Z1_VR_STAR.AlignWith( A ); Z1Adj_STAR_MR.AlignWith( A ); //--------------------------------------------------------------------// Z1_MC_STAR = Z1; Z1_VR_STAR = Z1_MC_STAR; w1_STAR_STAR = w1; // Scale Z1[VR,* ] with the modified eigenvalues const int width = Z1_VR_STAR.Width(); const int localHeight = Z1_VR_STAR.LocalHeight(); for( int j=0; j<width; ++j ) { const R omega = f(w1_STAR_STAR.GetLocalEntry(j,0)); C* buffer = Z1_VR_STAR.LocalBuffer(0,j); for( int iLocal=0; iLocal<localHeight; ++iLocal ) buffer[iLocal] *= omega; } Z1Adj_STAR_MR.AdjointFrom( Z1_VR_STAR ); internal::LocalTrrk( uplo, (C)1, Z1_MC_STAR, Z1Adj_STAR_MR, (C)1, A ); //--------------------------------------------------------------------// Z1Adj_STAR_MR.FreeAlignments(); Z1_VR_STAR.FreeAlignments(); Z1_MC_STAR.FreeAlignments(); SlideLockedPartitionDown ( wT, w0, w1, /**/ /**/ wB, w2 ); SlideLockedPartitionRight ( ZL, /**/ ZR, Z0, Z1, /**/ Z2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void ReformNormalMatrix ( DistMatrix<Complex<R>,MC,MR >& A, const DistMatrix<R, VR,STAR>& w, const DistMatrix<Complex<R>,MC,MR >& Z, const ComplexFunctor& f ) { #ifndef RELEASE PushCallStack("hermitian_function::ReformNormalMatrix"); #endif const Grid& g = A.Grid(); typedef Complex<R> C; DistMatrix<C,MC,MR> ZL(g), ZR(g), Z0(g), Z1(g), Z2(g); DistMatrix<R,VR,STAR> wT(g), w0(g), wB(g), w1(g), w2(g); DistMatrix<C,MC, STAR> Z1_MC_STAR(g); DistMatrix<C,VR, STAR> Z1_VR_STAR(g); DistMatrix<C,STAR,MR > Z1Adj_STAR_MR(g); DistMatrix<R,STAR,STAR> w1_STAR_STAR(g); Zero( A ); LockedPartitionRight( Z, ZL, ZR, 0 ); LockedPartitionDown ( w, wT, wB, 0 ); while( ZL.Width() < Z.Width() ) { LockedRepartitionRight ( ZL, /**/ ZR, Z0, /**/ Z1, Z2 ); LockedRepartitionDown ( wT, w0, /**/ /**/ w1, wB, w2 ); Z1_MC_STAR.AlignWith( A ); Z1_VR_STAR.AlignWith( A ); Z1Adj_STAR_MR.AlignWith( A ); //--------------------------------------------------------------------// Z1_MC_STAR = Z1; Z1_VR_STAR = Z1_MC_STAR; w1_STAR_STAR = w1; // Scale Z1[VR,* ] with the modified eigenvalues const int width = Z1_VR_STAR.Width(); const int localHeight = Z1_VR_STAR.LocalHeight(); for( int j=0; j<width; ++j ) { const C conjOmega = Conj(f(w1_STAR_STAR.GetLocalEntry(j,0))); C* buffer = Z1_VR_STAR.LocalBuffer(0,j); for( int iLocal=0; iLocal<localHeight; ++iLocal ) buffer[iLocal] *= conjOmega; } Z1Adj_STAR_MR.AdjointFrom( Z1_VR_STAR ); internal::LocalGemm ( NORMAL, NORMAL, (C)1, Z1_MC_STAR, Z1Adj_STAR_MR, (C)1, A ); //--------------------------------------------------------------------// Z1Adj_STAR_MR.FreeAlignments(); Z1_VR_STAR.FreeAlignments(); Z1_MC_STAR.FreeAlignments(); SlideLockedPartitionDown ( wT, w0, w1, /**/ /**/ wB, w2 ); SlideLockedPartitionRight ( ZL, /**/ ZR, Z0, Z1, /**/ Z2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void internal::ApplyPackedReflectorsLUVF ( Conjugation conjugation, int offset, const DistMatrix<Complex<R>,MC,MR >& H, const DistMatrix<Complex<R>,MD,STAR>& t, DistMatrix<Complex<R>,MC,MR >& A ) { #ifndef RELEASE PushCallStack("internal::ApplyPackedReflectorsLUVF"); if( H.Grid() != t.Grid() || t.Grid() != A.Grid() ) throw std::logic_error ("{H,t,A} must be distributed over the same grid"); if( offset > H.Height() ) throw std::logic_error("Transforms cannot extend above matrix"); if( offset < 0 ) throw std::logic_error("Transforms cannot extend below matrix"); if( H.Width() != A.Height() ) throw std::logic_error ("Width of transforms must equal height of target matrix"); if( t.Height() != H.DiagonalLength( offset ) ) throw std::logic_error("t must be the same length as H's offset diag"); if( !t.AlignedWithDiagonal( H, offset ) ) throw std::logic_error("t must be aligned with H's 'offset' diagonal"); #endif typedef Complex<R> C; const Grid& g = H.Grid(); // Matrix views DistMatrix<C,MC,MR> HTL(g), HTR(g), H00(g), H01(g), H02(g), HPan(g), HBL(g), HBR(g), H10(g), H11(g), H12(g), H20(g), H21(g), H22(g); DistMatrix<C,MC,MR> AT(g), A0(g), ATop(g), AB(g), A1(g), A2(g); DistMatrix<C,MD,STAR> tT(g), t0(g), tB(g), t1(g), t2(g); DistMatrix<C,MC, MR > HPanCopy(g); DistMatrix<C,VC, STAR> HPan_VC_STAR(g); DistMatrix<C,MC, STAR> HPan_MC_STAR(g); DistMatrix<C,STAR,STAR> t1_STAR_STAR(g); DistMatrix<C,STAR,STAR> SInv_STAR_STAR(g); DistMatrix<C,STAR,MR > Z_STAR_MR(g); DistMatrix<C,STAR,VR > Z_STAR_VR(g); LockedPartitionDownDiagonal ( H, HTL, HTR, HBL, HBR, 0 ); LockedPartitionDown ( t, tT, tB, 0 ); PartitionDown ( A, AT, AB, 0 ); while( HTL.Height() < H.Height() && HTL.Width() < H.Width() ) { LockedRepartitionDownDiagonal ( HTL, /**/ HTR, H00, /**/ H01, H02, /*************/ /******************/ /**/ H10, /**/ H11, H12, HBL, /**/ HBR, H20, /**/ H21, H22 ); const int HPanHeight = H01.Height() + H11.Height(); const int HPanOffset = std::min( H11.Width(), std::max(offset-H00.Width(),0) ); const int HPanWidth = H11.Width()-HPanOffset; HPan.LockedView( H, 0, H00.Width()+HPanOffset, HPanHeight, HPanWidth ); LockedRepartitionDown ( tT, t0, /**/ /**/ t1, tB, t2, HPanWidth ); RepartitionDown ( AT, A0, /**/ /**/ A1, AB, A2 ); ATop.View2x1( A0, A1 ); HPan_MC_STAR.AlignWith( ATop ); Z_STAR_MR.AlignWith( ATop ); Z_STAR_VR.AlignWith( ATop ); Z_STAR_MR.ResizeTo( HPan.Width(), ATop.Width() ); SInv_STAR_STAR.ResizeTo( HPan.Width(), HPan.Width() ); Zero( SInv_STAR_STAR ); //--------------------------------------------------------------------// HPanCopy = HPan; MakeTrapezoidal( RIGHT, UPPER, offset, HPanCopy ); SetDiagonalToOne( RIGHT, offset, HPanCopy ); HPan_VC_STAR = HPanCopy; Herk ( UPPER, ADJOINT, (C)1, HPan_VC_STAR.LockedLocalMatrix(), (C)0, SInv_STAR_STAR.LocalMatrix() ); SInv_STAR_STAR.SumOverGrid(); t1_STAR_STAR = t1; FixDiagonal( conjugation, t1_STAR_STAR, SInv_STAR_STAR ); HPan_MC_STAR = HPanCopy; internal::LocalGemm ( ADJOINT, NORMAL, (C)1, HPan_MC_STAR, ATop, (C)0, Z_STAR_MR ); Z_STAR_VR.SumScatterFrom( Z_STAR_MR ); internal::LocalTrsm ( LEFT, UPPER, ADJOINT, NON_UNIT, (C)1, SInv_STAR_STAR, Z_STAR_VR ); Z_STAR_MR = Z_STAR_VR; internal::LocalGemm ( NORMAL, NORMAL, (C)-1, HPan_MC_STAR, Z_STAR_MR, (C)1, ATop ); //--------------------------------------------------------------------// HPan_MC_STAR.FreeAlignments(); Z_STAR_MR.FreeAlignments(); Z_STAR_VR.FreeAlignments(); SlideLockedPartitionDownDiagonal ( HTL, /**/ HTR, H00, H01, /**/ H02, /**/ H10, H11, /**/ H12, /*************/ /******************/ HBL, /**/ HBR, H20, H21, /**/ H22 ); SlideLockedPartitionDown ( tT, t0, t1, /**/ /**/ tB, t2 ); SlidePartitionDown ( AT, A0, A1, /**/ /**/ AB, A2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void HermitianFromEVD ( UpperOrLower uplo, DistMatrix<F>& A, const DistMatrix<BASE(F),VR,STAR>& w, const DistMatrix<F>& Z ) { #ifndef RELEASE CallStackEntry entry("HermitianFromEVD"); #endif const Grid& g = A.Grid(); typedef BASE(F) R; DistMatrix<F> ZL(g), ZR(g), Z0(g), Z1(g), Z2(g); DistMatrix<R,VR,STAR> wT(g), w0(g), wB(g), w1(g), w2(g); DistMatrix<F,MC, STAR> Z1_MC_STAR(g); DistMatrix<F,VR, STAR> Z1_VR_STAR(g); DistMatrix<F,STAR,MR > Z1Adj_STAR_MR(g); DistMatrix<R,STAR,STAR> w1_STAR_STAR(g); A.ResizeTo( Z.Height(), Z.Height() ); if( uplo == LOWER ) MakeTrapezoidal( UPPER, A, 1 ); else MakeTrapezoidal( LOWER, A, -1 ); LockedPartitionRight( Z, ZL, ZR, 0 ); LockedPartitionDown ( w, wT, wB, 0 ); while( ZL.Width() < Z.Width() ) { LockedRepartitionRight ( ZL, /**/ ZR, Z0, /**/ Z1, Z2 ); LockedRepartitionDown ( wT, w0, /**/ /**/ w1, wB, w2 ); Z1_MC_STAR.AlignWith( A ); Z1_VR_STAR.AlignWith( A ); Z1Adj_STAR_MR.AlignWith( A ); //--------------------------------------------------------------------// Z1_MC_STAR = Z1; Z1_VR_STAR = Z1_MC_STAR; w1_STAR_STAR = w1; DiagonalScale( RIGHT, NORMAL, w1_STAR_STAR, Z1_VR_STAR ); Z1Adj_STAR_MR.AdjointFrom( Z1_VR_STAR ); LocalTrrk( uplo, F(1), Z1_MC_STAR, Z1Adj_STAR_MR, F(1), A ); //--------------------------------------------------------------------// SlideLockedPartitionDown ( wT, w0, w1, /**/ /**/ wB, w2 ); SlideLockedPartitionRight ( ZL, /**/ ZR, Z0, Z1, /**/ Z2 ); } }
inline void Trr2kNNTT ( UpperOrLower uplo, Orientation orientationOfC, Orientation orientationOfD, T alpha, const DistMatrix<T,MC,MR>& A, const DistMatrix<T,MC,MR>& B, const DistMatrix<T,MC,MR>& C, const DistMatrix<T,MC,MR>& D, T beta, DistMatrix<T,MC,MR>& E ) { #ifndef RELEASE PushCallStack("internal::Trr2kNNTT"); if( E.Height() != E.Width() || A.Width() != C.Height() || A.Height() != E.Height() || C.Width() != E.Height() || B.Width() != E.Width() || D.Height() != E.Width() || A.Width() != B.Height() || C.Height() != D.Width() ) throw std::logic_error("Nonconformal Trr2kNNTT"); #endif const Grid& g = E.Grid(); DistMatrix<T,MC,MR> AL(g), AR(g), A0(g), A1(g), A2(g); DistMatrix<T,MC,MR> BT(g), B0(g), BB(g), B1(g), B2(g); DistMatrix<T,MC,MR> CT(g), C0(g), CB(g), C1(g), C2(g); DistMatrix<T,MC,MR> DL(g), DR(g), D0(g), D1(g), D2(g); DistMatrix<T,MC, STAR> A1_MC_STAR(g); DistMatrix<T,MR, STAR> B1Trans_MR_STAR(g); DistMatrix<T,STAR,MC > C1_STAR_MC(g); DistMatrix<T,VR, STAR> D1_VR_STAR(g); DistMatrix<T,STAR,MR > D1AdjOrTrans_STAR_MR(g); A1_MC_STAR.AlignWith( E ); B1Trans_MR_STAR.AlignWith( E ); C1_STAR_MC.AlignWith( E ); D1_VR_STAR.AlignWith( E ); D1AdjOrTrans_STAR_MR.AlignWith( E ); LockedPartitionRight( A, AL, AR, 0 ); LockedPartitionDown ( B, BT, BB, 0 ); LockedPartitionDown ( C, CT, CB, 0 ); LockedPartitionRight( D, DL, DR, 0 ); while( AL.Width() < A.Width() ) { LockedRepartitionRight ( AL, /**/ AR, A0, /**/ A1, A2 ); LockedRepartitionDown ( BT, B0, /**/ /**/ B1, BB, B2 ); LockedRepartitionDown ( CT, C0, /**/ /**/ C1, CB, C2 ); LockedRepartitionRight ( DL, /**/ DR, D0, /**/ D1, D2 ); //--------------------------------------------------------------------// A1_MC_STAR = A1; C1_STAR_MC = C1; B1Trans_MR_STAR.TransposeFrom( B1 ); D1_VR_STAR = D1; if( orientationOfD == ADJOINT ) D1AdjOrTrans_STAR_MR.AdjointFrom( D1_VR_STAR ); else D1AdjOrTrans_STAR_MR.TransposeFrom( D1_VR_STAR ); LocalTrr2k ( uplo, TRANSPOSE, orientationOfC, alpha, A1_MC_STAR, B1Trans_MR_STAR, C1_STAR_MC, D1AdjOrTrans_STAR_MR, beta, E ); //--------------------------------------------------------------------// SlideLockedPartitionRight ( DL, /**/ DR, D0, D1, /**/ D2 ); SlideLockedPartitionDown ( CT, C0, C1, /**/ /**/ CB, C2 ); SlideLockedPartitionDown ( BT, B0, B1, /**/ /**/ BB, B2 ); SlideLockedPartitionRight ( AL, /**/ AR, A0, A1, /**/ A2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void Her2kUC ( T alpha, const DistMatrix<T>& A, const DistMatrix<T>& B, T beta, DistMatrix<T>& C ) { #ifndef RELEASE PushCallStack("internal::Her2kUC"); if( A.Grid() != B.Grid() || B.Grid() != C.Grid() ) throw std::logic_error ("{A,B,C} must be distributed over the same grid"); if( A.Width() != C.Height() || A.Width() != C.Width() || B.Width() != C.Height() || B.Width() != C.Width() || A.Height() != B.Height() ) { std::ostringstream msg; msg << "Nonconformal Her2kUC:\n" << " A ~ " << A.Height() << " x " << A.Width() << "\n" << " B ~ " << B.Height() << " x " << B.Width() << "\n" << " C ~ " << C.Height() << " x " << C.Width() << "\n"; throw std::logic_error( msg.str().c_str() ); } #endif const Grid& g = A.Grid(); // Matrix views DistMatrix<T> AT(g), A0(g), AB(g), A1(g), A2(g); DistMatrix<T> BT(g), B0(g), BB(g), B1(g), B2(g); // Temporary distributions DistMatrix<T,MR, STAR> A1Trans_MR_STAR(g); DistMatrix<T,MR, STAR> B1Trans_MR_STAR(g); DistMatrix<T,STAR,VR > A1_STAR_VR(g); DistMatrix<T,STAR,VR > B1_STAR_VR(g); DistMatrix<T,STAR,MC > A1_STAR_MC(g); DistMatrix<T,STAR,MC > B1_STAR_MC(g); A1Trans_MR_STAR.AlignWith( C ); B1Trans_MR_STAR.AlignWith( C ); A1_STAR_MC.AlignWith( C ); B1_STAR_MC.AlignWith( C ); // Start the algorithm ScaleTrapezoid( beta, LEFT, UPPER, 0, C ); LockedPartitionDown ( A, AT, AB, 0 ); LockedPartitionDown ( B, BT, BB, 0 ); while( AB.Height() > 0 ) { LockedRepartitionDown ( AT, A0, /**/ /**/ A1, AB, A2 ); LockedRepartitionDown ( BT, B0, /**/ /**/ B1, BB, B2 ); //--------------------------------------------------------------------// A1Trans_MR_STAR.TransposeFrom( A1 ); A1_STAR_VR.TransposeFrom( A1Trans_MR_STAR ); A1_STAR_MC = A1_STAR_VR; B1Trans_MR_STAR.TransposeFrom( B1 ); B1_STAR_VR.TransposeFrom( B1Trans_MR_STAR ); B1_STAR_MC = B1_STAR_VR; LocalTrr2k ( UPPER, ADJOINT, TRANSPOSE, ADJOINT, TRANSPOSE, alpha, A1_STAR_MC, B1Trans_MR_STAR, B1_STAR_MC, A1Trans_MR_STAR, T(1), C ); //--------------------------------------------------------------------// SlideLockedPartitionDown ( AT, A0, A1, /**/ /**/ AB, A2 ); SlideLockedPartitionDown ( BT, B0, B1, /**/ /**/ BB, B2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void LocalSymvColAccumulateU ( T alpha, const DistMatrix<T>& A, const DistMatrix<T,MC,STAR>& x_MC_STAR, const DistMatrix<T,MR,STAR>& x_MR_STAR, DistMatrix<T,MC,STAR>& z_MC_STAR, DistMatrix<T,MR,STAR>& z_MR_STAR, bool conjugate=false ) { #ifndef RELEASE CallStackEntry entry("internal::LocalSymvColAccumulateU"); if( A.Grid() != x_MC_STAR.Grid() || x_MC_STAR.Grid() != x_MR_STAR.Grid() || x_MR_STAR.Grid() != z_MC_STAR.Grid() || z_MC_STAR.Grid() != z_MR_STAR.Grid() ) LogicError ("{A,x,z} must be distributed over the same grid"); if( x_MC_STAR.Width() != 1 || x_MR_STAR.Width() != 1 || z_MC_STAR.Width() != 1 || z_MR_STAR.Width() != 1 ) LogicError("Expected x and z to be column vectors"); if( A.Height() != A.Width() || A.Height() != x_MC_STAR.Height() || A.Height() != x_MR_STAR.Height() || A.Height() != z_MC_STAR.Height() || A.Height() != z_MR_STAR.Height() ) { std::ostringstream msg; msg << "Nonconformal LocalSymvColAccumulateU: \n" << " A ~ " << A.Height() << " x " << A.Width() << "\n" << " x[MC,* ] ~ " << x_MC_STAR.Height() << " x " << x_MC_STAR.Width() << "\n" << " x[MR,* ] ~ " << x_MR_STAR.Height() << " x " << x_MR_STAR.Width() << "\n" << " z[MC,* ] ~ " << z_MC_STAR.Height() << " x " << z_MC_STAR.Width() << "\n" << " z[MR,* ] ~ " << z_MR_STAR.Height() << " x " << z_MR_STAR.Width() << "\n"; LogicError( msg.str() ); } if( x_MC_STAR.ColAlignment() != A.ColAlignment() || x_MR_STAR.ColAlignment() != A.RowAlignment() || z_MC_STAR.ColAlignment() != A.ColAlignment() || z_MR_STAR.ColAlignment() != A.RowAlignment() ) LogicError("Partial matrix distributions are misaligned"); #endif const Grid& g = A.Grid(); const Orientation orientation = ( conjugate ? ADJOINT : TRANSPOSE ); // Matrix views DistMatrix<T> A11(g), A12(g); DistMatrix<T> D11(g); DistMatrix<T,MC,STAR> x1_MC_STAR(g); DistMatrix<T,MR,STAR> xT_MR_STAR(g), x0_MR_STAR(g), xB_MR_STAR(g), x1_MR_STAR(g), x2_MR_STAR(g); DistMatrix<T,MC,STAR> z1_MC_STAR(g); DistMatrix<T,MR,STAR> z1_MR_STAR(g), z2_MR_STAR(g); // We want our local gemvs to be of width blocksize, so we will // temporarily change to max(r,c) times the current blocksize const Int ratio = Max( g.Height(), g.Width() ); PushBlocksizeStack( ratio*LocalSymvBlocksize<T>() ); LockedPartitionDown ( x_MR_STAR, xT_MR_STAR, xB_MR_STAR, 0 ); while( xT_MR_STAR.Height() < x_MR_STAR.Height() ) { LockedRepartitionDown ( xT_MR_STAR, x0_MR_STAR, /**********/ /**********/ x1_MR_STAR, xB_MR_STAR, x2_MR_STAR ); const Int n0 = x0_MR_STAR.Height(); const Int n1 = x1_MR_STAR.Height(); const Int n2 = x2_MR_STAR.Height(); LockedView( A11, A, n0, n0, n1, n1 ); LockedView( A12, A, n0, n0+n1, n1, n2 ); LockedView( x1_MC_STAR, x_MC_STAR, n0, 0, n1, 1 ); View( z1_MC_STAR, z_MC_STAR, n0, 0, n1, 1 ); View( z1_MR_STAR, z_MR_STAR, n0, 0, n1, 1 ); View( z2_MR_STAR, z_MR_STAR, n0+n1, 0, n2, 1 ); D11.AlignWith( A11 ); //--------------------------------------------------------------------// // TODO: These diagonal block updates can be greatly improved D11 = A11; MakeTriangular( UPPER, D11 ); LocalGemv( NORMAL, alpha, D11, x1_MR_STAR, T(1), z1_MC_STAR ); SetDiagonal( D11, T(0) ); LocalGemv( orientation, alpha, D11, x1_MC_STAR, T(1), z1_MR_STAR ); LocalGemv( NORMAL, alpha, A12, x2_MR_STAR, T(1), z1_MC_STAR ); LocalGemv( orientation, alpha, A12, x1_MC_STAR, T(1), z2_MR_STAR ); //--------------------------------------------------------------------// SlideLockedPartitionDown ( xT_MR_STAR, x0_MR_STAR, x1_MR_STAR, /**********/ /**********/ xB_MR_STAR, x2_MR_STAR ); } PopBlocksizeStack(); }
inline void LocalSymmetricAccumulateRU ( Orientation orientation, T alpha, const DistMatrix<T,MC, MR >& A, const DistMatrix<T,STAR,MC >& B_STAR_MC, const DistMatrix<T,MR, STAR>& BTrans_MR_STAR, DistMatrix<T,MC, STAR>& ZTrans_MC_STAR, DistMatrix<T,MR, STAR>& ZTrans_MR_STAR ) { #ifndef RELEASE PushCallStack("internal::LocalSymmetricAccumulateRU"); if( A.Grid() != B_STAR_MC.Grid() || B_STAR_MC.Grid() != BTrans_MR_STAR.Grid() || BTrans_MR_STAR.Grid() != ZTrans_MC_STAR.Grid() || ZTrans_MC_STAR.Grid() != ZTrans_MR_STAR.Grid() ) throw std::logic_error ("{A,B,C} must be distributed over the same grid"); if( A.Height() != A.Width() || A.Height() != B_STAR_MC.Width() || A.Height() != BTrans_MR_STAR.Height() || A.Height() != ZTrans_MC_STAR.Height() || A.Height() != ZTrans_MR_STAR.Height() || B_STAR_MC.Height() != BTrans_MR_STAR.Width() || BTrans_MR_STAR.Width() != ZTrans_MC_STAR.Width() || ZTrans_MC_STAR.Width() != ZTrans_MR_STAR.Width() ) { std::ostringstream msg; msg << "Nonconformal LocalSymmetricAccumulateRU: \n" << " A ~ " << A.Height() << " x " << A.Width() << "\n" << " B[* ,MC] ~ " << B_STAR_MC.Height() << " x " << B_STAR_MC.Width() << "\n" << " B^H/T[MR,* ] ~ " << BTrans_MR_STAR.Height() << " x " << BTrans_MR_STAR.Width() << "\n" << " Z^H/T[MC,* ] ~ " << ZTrans_MC_STAR.Height() << " x " << ZTrans_MC_STAR.Width() << "\n" << " Z^H/T[MR,* ] ~ " << ZTrans_MR_STAR.Height() << " x " << ZTrans_MR_STAR.Width() << "\n"; throw std::logic_error( msg.str().c_str() ); } if( B_STAR_MC.RowAlignment() != A.ColAlignment() || BTrans_MR_STAR.ColAlignment() != A.RowAlignment() || ZTrans_MC_STAR.ColAlignment() != A.ColAlignment() || ZTrans_MR_STAR.ColAlignment() != A.RowAlignment() ) throw std::logic_error("Partial matrix distributions are misaligned"); #endif const Grid& g = A.Grid(); // Matrix views DistMatrix<T> ATL(g), ATR(g), A00(g), A01(g), A02(g), ABL(g), ABR(g), A10(g), A11(g), A12(g), A20(g), A21(g), A22(g); DistMatrix<T> D11(g); DistMatrix<T,STAR,MC> BL_STAR_MC(g), BR_STAR_MC(g), B0_STAR_MC(g), B1_STAR_MC(g), B2_STAR_MC(g); DistMatrix<T,MR,STAR> BTTrans_MR_STAR(g), B0Trans_MR_STAR(g), BBTrans_MR_STAR(g), B1Trans_MR_STAR(g), B2Trans_MR_STAR(g); DistMatrix<T,MC,STAR> ZTTrans_MC_STAR(g), Z0Trans_MC_STAR(g), ZBTrans_MC_STAR(g), Z1Trans_MC_STAR(g), Z2Trans_MC_STAR(g); DistMatrix<T,MR,STAR> ZBTrans_MR_STAR(g), Z0Trans_MR_STAR(g), ZTTrans_MR_STAR(g), Z1Trans_MR_STAR(g), Z2Trans_MR_STAR(g); const int ratio = std::max( g.Height(), g.Width() ); PushBlocksizeStack( ratio*Blocksize() ); LockedPartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); LockedPartitionRight( B_STAR_MC, BL_STAR_MC, BR_STAR_MC, 0 ); LockedPartitionDown ( BTrans_MR_STAR, BTTrans_MR_STAR, BBTrans_MR_STAR, 0 ); PartitionDown ( ZTrans_MC_STAR, ZTTrans_MC_STAR, ZBTrans_MC_STAR, 0 ); PartitionDown ( ZTrans_MR_STAR, ZTTrans_MR_STAR, ZBTrans_MR_STAR, 0 ); while( ATL.Height() < A.Height() ) { LockedRepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ A01, A02, /*************/ /******************/ /**/ A10, /**/ A11, A12, ABL, /**/ ABR, A20, /**/ A21, A22 ); LockedRepartitionRight ( BL_STAR_MC, /**/ BR_STAR_MC, B0_STAR_MC, /**/ B1_STAR_MC, B2_STAR_MC ); LockedRepartitionDown ( BTTrans_MR_STAR, B0Trans_MR_STAR, /***************/ /***************/ B1Trans_MR_STAR, BBTrans_MR_STAR, B2Trans_MR_STAR ); RepartitionDown ( ZTTrans_MC_STAR, Z0Trans_MC_STAR, /***************/ /***************/ Z1Trans_MC_STAR, ZBTrans_MC_STAR, Z2Trans_MC_STAR ); RepartitionDown ( ZTTrans_MR_STAR, Z0Trans_MR_STAR, /***************/ /***************/ Z1Trans_MR_STAR, ZBTrans_MR_STAR, Z2Trans_MR_STAR ); D11.AlignWith( A11 ); //--------------------------------------------------------------------// D11 = A11; MakeTriangular( UPPER, D11 ); LocalGemm ( orientation, orientation, alpha, D11, B1_STAR_MC, T(1), Z1Trans_MR_STAR ); SetDiagonal( D11, T(0) ); LocalGemm ( NORMAL, NORMAL, alpha, D11, B1Trans_MR_STAR, T(1), Z1Trans_MC_STAR ); LocalGemm ( orientation, orientation, alpha, A12, B1_STAR_MC, T(1), Z2Trans_MR_STAR ); LocalGemm ( NORMAL, NORMAL, alpha, A12, B2Trans_MR_STAR, T(1), Z1Trans_MC_STAR ); //--------------------------------------------------------------------// D11.FreeAlignments(); SlideLockedPartitionDownDiagonal ( ATL, /**/ ATR, A00, A01, /**/ A02, /**/ A10, A11, /**/ A12, /*************/ /******************/ ABL, /**/ ABR, A20, A21, /**/ A22 ); SlideLockedPartitionRight ( BL_STAR_MC, /**/ BR_STAR_MC, B0_STAR_MC, B1_STAR_MC, /**/ B2_STAR_MC ); SlideLockedPartitionDown ( BTTrans_MR_STAR, B0Trans_MR_STAR, B1Trans_MR_STAR, /***************/ /***************/ BBTrans_MR_STAR, B2Trans_MR_STAR ); SlidePartitionDown ( ZTTrans_MC_STAR, Z0Trans_MC_STAR, Z1Trans_MC_STAR, /***************/ /***************/ ZBTrans_MC_STAR, Z2Trans_MC_STAR ); SlidePartitionDown ( ZTTrans_MR_STAR, Z0Trans_MR_STAR, Z1Trans_MR_STAR, /***************/ /***************/ ZBTrans_MR_STAR, Z2Trans_MR_STAR ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void SymmRUA ( T alpha, const DistMatrix<T>& A, const DistMatrix<T>& B, T beta, DistMatrix<T>& C, bool conjugate=false ) { #ifndef RELEASE PushCallStack("internal::SymmRUA"); if( A.Grid() != B.Grid() || B.Grid() != C.Grid() ) throw std::logic_error ("{A,B,C} must be distributed over the same grid"); #endif const Grid& g = A.Grid(); const Orientation orientation = ( conjugate ? ADJOINT : TRANSPOSE ); DistMatrix<T> BT(g), B0(g), BB(g), B1(g), B2(g); DistMatrix<T> CT(g), C0(g), CB(g), C1(g), C2(g); DistMatrix<T,MR, STAR> B1Trans_MR_STAR(g); DistMatrix<T,VC, STAR> B1Trans_VC_STAR(g); DistMatrix<T,STAR,MC > B1_STAR_MC(g); DistMatrix<T,MC, STAR> Z1Trans_MC_STAR(g); DistMatrix<T,MR, STAR> Z1Trans_MR_STAR(g); DistMatrix<T,MC, MR > Z1Trans(g); DistMatrix<T,MR, MC > Z1Trans_MR_MC(g); B1Trans_MR_STAR.AlignWith( A ); B1Trans_VC_STAR.AlignWith( A ); B1_STAR_MC.AlignWith( A ); Z1Trans_MC_STAR.AlignWith( A ); Z1Trans_MR_STAR.AlignWith( A ); Matrix<T> Z1Local; Scale( beta, C ); LockedPartitionDown ( B, BT, BB, 0 ); PartitionDown ( C, CT, CB, 0 ); while( CT.Height() < C.Height() ) { LockedRepartitionDown ( BT, B0, /**/ /**/ B1, BB, B2 ); RepartitionDown ( CT, C0, /**/ /**/ C1, CB, C2 ); Z1Trans_MR_MC.AlignWith( C1 ); Zeros( C1.Width(), C1.Height(), Z1Trans_MC_STAR ); Zeros( C1.Width(), C1.Height(), Z1Trans_MR_STAR ); //--------------------------------------------------------------------// B1Trans_MR_STAR.TransposeFrom( B1, conjugate ); B1Trans_VC_STAR = B1Trans_MR_STAR; B1_STAR_MC.TransposeFrom( B1Trans_VC_STAR, conjugate ); LocalSymmetricAccumulateRU ( orientation, alpha, A, B1_STAR_MC, B1Trans_MR_STAR, Z1Trans_MC_STAR, Z1Trans_MR_STAR ); Z1Trans.SumScatterFrom( Z1Trans_MC_STAR ); Z1Trans_MR_MC = Z1Trans; Z1Trans_MR_MC.SumScatterUpdate( T(1), Z1Trans_MR_STAR ); Transpose( Z1Trans_MR_MC.LockedMatrix(), Z1Local, conjugate ); Axpy( T(1), Z1Local, C1.Matrix() ); //--------------------------------------------------------------------// Z1Trans_MR_MC.FreeAlignments(); SlideLockedPartitionDown ( BT, B0, B1, /**/ /**/ BB, B2 ); SlidePartitionDown ( CT, C0, C1, /**/ /**/ CB, C2 ); } #ifndef RELEASE PopCallStack(); #endif }