std::unique_ptr<ElDistVector> ElRBFInterpolation::interpolate( const std::unique_ptr<ElDistVector> & values ) { assert( Phi->Height() > 0 ); assert( H->Height() > 0 ); assert( values->Height() == Phi->Width() ); std::unique_ptr<ElDistVector> result( new ElDistVector( Phi->Grid() ) ); result->AlignRowsWith( *Phi ); El::DistMatrix<double> B = *values; if ( HCopy.Width() == 0 ) { HCopy = El::DistMatrix<double> ( *H ); El::DistMatrixReadProxy<double, double, El::MC, El::MR> AProx( HCopy ); auto & A = AProx.Get(); p = El::DistPermutation( A.Grid() ); dSub = El::DistMatrix<double, El::MD, El::STAR> ( A.Grid() ); El::LDL( A, dSub, p, false, El::LDLPivotCtrl<El::Base<double> >() ); } El::DistMatrixReadProxy<double, double, El::MC, El::MR> AProx( HCopy ); El::DistMatrixReadWriteProxy<double, double, El::MC, El::MR> BProx( B ); auto & A = AProx.Get(); auto & B_LU = BProx.Get(); El::ldl::SolveAfter( A, dSub, p, B_LU, false ); El::Gemm( El::Orientation::NORMAL, El::Orientation::NORMAL, 1.0, *Phi, B, *result ); return result; }
void HermitianPseudoinverse ( UpperOrLower uplo, ElementalMatrix<F>& APre, Base<F> tolerance ) { DEBUG_CSE typedef Base<F> Real; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& g = A.Grid(); // Get the EVD of A // TODO: Use a relative eigenvalue lower-bound DistMatrix<Real,VR,STAR> w(g); DistMatrix<F> Z(g); HermitianEig( uplo, A, w, Z ); if( tolerance == Real(0) ) { // Set the tolerance equal to n ||A||_2 eps const Int n = Z.Height(); const Real eps = limits::Epsilon<Real>(); const Real twoNorm = MaxNorm( w ); tolerance = n*twoNorm*eps; } // Invert above the tolerance auto omegaMap = [=]( Real omega ) { return ( omega < tolerance ? Real(0) : 1/omega ); }; EntrywiseMap( w, function<Real(Real)>(omegaMap) ); // Form the pseudoinverse HermitianFromEVD( uplo, A, w, Z ); }
void Pseudoinverse( ElementalMatrix<F>& APre, Base<F> tolerance ) { DEBUG_CSE typedef Base<F> Real; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Int m = A.Height(); const Int n = A.Width(); const Grid& g = A.Grid(); const Real eps = limits::Epsilon<Real>(); // Get the SVD of A DistMatrix<Real,VR,STAR> s(g); DistMatrix<F> U(g), V(g); SVDCtrl<Real> ctrl; ctrl.overwrite = true; ctrl.bidiagSVDCtrl.approach = COMPACT_SVD; // TODO(poulson): Let the user change these defaults ctrl.bidiagSVDCtrl.tolType = RELATIVE_TO_MAX_SING_VAL_TOL; ctrl.bidiagSVDCtrl.tol = ( tolerance == Real(0) ? Max(m,n)*eps : tolerance ); SVD( A, U, s, V, ctrl ); // Scale U with the inverted (nonzero) singular values, U := U / Sigma DiagonalSolve( RIGHT, NORMAL, s, U ); // Form pinvA = (U Sigma V^H)^H = V (U Sigma)^H Gemm( NORMAL, ADJOINT, F(1), V, U, A ); }
void Overwrite ( Orientation orientation, ElementalMatrix<F>& APre, const ElementalMatrix<F>& B, ElementalMatrix<F>& X ) { DEBUG_ONLY(CSE cse("ls::Overwrite")) DistMatrixReadProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); DistMatrix<F,MD,STAR> t(A.Grid()); DistMatrix<Base<F>,MD,STAR> d(A.Grid()); const Int m = A.Height(); const Int n = A.Width(); if( m >= n ) { QR( A, t, d ); qr::SolveAfter( orientation, A, t, d, B, X ); } else { LQ( A, t, d ); lq::SolveAfter( orientation, A, t, d, B, X ); } }
void HermitianSign ( UpperOrLower uplo, AbstractDistMatrix<Field>& APre, const HermitianEigCtrl<Field>& ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre ); auto& A = AProx.Get(); // Get the EVD of A typedef Base<Field> Real; const Grid& g = A.Grid(); DistMatrix<Real,VR,STAR> w(g); DistMatrix<Field> Q(g); auto ctrlMod( ctrl ); ctrlMod.tridiagEigCtrl.sort = UNSORTED; HermitianEig( uplo, A, w, Q, ctrlMod ); const Int numLocalEigs = w.LocalHeight(); for( Int iLoc=0; iLoc<numLocalEigs; ++iLoc ) { const Real omega = w.GetLocal(iLoc,0); if( omega >= 0 ) w.SetLocal(iLoc,0,Real(1)); else w.SetLocal(iLoc,0,Real(-1)); } // Reform the Hermitian matrix with the modified eigenvalues HermitianFromEVD( uplo, A, w, Q ); }
void NormalUniformSpectrum ( ElementalMatrix<Complex<Real>>& APre, Int n, Complex<Real> center, Real radius ) { EL_DEBUG_CSE typedef Complex<Real> C; DistMatrixWriteProxy<C,C,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& grid = A.Grid(); A.Resize( n, n ); // Form d and D vector<C> d( n ); if( grid.Rank() == 0 ) for( Int j=0; j<n; ++j ) d[j] = SampleBall<C>( center, radius ); mpi::Broadcast( d.data(), n, 0, grid.Comm() ); Diagonal( A, d ); // Apply a Haar matrix from both sides DistMatrix<C> Q(grid); DistMatrix<C,MD,STAR> t(grid); DistMatrix<Real,MD,STAR> s(grid); ImplicitHaar( Q, t, s, n ); // Copy the result into the correct distribution qr::ApplyQ( LEFT, NORMAL, Q, t, s, A ); qr::ApplyQ( RIGHT, ADJOINT, Q, t, s, A ); }
void UN_C ( T alpha, const AbstractDistMatrix<T>& APre, AbstractDistMatrix<T>& CPre, bool conjugate=false ) { EL_DEBUG_CSE const Int r = APre.Width(); const Int bsize = Blocksize(); const Grid& g = APre.Grid(); DistMatrixReadProxy<T,T,MC,MR> AProx( APre ); DistMatrixReadWriteProxy<T,T,MC,MR> CProx( CPre ); auto& A = AProx.GetLocked(); auto& C = CProx.Get(); // Temporary distributions DistMatrix<T,MC, STAR> A1_MC_STAR(g); DistMatrix<T,VR, STAR> A1_VR_STAR(g); DistMatrix<T,STAR,MR > A1Trans_STAR_MR(g); A1_MC_STAR.AlignWith( C ); A1_VR_STAR.AlignWith( C ); A1Trans_STAR_MR.AlignWith( C ); for( Int k=0; k<r; k+=bsize ) { const Int nb = Min(bsize,r-k); auto A1 = A( ALL, IR(k,k+nb) ); A1_VR_STAR = A1_MC_STAR = A1; Transpose( A1_VR_STAR, A1Trans_STAR_MR, conjugate ); LocalTrrk( UPPER, alpha, A1_MC_STAR, A1Trans_STAR_MR, T(1), C ); } }
void NMF ( const ElementalMatrix<Real>& APre, ElementalMatrix<Real>& XPre, ElementalMatrix<Real>& YPre, const NMFCtrl<Real>& ctrl ) { DEBUG_ONLY(CSE cse("NMF")) DistMatrixReadProxy<Real,Real,MC,MR> AProx( APre ); DistMatrixReadWriteProxy<Real,Real,MC,MR> XProx( XPre ); DistMatrixWriteProxy<Real,Real,MC,MR> YProx( YPre ); auto& A = AProx.GetLocked(); auto& X = XProx.Get(); auto& Y = YProx.Get(); DistMatrix<Real> AAdj(A.Grid()), XAdj(A.Grid()), YAdj(A.Grid()); Adjoint( A, AAdj ); for( Int iter=0; iter<ctrl.maxIter; ++iter ) { NNLS( X, A, YAdj, ctrl.nnlsCtrl ); Adjoint( YAdj, Y ); NNLS( Y, AAdj, XAdj, ctrl.nnlsCtrl ); Adjoint( XAdj, X ); } }
void Explicit( AbstractDistMatrix<F>& L, AbstractDistMatrix<F>& APre ) { EL_DEBUG_CSE const Grid& g = APre.Grid(); DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); LQ( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); auto AL = A( IR(0,m), IR(0,minDim) ); Copy( AL, L ); MakeTrapezoidal( LOWER, L ); // TODO: Replace this with an in-place expansion of Q DistMatrix<F> Q(g); Identity( Q, A.Height(), A.Width() ); lq::ApplyQ( RIGHT, NORMAL, A, householderScalars, signature, Q ); Copy( Q, APre ); }
SafeProduct<Base<F>> AfterCholesky ( UpperOrLower uplo, const ElementalMatrix<F>& APre ) { DEBUG_CSE DistMatrixReadProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.GetLocked(); typedef Base<F> Real; const Int n = A.Height(); const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> d(g); GetDiagonal( A, d ); Real localKappa = 0; if( d.Participating() ) { const Real scale = Real(n)/Real(2); const Int nLocalDiag = d.LocalHeight(); for( Int iLoc=0; iLoc<nLocalDiag; ++iLoc ) { const Real delta = RealPart(d.GetLocal(iLoc,0)); localKappa += Log(delta)/scale; } } SafeProduct<Real> det( n ); det.kappa = mpi::AllReduce( localKappa, g.VCComm() ); det.rho = Real(1); return det; }
void Overwrite ( Orientation orientation, ElementalMatrix<F>& APre, const ElementalMatrix<F>& B, ElementalMatrix<F>& X ) { DEBUG_CSE DistMatrixReadProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); DistMatrix<F,MD,STAR> phase(A.Grid()); DistMatrix<Base<F>,MD,STAR> signature(A.Grid()); const Int m = A.Height(); const Int n = A.Width(); if( m >= n ) { QR( A, phase, signature ); qr::SolveAfter( orientation, A, phase, signature, B, X ); } else { LQ( A, phase, signature ); lq::SolveAfter( orientation, A, phase, signature, B, X ); } }
void ExplicitUnitary ( ElementalMatrix<F>& APre, bool thinQR, const QRCtrl<Base<F>>& ctrl ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); if( ctrl.colPiv ) { DistPermutation Omega(g); QR( A, householderScalars, signature, Omega, ctrl ); } else QR( A, householderScalars, signature ); if( thinQR ) { A.Resize( A.Height(), householderScalars.Height() ); ExpandPackedReflectors ( LOWER, VERTICAL, CONJUGATED, 0, A, householderScalars ); DiagonalScale( RIGHT, NORMAL, signature, A ); } else { auto ACopy = A; // TODO: Use an extension of ExpandPackedReflectors to make this faster Identity( A, A.Height(), A.Height() ); qr::ApplyQ( LEFT, NORMAL, ACopy, householderScalars, signature, A ); } }
void ApplyQ ( LeftOrRight side, Orientation orientation, const AbstractDistMatrix<F>& APre, const AbstractDistMatrix<F>& householderScalars, const AbstractDistMatrix<Base<F>>& signature, AbstractDistMatrix<F>& BPre ) { EL_DEBUG_CSE const bool normal = (orientation==NORMAL); const bool onLeft = (side==LEFT); const bool applyDFirst = normal==onLeft; const Int minDim = Min(APre.Height(),APre.Width()); const ForwardOrBackward direction = ( normal==onLeft ? BACKWARD : FORWARD ); const Conjugation conjugation = ( normal ? CONJUGATED : UNCONJUGATED ); DistMatrixReadProxy<F,F,MC,MR> AProx( APre ); DistMatrixReadWriteProxy<F,F,MC,MR> BProx( BPre ); auto& A = AProx.GetLocked(); auto& B = BProx.Get(); const Int m = B.Height(); const Int n = B.Width(); if( applyDFirst ) { if( onLeft ) { auto BTop = B( IR(0,minDim), IR(0,n) ); DiagonalScale( side, orientation, signature, BTop ); } else { auto BLeft = B( IR(0,m), IR(0,minDim) ); DiagonalScale( side, orientation, signature, BLeft ); } } ApplyPackedReflectors ( side, LOWER, VERTICAL, direction, conjugation, 0, A, householderScalars, B ); if( !applyDFirst ) { if( onLeft ) { auto BTop = B( IR(0,minDim), IR(0,n) ); DiagonalScale( side, orientation, signature, BTop ); } else { auto BLeft = B( IR(0,m), IR(0,minDim) ); DiagonalScale( side, orientation, signature, BLeft ); } } }
void Sign( ElementalMatrix<F>& APre, const SignCtrl<Base<F>> ctrl ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); sign::Newton( A, ctrl ); }
void Sign( AbstractDistMatrix<Field>& APre, const SignCtrl<Base<Field>> ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre ); auto& A = AProx.Get(); sign::Newton( A, ctrl ); }
SVDInfo GolubReinsch ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Base<Field>>& s, const SVDCtrl<Base<Field>>& ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre ); auto& A = AProx.Get(); return GolubReinsch( A, s, ctrl ); }
void RuizEquil ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Base<Field>>& dRowPre, AbstractDistMatrix<Base<Field>>& dColPre, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; ElementalProxyCtrl control; control.colConstrain = true; control.rowConstrain = true; control.colAlign = 0; control.rowAlign = 0; DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre, control ); DistMatrixWriteProxy<Real,Real,MC,STAR> dRowProx( dRowPre, control ); DistMatrixWriteProxy<Real,Real,MR,STAR> dColProx( dColPre, control ); auto& A = AProx.Get(); auto& dRow = dRowProx.Get(); auto& dCol = dColProx.Get(); const Int m = A.Height(); const Int n = A.Width(); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; DistMatrix<Real,MC,STAR> rowScale(A.Grid()); DistMatrix<Real,MR,STAR> colScale(A.Grid()); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, colScale ); EntrywiseMap( colScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, colScale, dCol ); DiagonalSolve( RIGHT, NORMAL, colScale, A ); // Rescale the rows // ---------------- RowMaxNorms( A, rowScale ); EntrywiseMap( rowScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, rowScale, dRow ); DiagonalSolve( LEFT, NORMAL, rowScale, A ); } SetIndent( indent ); }
void HermitianSign ( UpperOrLower uplo, ElementalMatrix<F>& APre, ElementalMatrix<F>& NPre, const HermitianEigCtrl<F>& ctrl ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,MC,MR> NProx( NPre ); auto& A = AProx.Get(); auto& N = NProx.Get(); // Get the EVD of A typedef Base<F> Real; const Grid& g = A.Grid(); DistMatrix<Real,VR,STAR> w(g); DistMatrix<F> Q(g); auto ctrlMod( ctrl ); ctrlMod.tridiagEigCtrl.sort = UNSORTED; HermitianEig( uplo, A, w, Q, ctrlMod ); const Int n = A.Height(); const Int numLocalEigs = w.LocalHeight(); DistMatrix<Real,VR,STAR> wSgn(g), wAbs(g); wSgn.AlignWith( w ); wAbs.AlignWith( w ); wSgn.Resize( n, 1 ); wAbs.Resize( n, 1 ); for( Int iLoc=0; iLoc<numLocalEigs; ++iLoc ) { const Real omega = w.GetLocal(iLoc,0); if( omega >= 0 ) { wSgn.SetLocal(iLoc,0,Real(1)); wAbs.SetLocal(iLoc,0,omega); } else { wSgn.SetLocal(iLoc,0,Real(-1)); wAbs.SetLocal(iLoc,0,-omega); } } // Form the Hermitian matrix with the modified eigenvalues HermitianFromEVD( uplo, A, wSgn, Q ); HermitianFromEVD( uplo, N, wAbs, Q ); }
void GolubReinsch ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Field>& UPre, AbstractDistMatrix<Base<Field>>& s, AbstractDistMatrix<Field>& VPre, const SVDCtrl<Base<Field>>& ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre ); DistMatrixWriteProxy<Field,Field,MC,MR> UProx( UPre ); DistMatrixWriteProxy<Field,Field,MC,MR> VProx( VPre ); auto& A = AProx.Get(); auto& U = UProx.Get(); auto& V = VProx.Get(); return GolubReinsch( A, U, s, V, ctrl ); }
void Sign ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Field>& NPre, const SignCtrl<Base<Field>> ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre ); DistMatrixWriteProxy<Field,Field,MC,MR> NProx( NPre ); auto& A = AProx.Get(); auto& N = NProx.Get(); DistMatrix<Field> ACopy( A ); sign::Newton( A, ctrl ); Gemm( NORMAL, NORMAL, Field(1), A, ACopy, N ); }
void Sign ( ElementalMatrix<F>& APre, ElementalMatrix<F>& NPre, const SignCtrl<Base<F>> ctrl ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,MC,MR> NProx( NPre ); auto& A = AProx.Get(); auto& N = NProx.Get(); DistMatrix<F> ACopy( A ); sign::Newton( A, ctrl ); Gemm( NORMAL, NORMAL, F(1), A, ACopy, N ); }
void Householder ( AbstractDistMatrix<F>& APre, AbstractDistMatrix<F>& householderScalarsPre, AbstractDistMatrix<Base<F>>& signaturePre ) { DEBUG_CSE DEBUG_ONLY(AssertSameGrids( APre, householderScalarsPre, signaturePre )) const Int m = APre.Height(); const Int n = APre.Width(); const Int minDim = Min(m,n); const Int iOff = m-minDim; const Int jOff = n-minDim; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,MD,STAR> householderScalarsProx( householderScalarsPre ); DistMatrixWriteProxy<Base<F>,Base<F>,MD,STAR> signatureProx( signaturePre ); auto& A = AProx.Get(); auto& householderScalars = householderScalarsProx.Get(); auto& signature = signatureProx.Get(); householderScalars.Resize( minDim, 1 ); signature.Resize( minDim, 1 ); const Int bsize = Blocksize(); const Int kLast = LastOffset( minDim, bsize ); for( Int k=kLast; k>=0; k-=bsize ) { const Int nb = Min(bsize,minDim-k); const Int ki = k + iOff; const Int kj = k + jOff; const Range<Int> ind0Vert( 0, ki ), ind1( k, k+nb ), ind1Vert( ki, ki+nb ), indL( 0, kj+nb ); auto A0L = A( ind0Vert, indL ); auto A1L = A( ind1Vert, indL ); auto householderScalars1 = householderScalars( ind1, ALL ); auto sig1 = signature( ind1, ALL ); PanelHouseholder( A1L, householderScalars1, sig1 ); ApplyQ( RIGHT, ADJOINT, A1L, householderScalars1, sig1, A0L ); } }
void HermitianFromEVD ( UpperOrLower uplo, AbstractDistMatrix<F>& APre, const AbstractDistMatrix<Base<F>>& wPre, const AbstractDistMatrix<F>& ZPre ) { DEBUG_CSE typedef Base<F> Real; DistMatrixWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixReadProxy<Real,Real,VR,STAR> wProx( wPre ); DistMatrixReadProxy<F,F,MC,MR> ZProx( ZPre ); auto& A = AProx.Get(); auto& w = wProx.GetLocked(); auto& Z = ZProx.GetLocked(); const Grid& g = A.Grid(); DistMatrix<F,MC, STAR> Z1_MC_STAR(g); DistMatrix<F,VR, STAR> Z1_VR_STAR(g); DistMatrix<F,STAR,MR > Z1Adj_STAR_MR(g); const Int m = Z.Height(); const Int n = Z.Width(); A.Resize( m, m ); if( uplo == LOWER ) MakeTrapezoidal( UPPER, A, 1 ); else MakeTrapezoidal( LOWER, A, -1 ); const Int bsize = Blocksize(); for( Int k=0; k<n; k+=bsize ) { const Int nb = Min(bsize,n-k); auto Z1 = Z( ALL, IR(k,k+nb) ); auto w1 = w( IR(k,k+nb), ALL ); Z1_MC_STAR.AlignWith( A ); Z1_MC_STAR = Z1; Z1_VR_STAR.AlignWith( A ); Z1_VR_STAR = Z1_MC_STAR; DiagonalScale( RIGHT, NORMAL, w1, Z1_VR_STAR ); Z1Adj_STAR_MR.AlignWith( A ); Adjoint( Z1_VR_STAR, Z1Adj_STAR_MR ); LocalTrrk( uplo, F(1), Z1_MC_STAR, Z1Adj_STAR_MR, F(1), A ); } }
void LT_Dot ( T alpha, const AbstractDistMatrix<T>& APre, AbstractDistMatrix<T>& CPre, const bool conjugate, Int blockSize=2000 ) { EL_DEBUG_CSE const Int n = CPre.Height(); const Grid& g = APre.Grid(); const Orientation orient = ( conjugate ? ADJOINT : TRANSPOSE ); DistMatrixReadProxy<T,T,VC,STAR> AProx( APre ); auto& A = AProx.GetLocked(); DistMatrixReadWriteProxy<T,T,MC,MR> CProx( CPre ); auto& C = CProx.Get(); DistMatrix<T,STAR,STAR> Z( blockSize, blockSize, g ); Zero( Z ); for( Int kOuter=0; kOuter<n; kOuter+=blockSize ) { const Int nbOuter = Min(blockSize,n-kOuter); const Range<Int> indOuter( kOuter, kOuter+nbOuter ); auto A1 = A( ALL, indOuter ); auto C11 = C( indOuter, indOuter ); Z.Resize( nbOuter, nbOuter ); Syrk( LOWER, TRANSPOSE, alpha, A1.Matrix(), Z.Matrix(), conjugate ); AxpyContract( T(1), Z, C11 ); for( Int kInner=kOuter+nbOuter; kInner<n; kInner+=blockSize ) { const Int nbInner = Min(blockSize,n-kInner); const Range<Int> indInner( kInner, kInner+nbInner ); auto A2 = A( ALL, indInner ); auto C21 = C( indInner, indOuter ); LocalGemm( orient, NORMAL, alpha, A1, A2, Z ); AxpyContract( T(1), Z, C21 ); } } }
void SUMMA_NTDot ( Orientation orientB, T alpha, const AbstractDistMatrix<T>& APre, const AbstractDistMatrix<T>& BPre, AbstractDistMatrix<T>& CPre, Int blockSize=2000 ) { EL_DEBUG_CSE const Int m = CPre.Height(); const Int n = CPre.Width(); const Grid& g = APre.Grid(); DistMatrixReadProxy<T,T,STAR,VC> AProx( APre ); auto& A = AProx.GetLocked(); ElementalProxyCtrl BCtrl; BCtrl.rowConstrain = true; BCtrl.rowAlign = A.RowAlign(); DistMatrixReadProxy<T,T,STAR,VC> BProx( BPre, BCtrl ); auto& B = BProx.GetLocked(); DistMatrixReadWriteProxy<T,T,MC,MR> CProx( CPre ); auto& C = CProx.Get(); DistMatrix<T,STAR,STAR> C11_STAR_STAR(g); for( Int kOuter=0; kOuter<m; kOuter+=blockSize ) { const Int nbOuter = Min(blockSize,m-kOuter); const Range<Int> indOuter( kOuter, kOuter+nbOuter ); auto A1 = A( indOuter, ALL ); for( Int kInner=0; kInner<n; kInner+=blockSize ) { const Int nbInner = Min(blockSize,n-kInner); const Range<Int> indInner( kInner, kInner+nbInner ); auto B1 = B( indInner, ALL ); auto C11 = C( indOuter, indInner ); LocalGemm( NORMAL, orientB, alpha, A1, B1, C11_STAR_STAR ); AxpyContract( T(1), C11_STAR_STAR, C11 ); } } }
void Explicit ( ElementalMatrix<F>& APre, ElementalMatrix<F>& R, bool thinQR, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CSE cse("qr::Explicit")) DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> t(g); DistMatrix<Base<F>,MD,STAR> d(g); if( ctrl.colPiv ) { DistPermutation Omega(g); QR( A, t, d, Omega, ctrl ); } else QR( A, t, d ); const Int m = A.Height(); const Int n = A.Width(); const Int numIts = t.Height(); auto AT = A( IR(0,numIts), IR(0,n) ); Copy( AT, R ); MakeTrapezoidal( UPPER, R ); if( thinQR ) { A.Resize( m, numIts ); ExpandPackedReflectors( LOWER, VERTICAL, CONJUGATED, 0, A, t ); DiagonalScale( RIGHT, NORMAL, d, A ); } else { auto ACopy = A; // TODO: Use an extension of ExpandPackedReflectors to make this faster Identity( A, A.Height(), A.Height() ); qr::ApplyQ( LEFT, NORMAL, ACopy, t, d, A ); } }
void L1DistanceMatrix(direction_t dirA, direction_t dirB, T alpha, const El::ElementalMatrix<T> &APre, const El::ElementalMatrix<T> &BPre, T beta, El::ElementalMatrix<T> &CPre) { if (dirA == base::COLUMNS && dirB == base::COLUMNS) { // Use a SUMMA-like routine, with C as stationary // Basically an adaptation of Elementals TN case for stationary C. const El::Int m = CPre.Height(); const El::Int n = CPre.Width(); const El::Int sumDim = BPre.Height(); const El::Int bsize = El::Blocksize(); const El::Grid& g = APre.Grid(); El::DistMatrixReadProxy<T, T, El::MC, El::MR> AProx(APre); El::DistMatrixReadProxy<T, T, El::MC, El::MR> BProx(BPre); El::DistMatrixReadWriteProxy<T, T, El::MC, El::MR> CProx(CPre); auto& A = AProx.GetLocked(); auto& B = BProx.GetLocked(); auto& C = CProx.Get(); // Temporary distributions El::DistMatrix<T, El::STAR, El::MC> A1_STAR_MC(g); El::DistMatrix<T, El::STAR, El::MR> B1_STAR_MR(g); A1_STAR_MC.AlignWith(C); B1_STAR_MR.AlignWith(C); El::Scale(beta, C); for(El::Int k = 0; k < sumDim; k += bsize) { const El::Int nb = std::min(bsize,sumDim-k); auto A1 = A(El::IR(k,k+nb), El::IR(0,m)); auto B1 = B(El::IR(k,k+nb), El::IR(0,n)); A1_STAR_MC = A1; B1_STAR_MR = B1; L1DistanceMatrix(base::COLUMNS, base::COLUMNS, alpha, A1_STAR_MC.LockedMatrix(), B1_STAR_MR.LockedMatrix(), T(1.0), C.Matrix()); } } // TODO the rest of the cases. }
void SUMMA_NTC ( Orientation orientB, T alpha, const AbstractDistMatrix<T>& APre, const AbstractDistMatrix<T>& BPre, AbstractDistMatrix<T>& CPre ) { EL_DEBUG_CSE const Int sumDim = APre.Width(); const Int bsize = Blocksize(); const Grid& g = APre.Grid(); const bool conjugate = ( orientB == ADJOINT ); DistMatrixReadProxy<T,T,MC,MR> AProx( APre ); DistMatrixReadProxy<T,T,MC,MR> BProx( BPre ); DistMatrixReadWriteProxy<T,T,MC,MR> CProx( CPre ); auto& A = AProx.GetLocked(); auto& B = BProx.GetLocked(); auto& C = CProx.Get(); // Temporary distributions DistMatrix<T,MC,STAR> A1_MC_STAR(g); DistMatrix<T,VR,STAR> B1_VR_STAR(g); DistMatrix<T,STAR,MR> B1Trans_STAR_MR(g); A1_MC_STAR.AlignWith( C ); B1_VR_STAR.AlignWith( C ); B1Trans_STAR_MR.AlignWith( C ); for( Int k=0; k<sumDim; k+=bsize ) { const Int nb = Min(bsize,sumDim-k); auto A1 = A( ALL, IR(k,k+nb) ); auto B1 = B( ALL, IR(k,k+nb) ); A1_MC_STAR = A1; B1_VR_STAR = B1; Transpose( B1_VR_STAR, B1Trans_STAR_MR, conjugate ); // C[MC,MR] += alpha A1[MC,*] (B1[MR,*])^T LocalGemm ( NORMAL, NORMAL, alpha, A1_MC_STAR, B1Trans_STAR_MR, T(1), C ); } }
void ExplicitUnitary( AbstractDistMatrix<F>& APre ) { EL_DEBUG_CSE const Grid& g = APre.Grid(); DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); LQ( A, householderScalars, signature ); // TODO: Replace this with an in-place expansion of Q DistMatrix<F> Q(g); Q.AlignWith( A ); Identity( Q, A.Height(), A.Width() ); lq::ApplyQ( RIGHT, NORMAL, A, householderScalars, signature, Q ); Copy( Q, APre ); }
Int ADMM ( const ElementalMatrix<Real>& APre, const ElementalMatrix<Real>& B, ElementalMatrix<Real>& X, const ADMMCtrl<Real>& ctrl ) { DEBUG_CSE const Real maxReal = limits::Max<Real>(); DistMatrixReadProxy<Real,Real,MC,MR> AProx( APre ); auto& A = AProx.GetLocked(); DistMatrix<Real> Q(A.Grid()), C(A.Grid()); Herk( LOWER, ADJOINT, Real(1), A, Q ); Gemm( ADJOINT, NORMAL, Real(-1), A, B, C ); return qp::box::ADMM( Q, C, Real(0), maxReal, X, ctrl ); }