Starting with SuiteSparse version 7.4.0 CHOLMOD has support for single
precision matrices. This allows us to have single precision and mixed
precision solves when using the SUITE_SPARSE backend.
This CL also fixes sparse_cholesky_test which was completely broken for
single precision testing.
Sample performance on my Mac.
/usr/bin/time -l ./bin/bundle_adjuster --input=../../Downloads/problem-3068-310854-pre.txt
<SNIP>
Cost:
Initial 9.099334e+07
Final 4.161838e+06
Change 8.683150e+07
Minimizer iterations 6
Successful steps 4
Unsuccessful steps 2
Time (in seconds):
Preprocessor 2.528222
Residual only evaluation 0.142804 (5)
Jacobian & residual evaluation 0.424014 (4)
Linear solver 54.083396 (5)
Minimizer 54.895752
Postprocessor 0.024564
Total 57.448539
Termination: NO_CONVERGENCE (Maximum number of iterations reached. Number of iterations: 5.)
59.04 real 341.24 user 5.49 sys
5776375808 maximum resident set size
<SNIP>
616329634071 instructions retired
929475980510 cycles elapsed
5375034560 peak memory footprint
/usr/bin/time -l ./bin/bundle_adjuster --input=../../Downloads/problem-3068-310854-pre.txt -mixed_precision_solves
<SNIP>
Cost:
Initial 9.099334e+07
Final 4.148930e+06
Change 8.684441e+07
Minimizer iterations 6
Successful steps 4
Unsuccessful steps 2
Time (in seconds):
Preprocessor 2.580217
Residual only evaluation 0.144098 (5)
Jacobian & residual evaluation 0.396723 (4)
Linear solver 23.636074 (5)
Minimizer 24.427163
Postprocessor 0.023790
Total 27.031170
Termination: NO_CONVERGENCE (Maximum number of iterations reached. Number of iterations: 5.)
28.58 real 128.53 user 2.37 sys
4818386944 maximum resident set size
<SNIP>
395186936091 instructions retired
368802808856 cycles elapsed
4327029824 peak memory footprint
Change-Id: I1f137b0dd12da8da7f9ced338dd8f20f4bbdf99d
Previously this header was included in absl/log/log.h
but going forward this header will not be included.
Change-Id: Ie663b221d90e32a852fb00dfe20f731dcd1dcf6b
Replace ceres::String* with their more modern and performant
absl strings library equivalent and delete our string
manipulation library.
Change-Id: Iecbdba9864e0abf329778f81fdc0708f78f7594f
1. Add abseil-cpp as a submodule. We are tracking the latest LTS
release, which is lts_2024_01_16.
2. Replace glog/gflags with absl::log and absl::flags.
3. Remove miniglog
4. Also take a whack at making the bazel build work with
abseil-cpp and gtest.
There are a number of TODOs in this CL that still need to be resolved.
Change-Id: I39355ed7d61375be4ebcbc8596d9cc70acc1c678
1. Add a version history
2. Update copyright years across the code base
3. Run format_all.sh
4. Update version strings from 2.1.0 to 2.2.0 in the docs and
elsewhere.
Change-Id: I46d8d479d54bd6002d532785e67342106e73c9ac
When AnalyzeCholesky is called on a Jacobian which has been
pre-ordered in the preprocessor, we assume a NATURAL ordering.
In this case, asking CHOLMOD to do a postordering is detrimental
to the performance. This regression was introduced in
https://github.com/ceres-solver/ceres-solver/commit/d09f7e9d5e3bfab2d7ec7e81fd6a55786edca17a
based on an email exchange with Prof. Tim Davis the author of CHOLMOD
who suggested that this should be innocous. Unfortunately this is not
the case. The following table shows the performance of bundle_adjuster
on a variety of problems. This matches the performance of the
bundle adjuster before the CL that introduced the regression.
Before After
problem-49-7776-pre.txt
SPARSE_NORMAL_CHOLESKY + AMD 0.8 0.6
SPARSE_NORMAL_CHOLESKY + NESDIS 0.8 0.6
SPARSE_SCHUR + AMD 0.1 0.1
SPARSE_SCHUR + NESDIS 0.1 0.1
problem-1778-993923-pre.txt
SPARSE_NORMAL_CHOLESKY + AMD 247.1 197.0
SPARSE_NORMAL_CHOLESKY + NESDIS 234.0 193.2
SPARSE_SCHUR + AMD 78.7 71.8
SPARSE_SCHUR + NESDIS 78.7 71.4
problem-1031-110968-pre.txt
SPARSE_NORMAL_CHOLESKY + AMD 26.1 22.4
SPARSE_NORMAL_CHOLESKY + NESDIS 26.0 23.0
SPARSE_SCHUR + AMD 14.9 13.1
SPARSE_SCHUR + NESDIS 14.9 13.1
problem-356-226730-pre.txt
SPARSE_NORMAL_CHOLESKY + AMD 43.9 34.7
SPARSE_NORMAL_CHOLESKY + NESDIS 42.5 34.8
SPARSE_SCHUR + AMD 6.8 6.1
SPARSE_SCHUR + NESDIS 6.8 6.1
problem-951-708276-pre.txt
SPARSE_NORMAL_CHOLESKY + AMD 170.3 139.0
SPARSE_NORMAL_CHOLESKY + NESDIS 168.9 139.8
SPARSE_SCHUR + AMD 52.3 47.9
SPARSE_SCHUR + NESDIS 52.0 47.7
Change-Id: I6421060dd835ab2fc81d270238f6f67e29f3ecd5
Previously some matrices used Block to keep track of
row/column block sizes and some would just use ints, and
then compute the position of each row and column from it.
By uniformly using Block everywhere, we reduce duplicate
computation and data copies.
I also cleaned up a bunch of c++17 related stuff as I edited
these files.
Change-Id: I4c86b1593fd4c91f9057fbb38314f62f303e0477
Use the more modern form of accessing the data array of a vector
rather than grabbing the pointer to the first element. The latter
can lead to errors if the vector is of zero length.
Change-Id: Ifc8fc969b06b3ba1a9385e8a3a8d5c50b25db5a8
* Split `CERES_NO_METIS` into two defines: `CERES_NO_PARTITION` and
`CERES_NO_METIS`. The former refers to METIS support in SuiteSparse,
the latter to the Eigen's MetisSupport module. This enables the use of
sparse matrix reordering independent from SuiteSparse.
* Run Linux, macOS, and macOS Github workflows with METIS enabled
SuiteSparse.
Fixes#808
Change-Id: I5076b7e1268d32cc3e7e56650edcbaf7fb3b59ce
Previously when using a natural ordering, we had postordering
turned off. This is not a good idea. Enabling postordering will
also has the possibility of improving the size of the supernodes.
Change-Id: I8c270e54751b8bed53b38a0b461f647f5c8f5640
1. Generalize SuiteSparse::AnalyzeCholesky and
SuiteSparse::BlockAnalyzeCholesky from just doing AMD to taking
OrderingType as an argument and using that to determine whether
AMD & Nested Dissection algorithms are used for computing the
fill-reducing ordering or a natural ordering when computing
the symbolic factorization.
2. Remove AnalyzeCholeskyWithNaturalOrdering.
3. Replace and generalize SuiteSparse::BlockAMDOrdering with
SuiteSparse::BlockOrdering which also takes OrderingType as an
argument. Same for SuiteSparse::ApproximateMinimumDegreeOrdering
and SuiteSparse::NestedDissectionOrdering by
SuiteSparse::Ordering.
4. Remove LinearSolver::Options::use_postordering and replace it
with LinearSolver::Options::ordering_type.
5. Replace Preconditioner::Options::use_postordering and replace it
with Preconditioner::Options::ordering_type.
6. Add NESDIS to OrderingType. With the above changes, the linear
solvers can now use Nested Dissection once this information
is piped through the nonlinear solver.
Change-Id: Ib8e93fbf34ae2981bf2ac54dcda9e25c7c213790
With this change we can drop the complicated/conditional handling
around CAMD and assume that it is always available.
Change-Id: I93e1da676fb75817f79824b8b2b6549d03f278b0
Currently, the logic for exporting symbols is rather complicated: when
tests are enabled internal symbols are exported in addition to the
public symbols. Such logic causes several problems. (1) Test binaries
link against a Ceres build that is different from the final release
since fewer optimizations are applied if more symbols are exported. (2)
Also, some toolchains hide symbols by default breaking the existing
logic eventually causing linker errors.
Since internal symbols are not intended to be used outside of the
project, we can compile them into object files and use exactly the same
binary code both for the final build and the tests without relying on
conditionals.
By default, all symbols are now hidden unless annotated as public.
Internal symbols are explicitly marked as not being exported in case
users chose not to hide symbols by default.
Change-Id: I589dd10be2f6f438508783cf99d141af0120057b
- Change formatting standard to Cpp11. Main difference is not having
the space between two closing >> for nested templates. We don't
choose c++14, because older versions of clang-format (version 9
and earlier) don't know this value yet, and it doesn't make a
difference in the formatting.
- Apply clang-format to all (non generated) internal source files.
- Manually fix some code sections (clang-format on/off) and c-strings
- Exclude some embedded external files with very different formatting
(gtest/gmock)
- Add script to format all source files
Change-Id: Ic6cea41575ad6e37c9e136dbce176b0d505dc44d
1. Add Solver::Options::use_mixed_precision_solves,
and Solver::Options::max_num_refinement_iterations.
2. Make SparseCholesky::Create return a unique_ptr.
3. SparseCholesky::Create now takes LinearSolver::Options
as an argument.
4. IterativeRefiner's constructor does not require num_cols
as an argument.
5. SparseNormalCholeskySolver now uses a separate rhs vector.
This basic implementation results in a 10% reduction in solver time
and 30% reduction in linear solver memory usage.
Change-Id: I6830f32cae2febf082d2733262eb2c9f0482b0ea
1. Add SuiteSparse::CreateDenseVectorView
2. Replace calls to SuiteSparse::CreateDenseVector with
SuiteSparse::CreateDenseVectorView.
2. Replace NULL with nullptr in suitesparse.cc and
dynamic_sparse_normal_cholesky_solver.cc
Change-Id: I94355c1dc27789e5b987a7b2850e9db6176a0914
SparseCholesky is an interface to sparse cholesky factorization
routines across sparse linear algebra libraries. Each sparse
linear algebra library is responsible for implementing its own
instance of this interface.
As a result the various places - SparseNormalCholeskySolver,
SparseSchurComplementSolver and VisibilityBasedPreconditioner
are significantly simplified.
Change-Id: I8b465705eae83bba9e1adfffcc741a05c70faf2e
By adding an enum to CompressedRowSparseMatrix, which indicates
whether the matrix is unsymmetric, upper or lower triangular
we are able to improve the readability and fix some minor
bugs in the way some matrix manipulation code was being
called.
Thank to William Rucklidge for this suggestion.
Change-Id: I355c90d11cd5d31f5a25741b0bda4fc4583e9095
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
Since Ceres is moving to using GitHub for issues, and the Google
Code URL in the current copyright header will soon become invalid,
update all the headers.
Change-Id: I1fce70375d1bcf098591f07b4d8f01a5c1e0789c
For historical reasons we had a "using namespace std;" in port.h. This
is generally a bad idea. So removing it and along the way doing a bunch
of cpplint cleanup.
Change-Id: Ia125601a55ae62695e247fb0250df4c6f86c46c6
- Previously we passed all compile options to Ceres via add_definitions
in CMake. This was fine for private definitions (used only by Ceres)
but required additional work for public definitions to ensure they
were correctly propagated to clients via CMake using
target_compile_definitions() (>= 2.8.11) or add_definitions().
- A drawback to these approaches is that they did not work for chained
dependencies on Ceres, as in if in the users project B <- A <- Ceres,
then although the required Ceres public compile definitions would
be used when compiling A, they would not be propagated to B.
- This patch replaces the addition of compile definitions via
add_definitions() with an autogenerated config.h header which
is installed with Ceres and defines all of the enabled Ceres compile
options.
- This removes the need for the user to propagate any compile
definitions in their projects, and additionally allows post-install
inspect of the options with which Ceres was compiled.
Change-Id: Idbdb6abdad0eb31e7540370e301afe87a07f2260
A lot of error checking cruft has accumulated over the years
in the various linear solvers. This change makes the error reporting
more robust and consistent across the various solvers.
Preconditioners are not covered by this change and will be the
subject of a future change.
Change-Id: Ibeb2572a1e67758953dde8d12e3abc6d1df9052d
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
1. CX_SPARSE supports pre-ordering of the jacobian.
2. Add support for constrained approximate minimum degree ordering
for SuiteSparse versions >= 4.2.0
3. Using 2, support for pre-ordering for SPARSE_SCHUR when used
with SUITE_SPARSE.
4. Using 2, support for user orderings in SPARSE_NORMAL_CHOLESKY.
5. Minor cleanups in documentation and code all around.
6. Test update and refactoring.
Change-Id: Ibfe3ac95d59d54ab14d1d60a07f767688070f29f
Uptil now only SuiteSparse when used with SPARSE_SCHUR would use
the block structure of the reduced camera matrix to find a fill-reducing
ordering.
This leads to substantial speedup for some bundle adjustment
problems.
Credit for this technique goes to the authors of g2o. I learned
about it from reading their source code.
Change-Id: I5403efefd4d9552c9c6fc6e02a65498bdf171584
This will allow CHOLMOD to compute the sparse
Cholesky factorization of J'J without making
a permuted copy of it.
Change-Id: I25d0e18f5957ab7fdce15c543234bb2f09db482e
1. CreateSparseMatrixTransposeView now returns a struct instead
of a pointer.
2. Add AnalyzeCholeskyWithNaturalOrdering.
Change-Id: If27a5502949c3994edd95be0d25ec7a0d1fa1ae1
1. Silence CHOLMOD's indefiniteness warnings.
2. Add a comment about how the error handling in suitesparse.cc
needs to be improved.
3. Move the analysis logging into suitesparse.cc and out of the
three callsites.
Change-Id: Idd396b8ea4bf59fc1ffc7f9fcbbc7b38ed71643c