In many cases, manifolds stored in ProductManifold have a default
constructor which can simplify ProductManifold initialization even
further. Allow default construction of ProductManifold in this case.
Change-Id: I29b2612870c02232556688019a77049709684a55
Since the number of manifolds used to initialize ProductManifold and
their types are known at compile-time, it is possible to avoid storing
pointers to the base class as required by a homogeneous, currently
dynamically sized container. Instead, we can use std::tuple<> as a
heterogenous container with the number of elements fixed at compile-time
that allows us to store the concrete manifold realizations.
The advantage of this approach is that we can bypass the vtable when
iterating over each manifold within ProductManifold. The indirection is
invoked only once while accessing the ProductManifoldImpl members.
Additionally, potential dynamic memory allocations by a std::vector can
be completely avoided. This makes the ProductManifold implementation
more efficient both in memory and runtime.
Change-Id: Ic71b0c175ab726f8992e9703f7666bca477baf19
This brings it in line with other manifolds like SphereManifold
and LineManifold, where the user has the choice to specify the size
of the manifold at compile time or runtime.
Most of the time the size is known at compile time so this will
speed up the common case.
Change-Id: I0c7ff8b7a9a64a81203eb11afc074874e208815a
Remove logic invoked based on obsolete variable definitions. Use new
(explicit) target_link_libraries syntax to link binaries against
dependencies. Do not rely on prior knowledge about the compiler for
specifying flags and system libraries but instead directly test their
presence to be more robust.
Change-Id: I76e0d10fae6eba4b343048e4404f0a9b08c7cb6c
1. Add CUDADenseQR & tests.
CUDADenseQR uses the cuSolverDN LAPACK implementation
of QR factorization. A key limitation, however, is that
this solver does not perform singularity checking --
this is because cuSolverDN does not have a trtrs
implementation; we instead use cuBLAS' trsv for
backsubstitution.
2. All CPU -> GPU memory transfers are now async, and both
CUDADenseQR and CUDADenseCholesky explicitly manage their
own streams for async operations.
3. Simplified CUDADenseCholesky to only use the legacy 32-bit
cuSolverDN API.
Change-Id: I2a9b7b65469658ddfe33b5b2a3892c8744d6e437
1. Add CUDADenseCholesky64Bit, CUDADenseCholesky32Bit, & tests.
CUDADenseCholesky32Bit uses the legacy versions of potrf/potrs
in cuSolverDN, while CUDADenseCholesky64Bit uses the new 64-bit
versions available since Cuda 11.1. The legacy versions are
provided since some platforms such as the Nvidia Jetsons only
support Cuda 10.2.
2. Expose CUDA as a new option under DenseLinearAlgebraLibraryType.
The relevant option to string and string to option helper functions
are modified accordingly.
3. Add cuda as a dense_linear_algebra_library option in bundle_adjuster
to demonstrate the use of the new CUDA option.
Change-Id: I23615e1d301df5185ed646b3e33ee802508dae86
1. Add EigenDenseQR & tests.
This implementation now uses an in place decomposition,
which means that we are not allocating, deallocating
memory every call.
2. Add LAPACKDenseQR and tests.
The LAPACK implementation instead of using dgels which is a
routine which does the factorization and solve in one
call, now uses dgeqrf for factorization and then
dormqr and dtrtrs for solving. This allows us to
have a factorize and solve interface like DenseCholesky.
And opens the door to iterative refinement and mixed
precision solves.
3. The refactor also allows us to simplify the interface to
DenseSparseMatrix considerably. The internals of this
class were complicated because we had the AppendDiagonal
and RemoveDiagonal methods and we did not want to allocate
deallocate memory every call. But since we pay the cost
of the copy anyways, we can just hold that buffer
in DenseQRSolver.
4. Delete lapack.cc/h
5. The net result is that everything seems to be a bit faster.
For LAPACK we are not doing some of the scaling work that
dgels was doing. For Eigen I think it maybe the inplace
decomposition.
Benchmark Time CPU Time Old Time New CPU Old CPU New
----------------------------------------------------------------------------------------------------------------------------------------------------------
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/1/1 -0.1154 -0.1159 692 612 691 611
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/2/1 -0.1601 -0.1553 717 603 712 601
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/3/1 -0.1673 -0.1575 733 610 724 610
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/6/2 -0.1008 -0.1003 886 797 884 796
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/10/3 -0.1489 -0.1514 1283 1092 1281 1087
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/12/4 -0.1040 -0.1104 1556 1394 1553 1381
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/20/5 -0.0007 -0.0097 1911 1910 1908 1890
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/40/5 -0.1033 -0.1022 2981 2673 2957 2655
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/100/10 -0.0147 +0.0015 9275 9138 9026 9040
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/200/10 -0.1408 -0.1284 15093 12968 14778 12880
BM_DenseSolver<ceres::EIGEN, ceres::DENSE_QR>/200/20 -0.0310 -0.0355 38973 37765 38837 37460
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/1/1 -0.1228 -0.1256 736 646 731 640
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/2/1 -0.1401 -0.1396 740 636 735 633
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/3/1 -0.1731 -0.1695 744 615 738 613
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/6/2 -0.1399 -0.1408 1121 965 1113 956
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/10/3 -0.1110 -0.1145 1571 1397 1560 1382
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/12/4 -0.1411 -0.1417 2006 1722 1993 1710
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/20/5 -0.1740 -0.1729 2741 2264 2724 2253
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/40/5 -0.0966 -0.1123 3462 3128 3425 3040
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/100/10 -0.0387 -0.0998 10365 9964 10339 9307
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/200/10 -0.2044 -0.2049 16031 12754 15998 12720
BM_DenseSolver<ceres::LAPACK, ceres::DENSE_QR>/200/20 -0.2391 -0.2386 35777 27223 35716 27193
Change-Id: I782f0d7664efe1435eebda92ddf47a0fe66c9c72
This has been a long requested feature so that users can minimize
functions using numeric differentiation.
As part of this, I have also redone rosenbrock.cc, which now has three
variants.
rosenbrock.cc now uses automatic differentiation.
rosenbrock_numeric_diff.cc uses numeric differentiation.
rosenbrock_analytic_diff.cc uses analytic derivatives.
This is analogus to how the helloworld example code is structured.
The tutorial for GradientProblemSolver has also been updated to reflect
this.
https://github.com/ceres-solver/ceres-solver/issues/691
Change-Id: Ib0fb9e35127fe4c8299d4793bea3558722c70dd7
1. Add function_tolerance based termination, updating the
termination logic to be in line with Ceres.
2. Replace the use of "error" with "residuals" in the code.
Change-Id: I3fd543f3a8226fe7f07eeec358559cba934679b2
This is needed to add a layer of indirection which will allow
us to use gflags in the public version and absl inside Google.
Change-Id: I32f3da23200a01c9b658bbf8aaa66cb8fddc2cc3
When the examples are built from an external repo, the -I flag doesn't
point anywhere useful. Bazel has an includes option to handle this, so
just use that instead.
Change-Id: Ic768bd60c547948959912193765d4097ec0adf8c
- 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
This is mostly just applying the existing clang format config, except:
- Use NOLINT on overlong comment lines.
- Wrap some sections in 'clang-format off' / 'clang format on'.
- Manually split or join some multi-line strings.
Change-Id: Ia1a40eeb92112e12c3a169309afe087af55b2f4f
Add Ownership semantics to the AutoDiffCostFunction
This allows several benefits, such as pointer ordering always being the
same for numerical repeatability (due to blocks being ordered by
pointer address), memory adjacency for better cache performance, and
reduced allocator pressure / overhead.
This is then made use of in libmv by preallocating the errors and
cost functions into vectors
Change-Id: Ia5b97e7249b55a463264b6e26f7a02291927c9f2
- As our minimum required version of gflags (2.2) exports itself as
a CMake package and this is the case for the default 18.04 package
we can use the gflags target directly.
- Replaces forced use of CONFIG in find_package(gflags) with a check
that the gflags imported target exists to avoid ambiguity with
libgflags if installed in a default location. This permits users to
override the gflags detection should they so choose, provided that
they do so via an imported target.
- Also removes some previously removed legacy GLAGS_ vars from the
installation docs.
Change-Id: I015f5a751e5b22f956bbf9df692e63a6825c9f0d
- Removes all workarounds for pre-C++14 versions
- Removes '11' qualifier from C++ threading option and associated
defines.
- Fix missing inclusion of 'Multithreading' in reported Ceres components
when C++ threading model is enabled.
- Update Sphinx documentation to specify C++14 as minimum requirement.
Change-Id: I706c8b367b3221e3c4d1a0aaf669a8f9c911e438
Fix typos in docs/source/features.rst and examples/helloworld.cc. Alter a NULL to nullptr in include/ceres/autodiff_cost_function.h
Change-Id: Ibcf00b6ef665ad6be9af14b3add2dd4f3852e7e6
- This reflects modern CMake style, and also provides a measure of
protection against missing find_package() imports in downstream
clients resulting in linker errors when 'ceres' matches the compiled
library and not the imported target.
- The original 'ceres' target remains, as a local imported interface
target created by CeresConfig for backwards compatibility.
Change-Id: Ie9ed8de9b7059bc0cae1ae5002bb94d8fe617188
This patch integrates the code generation module into the build
system. All depenendcies are tracked through CMake targets.
Modifying the cost functor will automatically trigger code
re-generation.
All this functionality is defined in the CMake function
ceres_generate_cost_function_implementation_for_functor
in CeresCodeGeneration.cmake. A hello world usage example
is included in examples/CMakeLists.txt.
Change-Id: I23b8b6698d1ea51cf3d788a47afcf39f8c5ce327
After this patch, users have to add -DCODE_GENERATION=ON to the
cmake command, if they want to compile the code generation module.
A warning is printed if they enable code generation.
This informs the users that the code generation is still under
development and should be used with care. Also, we don't break
the master branch immediately if one of the bigger codegen
patches fails to build on some platform.
When this system is finished, we can enable it by default or
remove this option again.
Change-Id: Ib26498f0d5bd8b3c165807ffd774c057c2d21d39
The public API for the Autodiff Codegen system consist of a single
function, GenerateCodeForFunctor. This function takes as template
argument a cost functor type and the residual/parameter structure.
The output is the C++ for the residual and derivative. This class
mainly serves as a wrapper for the different codegen modules.
Change-Id: I8ee974199219805d54eed5e07c0e8d1394940779
https://github.com/ceres-solver/ceres-solver/issues/270
Detailed list of changes:
1. Add SUBSET to the PreconditionerType enum.
2. Add Solver::Options::residual_blocks_for_subset_preconditioner
3. Integrate SubsetPreconditioner into the CGNR solver.
4. Add the reordering logic needed for this to TrustRegionPreprocessor.
5. Expect CreateJacobianBlockTranspose to take the starting row block
so that we can work with subparts of the Jacobian matrix.
6. Extend the denoising example to use this preconditioner.
As an illustration of its performance, we consider the performance of
denoising -input ../data/ceres_noisy.pgm --foe_file ../data/5x5.foe
tl;dr
For the same cost,
SPARSE_NORMAL_CHOLESKY - 81s
CGNR + JACOBI - 718s
CGNR + SUBSET - 57s
SPARSE_NORMAL_CHOLESKY
======================
Cost:
Initial 2.317806e+05
Final 2.232323e+04
Change 2.094574e+05
Minimizer iterations 10
Successful steps 10
Unsuccessful steps 0
Time (in seconds):
Preprocessor 2.999746
Residual only evaluation 2.306811 (10)
Jacobian & residual evaluation 7.421727 (10)
Linear solver 65.517273 (10)
Minimizer 78.731011
Postprocessor 0.026079
Total 81.756836
Termination: CONVERGENCE (Function tolerance reached. |cost_change|/cost: 8.573046e-04 <= 1.000000e-03)
CGNR + JACOBI
=============
Cost:
Initial 2.317806e+05
Final 2.232344e+04
Change 2.094572e+05
Minimizer iterations 10
Successful steps 10
Unsuccessful steps 0
Time (in seconds):
Preprocessor 0.648814
Residual only evaluation 2.297607 (10)
Jacobian & residual evaluation 7.327886 (10)
Linear solver 699.601248 (10)
Minimizer 712.419493
Postprocessor 0.024014
Total 713.092321
Termination: CONVERGENCE (Function tolerance reached. |cost_change|/cost: 8.528538e-04 <= 1.000000e-03)
CGNR + SUBSET (random 20% residuals used for the preconditioner)
===============================================================
Cost:
Initial 2.317806e+05
Final 2.232327e+04
Change 2.094574e+05
Minimizer iterations 10
Successful steps 10
Unsuccessful steps 0
Time (in seconds):
Preprocessor 1.472743
Residual only evaluation 2.428315 (10)
Jacobian & residual evaluation 7.367796 (10)
Linear solver 42.585999 (10)
Minimizer 55.664459
Postprocessor 0.024098
Total 57.161301
Termination: CONVERGENCE (Function tolerance reached. |cost_change|/cost: 8.538277e-04 <= 1.000000e-03)
Change-Id: Ifb011408bd53edbb9439b0b7345649a38f999e18
This commit includes the following:
- Changes to CMake to make it safer to see which compiler flags are supported,
so this way we do not need to worry about version checks in CMake.
- Unix platforms (which includes both Linux and Apple as far as i can tell)
will now enable -Wmissing-declarations warning for the whole Ceres.
- Changes in all sources to solve missing declaration warning. In most cases
it was either matter of using static qualifier or moving functions to an
anonymous namespace.
In one case the function got removed, since it seems to be unused.
Additionally, in slam examples there was a non-inlined function implementation
in a header, which is a direct way to cause linking errors if other .cc file
will include that helper header.
- All third party sources (which is currently only gmock) has this extra
paranoid warning disabled.
This warning is important in the following cases:
- Detect helper functions which are not needed anymore.
- Avoid unnoticed pollution of namespace.
- Avoid bad level calls.
- Avoid missing updates in header files after changes in implementation file.
- Helps integrating Ceres into software where paranoid warnings are important.
Change-Id: I9b1044aced3910d8c6b2356cfe2bf57f3c8c58db
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. Solver::Options::num_threads now controls parallelism in Ceres
Solver. The user specified value of
Solver::Options::num_linear_solver_threads is ignored.
2. If the user specifies Solver::Options::num_linear_solver_threads
and it is different from Solver::Options::num_threads,
a warning is printed.
3. Solver::Summary:num_linear_solver_threads_given and
Solver::Summary::num_linear_solver_threads_used are also
deprecated and are always set to Solver::Summary::num_threads_given
and Solver::Summary::num_threads_used.
Change-Id: I20b9336d9336e400e6f0a15b63857c0c43eb271c
1. Default linear solver is Eigen::LDLT
2. Options::max_iterations -> Options::max_num_iterations
3. Options::error_threshold -> Options::cost_threshold
4. Options::relative_step_threshold -> Options::parameter_threshold
5. Options::initial_scale_factor -> Options::initial_trust_region_radius
6. The default values of the above parameters have been changed
to match those in ceres::Solver::Options
7. Status::RUNNING has been removed
8. Update now returns a bool instead of a Status enum and
the status handling has been included in the main loop.
9. Summary::gradient_norm has been changed to Summary::gradient_max_norm
to match the convergence test
10. A member variable cost_ has been added which is computed by Update
11. The test for parameter_tolerance based convergence is made
more robust near zero.
12. Use of double has been replaced by Scalar.
13. Minor clang-formatting
Change-Id: I3cb0e2fd0a0204476bb8718761dc740cdf5e42ce