Bugzilla – Attachment 110 Details for
Bug 206
JacobiSVD problem size constructor does not preallocate all of its resources
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
This bugzilla service is closed. All entries have been migrated to
https://gitlab.com/libeigen/eigen
[patch]
Removes explicit heap allocations from JacobiSVD and its preconditioners.
JacobiSVDnoAlloc.patch (text/plain), 14.15 KB, created by
Adolfo Rodriguez Tsouroukdissian
on 2011-03-01 18:44:00 UTC
(
hide
)
Description:
Removes explicit heap allocations from JacobiSVD and its preconditioners.
Filename:
MIME Type:
Creator:
Adolfo Rodriguez Tsouroukdissian
Created:
2011-03-01 18:44:00 UTC
Size:
14.15 KB
patch
obsolete
># HG changeset patch ># User Adolfo Rodriguez Tsourouksdissian <adolfo.rodriguez@pal-robotics.com> ># Date 1299001275 -3600 ># Node ID d8f5777a51ffd0a4156c78a48883f0b7554f56b3 ># Parent a3e7813246061ecefba7d32818d58f07aae69107 >Modified JacobiSVD and preconditioners to prevent explicit heap allocations at compute() time if problem size is known in advance. >Todo: QR module needs to be patched as well, because it's causing indirect allocations. > >diff -r a3e781324606 -r d8f5777a51ff Eigen/src/SVD/JacobiSVD.h >--- a/Eigen/src/SVD/JacobiSVD.h Tue Mar 01 16:45:46 2011 +0100 >+++ b/Eigen/src/SVD/JacobiSVD.h Tue Mar 01 18:41:15 2011 +0100 >@@ -61,9 +61,12 @@ > > struct qr_preconditioner_impl {}; > > template<typename MatrixType, int QRPreconditioner, int Case> >-struct qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false> >+class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false> > { >- static bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&) >+public: >+ typedef typename MatrixType::Index Index; >+ void resize(Index, Index) {} >+ bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&) > { > return false; > } >@@ -72,134 +75,218 @@ > /*** preconditioner using FullPivHouseholderQR ***/ > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> >+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> > { >- static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (rows != m_qr.rows() || cols != m_qr.cols()) m_qr = FullPivHouseholderQR<MatrixType>(rows, cols); >+ } >+ >+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.rows() > matrix.cols()) > { >- FullPivHouseholderQR<MatrixType> qr(matrix); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >- if(svd.m_computeFullU) svd.m_matrixU = qr.matrixQ(); >- if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); >+ m_qr.compute(matrix); >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >+ if(svd.m_computeFullU) svd.m_matrixU = m_qr.matrixQ(); >+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); > return true; > } > return false; > } >+private: >+ FullPivHouseholderQR<MatrixType> m_qr; > }; > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> >+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> > { >- static bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >+ MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >+ TransposeTypeWithSameStorageOrder; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (cols != m_qr.rows() || rows != m_qr.cols()) >+ { >+ m_qr = FullPivHouseholderQR<TransposeTypeWithSameStorageOrder>(cols, rows); >+ } >+ m_adjoint.resize(cols, rows); >+ } >+ >+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.cols() > matrix.rows()) > { >- typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >- MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >- TransposeTypeWithSameStorageOrder; >- FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >- if(svd.m_computeFullV) svd.m_matrixV = qr.matrixQ(); >- if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); >+ m_adjoint = matrix.adjoint(); >+ m_qr.compute(m_adjoint); >+ >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >+ if(svd.m_computeFullV) svd.m_matrixV = m_qr.matrixQ(); >+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); > return true; > } > else return false; > } >+private: >+ FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; >+ TransposeTypeWithSameStorageOrder m_adjoint; > }; > > /*** preconditioner using ColPivHouseholderQR ***/ > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> >+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> > { >- static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (rows != m_qr.rows() || cols != m_qr.cols()) m_qr = ColPivHouseholderQR<MatrixType>(rows, cols); >+ } >+ >+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.rows() > matrix.cols()) > { >- ColPivHouseholderQR<MatrixType> qr(matrix); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >- if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); >+ m_qr.compute(matrix); >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >+ if(svd.m_computeFullU) svd.m_matrixU = m_qr.householderQ(); > else if(svd.m_computeThinU) { > svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); >- qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); >+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); > } >- if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); >+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); > return true; > } > return false; > } >+ >+private: >+ ColPivHouseholderQR<MatrixType> m_qr; > }; > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> >+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> > { >- static bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >+ MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >+ TransposeTypeWithSameStorageOrder; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (cols != m_qr.rows() || rows != m_qr.cols()) >+ { >+ m_qr = ColPivHouseholderQR<TransposeTypeWithSameStorageOrder>(cols, rows); >+ } >+ m_adjoint.resize(cols, rows); >+ } >+ >+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.cols() > matrix.rows()) > { >- typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >- MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >- TransposeTypeWithSameStorageOrder; >- ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >- if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); >+ m_adjoint = matrix.adjoint(); >+ m_qr.compute(m_adjoint); >+ >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >+ if(svd.m_computeFullV) svd.m_matrixV = m_qr.householderQ(); > else if(svd.m_computeThinV) { > svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); >- qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); >+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); > } >- if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); >+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); > return true; > } > else return false; > } >+ >+private: >+ ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; >+ TransposeTypeWithSameStorageOrder m_adjoint; > }; > > /*** preconditioner using HouseholderQR ***/ > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> >+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> > { >- static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (rows != m_qr.rows() || cols != m_qr.cols()) m_qr = HouseholderQR<MatrixType>(rows, cols); >+ } >+ >+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.rows() > matrix.cols()) > { >- HouseholderQR<MatrixType> qr(matrix); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >- if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); >+ m_qr.compute(matrix); >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>(); >+ if(svd.m_computeFullU) svd.m_matrixU = m_qr.householderQ(); > else if(svd.m_computeThinU) { > svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); >- qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); >+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); > } > if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols()); > return true; > } > return false; > } >+private: >+ HouseholderQR<MatrixType> m_qr; > }; > > template<typename MatrixType> >-struct qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> >+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> > { >- static bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) >+public: >+ typedef typename MatrixType::Index Index; >+ typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >+ MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >+ TransposeTypeWithSameStorageOrder; >+ >+ void resize(Index rows, Index cols) >+ { >+ if (cols != m_qr.rows() || rows != m_qr.cols()) >+ { >+ m_qr = HouseholderQR<TransposeTypeWithSameStorageOrder>(cols, rows); >+ } >+ m_adjoint.resize(cols, rows); >+ } >+ >+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix) > { > if(matrix.cols() > matrix.rows()) > { >- typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime, >- MatrixType::Options, MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime> >- TransposeTypeWithSameStorageOrder; >- HouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint()); >- svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >- if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); >+ m_adjoint = matrix.adjoint(); >+ m_qr.compute(m_adjoint); >+ >+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint(); >+ if(svd.m_computeFullV) svd.m_matrixV = m_qr.householderQ(); > else if(svd.m_computeThinV) { > svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); >- qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); >+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); > } > if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows()); > return true; > } > else return false; > } >+ >+private: >+ HouseholderQR<TransposeTypeWithSameStorageOrder> m_qr; >+ TransposeTypeWithSameStorageOrder m_adjoint; > }; > > /*** 2x2 SVD implementation >@@ -510,6 +597,9 @@ > friend struct internal::svd_precondition_2x2_block_to_be_real; > template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything> > friend struct internal::qr_preconditioner_impl; >+ >+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols; >+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows; > }; > > template<typename MatrixType, int QRPreconditioner> >@@ -541,6 +631,8 @@ > : m_computeThinV ? m_diagSize > : 0); > m_workMatrix.resize(m_diagSize, m_diagSize); >+ m_qr_precond_morecols.resize(rows, cols); >+ m_qr_precond_morerows.resize(rows, cols); > } > > template<typename MatrixType, int QRPreconditioner> >@@ -554,9 +646,7 @@ > const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon(); > > /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */ >- >- if(!internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows>::run(*this, matrix) >- && !internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols>::run(*this, matrix)) >+ if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix)) > { > m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize); > if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 206
:
110
|
115
|
119
|
125
|
126
|
128
|
132
|
134
|
135
|
136
|
137
|
138
|
152
|
153
|
154
|
158
|
159