mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 16:40:38 +08:00
SuiteSparse errors do not cause a fatal crash.
1. Move LinearSolverTerminationType to ceres::internal. 2. Add FATAL_ERROR as a new enum to LinearSolverTerminationType. 3. Pipe SuiteSparse errors via a LinearSolverTerminationType so to distinguish between fatal and non-fatal errors. 4. Update levenberg marquardt and dogleg strategies to deal with FATAL_ERROR. 5. Update trust_region_minimizer to terminate when FATAL_ERROR is encountered. 6. Remove SuiteSparse::SolveCholesky as it screws up the error handling. 7. Fix all clients calling SuiteSparse to handle the result of SuiteSparse::Cholesky correctly. 8. Remove fatal failures in SuiteSparse when symbolic factorization fails. 9. Fix all clients of SuiteSparse to deal with null symbolic factors. This is a temporary fix to deal with some production problems. A more extensive cleanup and testing regime will be put in place in a subsequent CL. Change-Id: I1f60d539799dd95db7ecc340911e261fa4824f92
This commit is contained in:
@@ -195,34 +195,50 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
|
||||
VectorRef(x, num_cols).setZero();
|
||||
|
||||
cholmod_sparse lhs = ss_.CreateSparseMatrixTransposeView(A);
|
||||
cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols);
|
||||
|
||||
event_logger.AddEvent("Setup");
|
||||
|
||||
if (factor_ == NULL) {
|
||||
if (options_.use_postordering) {
|
||||
factor_ =
|
||||
CHECK_NOTNULL(ss_.BlockAnalyzeCholesky(&lhs,
|
||||
A->col_blocks(),
|
||||
A->row_blocks()));
|
||||
factor_ = ss_.BlockAnalyzeCholesky(&lhs,
|
||||
A->col_blocks(),
|
||||
A->row_blocks());
|
||||
} else {
|
||||
factor_ =
|
||||
CHECK_NOTNULL(ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs));
|
||||
factor_ = ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs);
|
||||
}
|
||||
}
|
||||
|
||||
event_logger.AddEvent("Analysis");
|
||||
|
||||
cholmod_dense* sol = ss_.SolveCholesky(&lhs, factor_, rhs);
|
||||
if (factor_ == NULL) {
|
||||
if (per_solve_options.D != NULL) {
|
||||
A->DeleteRows(num_cols);
|
||||
}
|
||||
|
||||
summary.termination_type = FATAL_ERROR;
|
||||
return summary;
|
||||
}
|
||||
|
||||
const LinearSolverTerminationType status = ss_.Cholesky(&lhs, factor_);
|
||||
if (status != TOLERANCE) {
|
||||
if (per_solve_options.D != NULL) {
|
||||
A->DeleteRows(num_cols);
|
||||
}
|
||||
|
||||
summary.termination_type = FATAL_ERROR;
|
||||
return summary;
|
||||
}
|
||||
|
||||
cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols);
|
||||
cholmod_dense* sol = ss_.Solve(factor_, rhs);
|
||||
event_logger.AddEvent("Solve");
|
||||
|
||||
ss_.Free(rhs);
|
||||
rhs = NULL;
|
||||
|
||||
if (per_solve_options.D != NULL) {
|
||||
A->DeleteRows(num_cols);
|
||||
}
|
||||
|
||||
summary.num_iterations = 1;
|
||||
|
||||
if (sol != NULL) {
|
||||
memcpy(x, sol->x, num_cols * sizeof(*x));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user