mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 08:34:37 +08:00
Add explicit no sparse linear algebra library available option.
- Previously we had no defined default value for sparse_linear_algebra_library_type in Solver::Options if Ceres was compiled with no sparse library available. Thus in that case, the default value (dependent upon the compiler) would indicate that one was available. - Now we have an explicit option that means no sparse library is available, which is now the default value in Solver::Options in this case. - Add a warning in CMake when the user disables all sparse libraries. - Fix typos in trust_region_preprocessor_test: (SUITE/CX)_SPARSE -> (SUITE/CX)SPARSE that induced failures when no sparse libraries were available. Change-Id: I869c399a12d42bfc44220cbb25ce6d6dd80236bd
This commit is contained in:
@@ -370,6 +370,16 @@ ELSE (CXSPARSE)
|
||||
CXSPARSE_LIBRARY)
|
||||
ENDIF (CXSPARSE)
|
||||
|
||||
# Ensure that the user understands they have disabled all sparse libraries.
|
||||
IF (NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
|
||||
MESSAGE(" ===============================================================")
|
||||
MESSAGE(" Compiling without any sparse library: SuiteSparse, CXSparse ")
|
||||
MESSAGE(" & Eigen (Sparse) are all disabled or unavailable. No sparse ")
|
||||
MESSAGE(" linear solvers (SPARSE_NORMAL_CHOLESKY & SPARSE_SCHUR)")
|
||||
MESSAGE(" will be available when Ceres is used.")
|
||||
MESSAGE(" ===============================================================")
|
||||
ENDIF(NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
|
||||
|
||||
# GFlags.
|
||||
IF (GFLAGS)
|
||||
HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(GFLAGS_INCLUDE GFLAGS_INCLUDE_DIR_HINTS)
|
||||
|
||||
@@ -1237,13 +1237,16 @@ elimination group [LiSaad]_.
|
||||
|
||||
.. member:: SparseLinearAlgebraLibrary Solver::Options::sparse_linear_algebra_library_type
|
||||
|
||||
Default:``SUITE_SPARSE``
|
||||
Default: The highest available according to: ``SUITE_SPARSE`` >
|
||||
``CX_SPARSE`` > ``EIGEN_SPARSE`` > ``NO_SPARSE``
|
||||
|
||||
Ceres supports the use of three sparse linear algebra libraries,
|
||||
``SuiteSparse``, which is enabled by setting this parameter to
|
||||
``SUITE_SPARSE``, ``CXSparse``, which can be selected by setting
|
||||
this parameter to ```CX_SPARSE`` and ``Eigen`` which is enabled by
|
||||
setting this parameter to ``EIGEN_SPARSE``.
|
||||
this parameter to ``CX_SPARSE`` and ``Eigen`` which is enabled by
|
||||
setting this parameter to ``EIGEN_SPARSE``. Lastly, ``NO_SPARSE``
|
||||
means that no sparse linear solver should be used; note that this is
|
||||
irrespective of whether Ceres was compiled with support for one.
|
||||
|
||||
``SuiteSparse`` is a sophisticated and complex sparse linear
|
||||
algebra library and should be used in general.
|
||||
|
||||
@@ -104,7 +104,8 @@ class CERES_EXPORT Solver {
|
||||
|
||||
// Choose a default sparse linear algebra library in the order:
|
||||
//
|
||||
// SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE
|
||||
// SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE > NO_SPARSE
|
||||
sparse_linear_algebra_library_type = NO_SPARSE;
|
||||
#if !defined(CERES_NO_SUITESPARSE)
|
||||
sparse_linear_algebra_library_type = SUITE_SPARSE;
|
||||
#else
|
||||
|
||||
@@ -157,7 +157,12 @@ enum SparseLinearAlgebraLibraryType {
|
||||
|
||||
// Eigen's sparse linear algebra routines. In particular Ceres uses
|
||||
// the Simplicial LDLT routines.
|
||||
EIGEN_SPARSE
|
||||
EIGEN_SPARSE,
|
||||
|
||||
// No sparse linear solver should be used. This does not necessarily
|
||||
// imply that Ceres was built without any sparse library, although that
|
||||
// is the likely use case, merely that one should not be used.
|
||||
NO_SPARSE
|
||||
};
|
||||
|
||||
enum DenseLinearAlgebraLibraryType {
|
||||
|
||||
@@ -228,6 +228,20 @@ bool TrustRegionOptionsAreValid(const Solver::Options& options, string* error) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (options.sparse_linear_algebra_library_type == NO_SPARSE) {
|
||||
if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) {
|
||||
*error = "Can't use SPARSE_NORMAL_CHOLESKY as "
|
||||
"sparse_linear_algebra_library_type is NO_SPARSE.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.linear_solver_type == SPARSE_SCHUR) {
|
||||
*error = "Can't use SPARSE_SCHUR as "
|
||||
"sparse_linear_algebra_library_type is NO_SPARSE.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.trust_region_strategy_type == DOGLEG) {
|
||||
if (options.linear_solver_type == ITERATIVE_SCHUR ||
|
||||
options.linear_solver_type == CGNR) {
|
||||
|
||||
@@ -293,6 +293,42 @@ TEST(Solver, SparseSchurNoEigenSparse) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Solver, SparseNormalCholeskyNoSparseLibrary) {
|
||||
Solver::Options options;
|
||||
options.sparse_linear_algebra_library_type = NO_SPARSE;
|
||||
options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
|
||||
string message;
|
||||
EXPECT_FALSE(options.IsValid(&message));
|
||||
}
|
||||
|
||||
TEST(Solver, SparseSchurNoSparseLibrary) {
|
||||
Solver::Options options;
|
||||
options.sparse_linear_algebra_library_type = NO_SPARSE;
|
||||
options.linear_solver_type = SPARSE_SCHUR;
|
||||
string message;
|
||||
EXPECT_FALSE(options.IsValid(&message));
|
||||
}
|
||||
|
||||
TEST(Solver, IterativeSchurWithClusterJacobiPerconditionerNoSparseLibrary) {
|
||||
Solver::Options options;
|
||||
options.sparse_linear_algebra_library_type = NO_SPARSE;
|
||||
options.linear_solver_type = ITERATIVE_SCHUR;
|
||||
// Requires SuiteSparse.
|
||||
options.preconditioner_type = CLUSTER_JACOBI;
|
||||
string message;
|
||||
EXPECT_FALSE(options.IsValid(&message));
|
||||
}
|
||||
|
||||
TEST(Solver, IterativeSchurWithClusterTridiagonalPerconditionerNoSparseLibrary) {
|
||||
Solver::Options options;
|
||||
options.sparse_linear_algebra_library_type = NO_SPARSE;
|
||||
options.linear_solver_type = ITERATIVE_SCHUR;
|
||||
// Requires SuiteSparse.
|
||||
options.preconditioner_type = CLUSTER_TRIDIAGONAL;
|
||||
string message;
|
||||
EXPECT_FALSE(options.IsValid(&message));
|
||||
}
|
||||
|
||||
TEST(Solver, IterativeLinearSolverForDogleg) {
|
||||
Solver::Options options;
|
||||
options.trust_region_strategy_type = DOGLEG;
|
||||
|
||||
@@ -201,16 +201,16 @@ TEST_F(LinearSolverAndEvaluatorCreationTest, DenseSchur) {
|
||||
}
|
||||
|
||||
#if defined(CERES_USE_EIGEN_SPARSE) || \
|
||||
!defined(CERES_NO_SUITE_SPARSE) || \
|
||||
!defined(CERES_NO_CX_SPARSE)
|
||||
!defined(CERES_NO_SUITESPARSE) || \
|
||||
!defined(CERES_NO_CXSPARSE)
|
||||
TEST_F(LinearSolverAndEvaluatorCreationTest, SparseNormalCholesky) {
|
||||
PreprocessForGivenLinearSolverAndVerify(SPARSE_NORMAL_CHOLESKY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CERES_USE_EIGEN_SPARSE) || \
|
||||
!defined(CERES_NO_SUITE_SPARSE) || \
|
||||
!defined(CERES_NO_CX_SPARSE)
|
||||
!defined(CERES_NO_SUITESPARSE) || \
|
||||
!defined(CERES_NO_CXSPARSE)
|
||||
TEST_F(LinearSolverAndEvaluatorCreationTest, SparseSchur) {
|
||||
PreprocessForGivenLinearSolverAndVerify(SPARSE_SCHUR);
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ const char* SparseLinearAlgebraLibraryTypeToString(
|
||||
CASESTR(SUITE_SPARSE);
|
||||
CASESTR(CX_SPARSE);
|
||||
CASESTR(EIGEN_SPARSE);
|
||||
CASESTR(NO_SPARSE);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -109,6 +110,7 @@ bool StringToSparseLinearAlgebraLibraryType(
|
||||
STRENUM(SUITE_SPARSE);
|
||||
STRENUM(CX_SPARSE);
|
||||
STRENUM(EIGEN_SPARSE);
|
||||
STRENUM(NO_SPARSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user