mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 08:34:37 +08:00
SPARSE_SCHUR + CX_SPARSE = Faster
There was a bug in the trust region preprocessor where no fill reducing ordering was computed for the case of SPARSE_SCHUR + CX_SPARSE but this was not signaled to SchurComplementSolver, so it was using a naive/natural ordering. To fix this two changes are made: 1. TrustRegionProcessor's logic for signaling the ordering to the linear solver has been re-worked. The surrounding code has also been re-organized for better readability. 2. In SchurComplementSolver::SolveReducedSystem the row and column block structure has been added to the CompressedRowSparseMatrix containing the Schur complement so that block AMD can be used. As a result of these changes the linear solve time for problem-744-543562-pre.txt has been brought down from 58 seconds to 35 seconds. Change-Id: I4d82efce05175260f97b1f925f8a1b4a9d650cae
This commit is contained in:
@@ -337,6 +337,9 @@ LinearSolver::Summary SparseSchurComplementSolver::SolveReducedLinearSystem(
|
||||
lhs->set_storage_type(CompressedRowSparseMatrix::LOWER_TRIANGULAR);
|
||||
}
|
||||
|
||||
*lhs->mutable_col_blocks() = blocks_;
|
||||
*lhs->mutable_row_blocks() = blocks_;
|
||||
|
||||
summary.num_iterations = 1;
|
||||
summary.termination_type = sparse_cholesky_->FactorAndSolve(
|
||||
lhs.get(), rhs(), solution, &summary.message);
|
||||
|
||||
@@ -121,6 +121,7 @@ bool ReorderProgram(PreprocessedProblem* pp) {
|
||||
&pp->error);
|
||||
}
|
||||
|
||||
|
||||
if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
|
||||
!options.dynamic_sparsity) {
|
||||
return ReorderProgramForSparseNormalCholesky(
|
||||
@@ -192,28 +193,40 @@ bool SetupLinearSolver(PreprocessedProblem* pp) {
|
||||
options.use_explicit_schur_complement;
|
||||
pp->linear_solver_options.dynamic_sparsity = options.dynamic_sparsity;
|
||||
pp->linear_solver_options.num_threads = options.num_linear_solver_threads;
|
||||
|
||||
// Ignore user's postordering preferences and force it to be true if
|
||||
// cholmod_camd is not available. This ensures that the linear
|
||||
// solver does not assume that a fill-reducing pre-ordering has been
|
||||
// done.
|
||||
pp->linear_solver_options.use_postordering = options.use_postordering;
|
||||
if (options.linear_solver_type == SPARSE_SCHUR &&
|
||||
options.sparse_linear_algebra_library_type == SUITE_SPARSE &&
|
||||
!SuiteSparse::IsConstrainedApproximateMinimumDegreeOrderingAvailable()) {
|
||||
pp->linear_solver_options.use_postordering = true;
|
||||
}
|
||||
|
||||
OrderingToGroupSizes(options.linear_solver_ordering.get(),
|
||||
&pp->linear_solver_options.elimination_groups);
|
||||
if (IsSchurType(pp->linear_solver_options.type)) {
|
||||
OrderingToGroupSizes(options.linear_solver_ordering.get(),
|
||||
&pp->linear_solver_options.elimination_groups);
|
||||
|
||||
// Schur type solvers expect at least two elimination groups. If
|
||||
// there is only one elimination group, then it is guaranteed that
|
||||
// this group only contains e_blocks. Thus we add a dummy
|
||||
// elimination group with zero blocks in it.
|
||||
if (IsSchurType(pp->linear_solver_options.type) &&
|
||||
pp->linear_solver_options.elimination_groups.size() == 1) {
|
||||
pp->linear_solver_options.elimination_groups.push_back(0);
|
||||
// Schur type solvers expect at least two elimination groups. If
|
||||
// there is only one elimination group, then it is guaranteed that
|
||||
// this group only contains e_blocks. Thus we add a dummy
|
||||
// elimination group with zero blocks in it.
|
||||
if (pp->linear_solver_options.elimination_groups.size() == 1) {
|
||||
pp->linear_solver_options.elimination_groups.push_back(0);
|
||||
}
|
||||
|
||||
if (options.linear_solver_type == SPARSE_SCHUR) {
|
||||
// When using SPARSE_SCHUR, we ignore the user's postordering
|
||||
// preferences in certain cases.
|
||||
//
|
||||
// 1. SUITE_SPARSE is the sparse linear algebra library requested
|
||||
// but cholmod_camd is not available.
|
||||
// 2. CX_SPARSE is the sparse linear algebra library requested.
|
||||
//
|
||||
// This ensures that the linear solver does not assume that a
|
||||
// fill-reducing pre-ordering has been done.
|
||||
//
|
||||
// TODO(sameeragarwal): Implement the reordering of parameter
|
||||
// blocks for CX_SPARSE.
|
||||
if ((options.sparse_linear_algebra_library_type == SUITE_SPARSE &&
|
||||
!SuiteSparse::
|
||||
IsConstrainedApproximateMinimumDegreeOrderingAvailable()) ||
|
||||
(options.sparse_linear_algebra_library_type == CX_SPARSE)) {
|
||||
pp->linear_solver_options.use_postordering = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pp->linear_solver.reset(LinearSolver::Create(pp->linear_solver_options));
|
||||
|
||||
Reference in New Issue
Block a user