diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc index 1a1becb69..16470fd8a 100644 --- a/internal/ceres/schur_complement_solver.cc +++ b/internal/ceres/schur_complement_solver.cc @@ -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); diff --git a/internal/ceres/trust_region_preprocessor.cc b/internal/ceres/trust_region_preprocessor.cc index 4020e4ca1..d3f912cdd 100644 --- a/internal/ceres/trust_region_preprocessor.cc +++ b/internal/ceres/trust_region_preprocessor.cc @@ -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));