HessenbergSchurInfo ScaLAPACKHelper ( AbstractDistMatrix<F>& HPre, AbstractDistMatrix<Complex<Base<F>>>& wPre, AbstractDistMatrix<F>& ZPre, const HessenbergSchurCtrl& ctrl ) { EL_DEBUG_CSE typedef Base<F> Real; AssertScaLAPACKSupport(); HessenbergSchurInfo info; ProxyCtrl proxyCtrl; proxyCtrl.colConstrain = true; proxyCtrl.rowConstrain = true; proxyCtrl.blockHeight = ctrl.blockHeight; proxyCtrl.blockWidth = ctrl.blockHeight; proxyCtrl.colAlign = 0; proxyCtrl.rowAlign = 0; proxyCtrl.colCut = 0; proxyCtrl.rowCut = 0; DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> HProx( HPre, proxyCtrl ); auto& H = HProx.Get(); const Int n = H.Height(); DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> ZProx( ZPre, proxyCtrl ); auto& Z = ZProx.Get(); if( !ctrl.accumulateSchurVecs ) Identity( Z, n, n ); DistMatrixWriteProxy<Complex<Real>,Complex<Real>,STAR,STAR> wProx( wPre ); auto& w = wProx.Get(); #ifdef EL_HAVE_SCALAPACK bool accumulateSchurVecs=true; bool useAED = ( ctrl.alg == HESSENBERG_SCHUR_AED ); auto descH = FillDesc( H ); scalapack::HessenbergSchur ( n, H.Buffer(), descH.data(), w.Buffer(), Z.Buffer(), descH.data(), ctrl.fullTriangle, accumulateSchurVecs, useAED ); // TODO(poulson): Find a way to fill in info? #endif return info; }
void ScaLAPACKHelper ( DistMatrix<F,MC,MR,BLOCK>& A, DistMatrix<F,MR,STAR,BLOCK>& householderScalars ) { EL_DEBUG_CSE AssertScaLAPACKSupport(); #ifdef EL_HAVE_SCALAPACK const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); householderScalars.AlignWith( A ); householderScalars.Resize( minDim, 1 ); auto descA = FillDesc( A ); scalapack::QR ( m, n, A.Buffer(), descA.data(), householderScalars.Buffer() ); #endif }
void QR ( DistMatrix<F,MC,MR,BLOCK>& A, DistMatrix<F,MR,STAR,BLOCK>& phase ) { DEBUG_CSE AssertScaLAPACKSupport(); #ifdef EL_HAVE_SCALAPACK const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); phase.AlignWith( A ); phase.Resize( minDim, 1 ); const int bHandle = blacs::Handle( A ); const int context = blacs::GridInit( bHandle, A ); auto descA = FillDesc( A, context ); scalapack::QR( m, n, A.Buffer(), descA.data(), phase.Buffer() ); blacs::FreeGrid( context ); blacs::FreeHandle( bHandle ); #endif }
SVDInfo ScaLAPACKHelper ( const AbstractDistMatrix<F>& APre, AbstractDistMatrix<F>& UPre, AbstractDistMatrix<Base<F>>& sPre, AbstractDistMatrix<F>& V, const SVDCtrl<Base<F>>& ctrl ) { DEBUG_CSE AssertScaLAPACKSupport(); SVDInfo info; #ifdef EL_HAVE_SCALAPACK typedef Base<F> Real; DistMatrix<F,MC,MR,BLOCK> A( APre ); DistMatrixWriteProxy<Real,Real,STAR,STAR> sProx(sPre); DistMatrixWriteProxy<F,F,MC,MR,BLOCK> UProx(UPre); auto& s = sProx.Get(); auto& U = UProx.Get(); const int m = A.Height(); const int n = A.Width(); const int k = Min(m,n); auto approach = ctrl.bidiagSVDCtrl.approach; if( approach == THIN_SVD || approach == COMPACT_SVD ) { Zeros( U, m, k ); DistMatrix<F,MC,MR,BLOCK> VH( A.Grid() ); Zeros( VH, k, n ); s.Resize( k, 1 ); auto descA = FillDesc( A ); auto descU = FillDesc( U ); auto descVH = FillDesc( VH ); scalapack::SVD ( m, n, A.Buffer(), descA.data(), s.Buffer(), U.Buffer(), descU.data(), VH.Buffer(), descVH.data() ); const bool compact = ( approach == COMPACT_SVD ); if( compact ) { const Real twoNorm = ( k==0 ? Real(0) : s.Get(0,0) ); const Real thresh = bidiag_svd::APosterioriThreshold ( m, n, twoNorm, ctrl.bidiagSVDCtrl ); Int rank = k; for( Int j=0; j<k; ++j ) { if( s.Get(j,0) <= thresh ) { rank = j; break; } } s.Resize( rank, 1 ); U.Resize( m, rank ); VH.Resize( rank, n ); } Adjoint( VH, V ); } else LogicError ("Only Thin and Compact singular value options currently supported"); #endif return info; }