mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 16:40:38 +08:00
Optimize J' * J in sparse_normal_cholesky_solver.
1. Add stype to the outerproduct computation to control the output matrix in upper or lower triangular matrix. For SuiteSparse, upper triangular matrix is generated. SuiteSparse can directly use this matrix format for cholesky without matrix transpose overhead. 2. Change the outerproduct computation to block multiplication. This reduces the computation complexity for the sort in preprocessing, also allows formulation of the block outerproduct computation as dense Eigen block matrix multiplication. 3. Solve 32 Tango problems on Qualcomm MSM8994 Cortex-A53 (1.55GHz) before change: 140 seconds after change: 131 seconds Change-Id: I8054114cef911de6a303310a448821ca296e4744
This commit is contained in:
@@ -275,14 +275,21 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingEigen(
|
||||
&event_logger);
|
||||
}
|
||||
|
||||
// Compute outerproduct to compressed row lower triangular matrix.
|
||||
// Eigen SimplicialLDLT default uses lower triangular part of matrix.
|
||||
// This can change to upper triangular matrix if specifying
|
||||
// Eigen::SimplicialLDLT< _MatrixType, _UpLo, _Ordering >
|
||||
// with _UpLo = Upper.
|
||||
const int stype = 1;
|
||||
|
||||
if (outer_product_.get() == NULL) {
|
||||
outer_product_.reset(
|
||||
CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
|
||||
*A, &pattern_));
|
||||
*A, stype, &pattern_));
|
||||
}
|
||||
|
||||
CompressedRowSparseMatrix::ComputeOuterProduct(
|
||||
*A, pattern_, outer_product_.get());
|
||||
*A, stype, pattern_, outer_product_.get());
|
||||
|
||||
// Map to an upper triangular column major matrix.
|
||||
//
|
||||
@@ -362,20 +369,21 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
|
||||
summary.termination_type = LINEAR_SOLVER_SUCCESS;
|
||||
summary.message = "Success.";
|
||||
|
||||
// Compute outerproduct to compressed row lower triangular matrix.
|
||||
// CXSparse Cholesky factorization uses lower triangular part of the matrix.
|
||||
const int stype = 1;
|
||||
|
||||
// Compute the normal equations. J'J delta = J'f and solve them
|
||||
// using a sparse Cholesky factorization. Notice that when compared
|
||||
// to SuiteSparse we have to explicitly compute the normal equations
|
||||
// before they can be factorized. CHOLMOD/SuiteSparse on the other
|
||||
// hand can just work off of Jt to compute the Cholesky
|
||||
// factorization of the normal equations.
|
||||
// using a sparse Cholesky factorization. Notice that we explicitly
|
||||
// compute the normal equations before they can be factorized.
|
||||
if (outer_product_.get() == NULL) {
|
||||
outer_product_.reset(
|
||||
CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
|
||||
*A, &pattern_));
|
||||
*A, stype, &pattern_));
|
||||
}
|
||||
|
||||
CompressedRowSparseMatrix::ComputeOuterProduct(
|
||||
*A, pattern_, outer_product_.get());
|
||||
*A, stype, pattern_, outer_product_.get());
|
||||
cs_di lhs =
|
||||
cxsparse_.CreateSparseMatrixTransposeView(outer_product_.get());
|
||||
|
||||
@@ -431,8 +439,26 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
|
||||
summary.num_iterations = 1;
|
||||
summary.message = "Success.";
|
||||
|
||||
// Compute outerproduct to compressed row upper triangular matrix.
|
||||
// This is the fastest option for the our default natural ordering
|
||||
// (see comment in cholmod_factorize.c:205 in SuiteSparse).
|
||||
const int stype = -1;
|
||||
|
||||
// Compute the normal equations. J'J delta = J'f and solve them
|
||||
// using a sparse Cholesky factorization. Notice that we explicitly
|
||||
// compute the normal equations before they can be factorized.
|
||||
if (outer_product_.get() == NULL) {
|
||||
outer_product_.reset(
|
||||
CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
|
||||
*A, stype, &pattern_));
|
||||
}
|
||||
|
||||
CompressedRowSparseMatrix::ComputeOuterProduct(
|
||||
*A, stype, pattern_, outer_product_.get());
|
||||
|
||||
const int num_cols = A->num_cols();
|
||||
cholmod_sparse lhs = ss_.CreateSparseMatrixTransposeView(A);
|
||||
cholmod_sparse lhs =
|
||||
ss_.CreateSparseMatrixTransposeView(outer_product_.get(), stype);
|
||||
event_logger.AddEvent("Setup");
|
||||
|
||||
if (options_.dynamic_sparsity) {
|
||||
@@ -443,7 +469,7 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
|
||||
if (options_.use_postordering) {
|
||||
factor_ = ss_.BlockAnalyzeCholesky(&lhs,
|
||||
A->col_blocks(),
|
||||
A->row_blocks(),
|
||||
A->col_blocks(),
|
||||
&summary.message);
|
||||
} else {
|
||||
if (options_.dynamic_sparsity) {
|
||||
|
||||
Reference in New Issue
Block a user