* Added CudaCgnrSolver, a new CUDA-accelerated CGNR.
* To use CudaCgnrSolver, the user must select CGNR as the linear_solver
and CUDA_SPARSE as the sparse_linear_algebra_library.
* Updated ConjugateGradientSolver to work with an array of pointers to
scratch to support CudaVectors as scratch.
* Moved CUDA initialization to run in Solver::Solve as needed.
Some performance comparisons on an Ubuntu 20.04 desktop with an
Intel i9-9940X CPU @ 3.30GHz, and an nVidia Quadro RTX 6000,
all configurations run with 24 threads, and 10 iterations.
=================================================
CGNR + CUDA_SPARSE + IDENTITY Preconditioner
problem-1778-993923-pre.txt
=================================================
Cost:
Initial 2.563973e+08
Final 1.724755e+06
Change 2.546725e+08
Minimizer iterations 11
Successful steps 7
Unsuccessful steps 4
Time (in seconds):
Preprocessor 4.020158
Residual only evaluation 1.567092 (10)
Jacobian & residual evaluation 7.847130 (7)
Linear solver 31.688898 (10)
Minimizer 46.834987
Postprocessor 0.353974
Total 51.209120
=================================================
SPARSE_SCHUR (CPU) + SUITE_SPARSE + AMD
problem-1778-993923-pre.txt
=================================================
Cost:
Initial 2.563973e+08
Final 1.651617e+06
Change 2.547457e+08
Minimizer iterations 11
Successful steps 11
Unsuccessful steps 0
Time (in seconds):
Preprocessor 35.812003
Residual only evaluation 1.658980 (10)
Jacobian & residual evaluation 12.218799 (11)
Linear solver 76.409992 (10)
Minimizer 98.809773
Postprocessor 0.372712
Total 134.994489
=================================================
ITERATIVE_SCHUR (CPU) + JACOBI Preconditioner
problem-1778-993923-pre.txt
=================================================
Cost:
Initial 2.563973e+08
Final 1.684447e+06
Change 2.547128e+08
Minimizer iterations 11
Successful steps 8
Unsuccessful steps 3
Time (in seconds):
Preprocessor 15.331614
Residual only evaluation 1.606114 (10)
Jacobian & residual evaluation 8.502166 (8)
Linear solver 351.910080 (10)
Minimizer 368.797327
Postprocessor 0.363536
Total 384.492478
=================================================
CGNR + CUDA_SPARSE + IDENTITY Preconditioner
problem-13682-4456117-pre.txt
=================================================
Cost:
Initial 1.126372e+09
Final 2.269329e+07
Change 1.103678e+09
Minimizer iterations 11
Successful steps 7
Unsuccessful steps 4
Time (in seconds):
Preprocessor 19.140087
Residual only evaluation 8.721920 (10)
Jacobian & residual evaluation 41.955923 (7)
Linear solver 214.121861 (10)
Minimizer 296.636890
Postprocessor 1.971827
Total 317.748804
Change-Id: I3a09f31aa6903f661e91f595afd39d427583e856
Add an option to use schur power series expansion for initialization
of pcg solution in ITERATIVE_SCHUR linear solver.
Change-Id: Ifb8bce02bc5f5ceebc74f961eefd3f6dd2ffab4a
Implementation of "Power Bundle Adjustment for Large-Scale 3D
Reconstruction" by Weber et. al. added in the form of preconditioner.
Change-Id: Ie85526a5fc46f74256f6dfe9173c3571f7160f3a
This PR changes the Sphere and Line Manifold formulations so that their
tangent spaces represent traveled angles (for the sphere and the line
direction vector) and traveled distance (for the line origin). These
magnitudes were previously halved according to "Hartley & Zisserman
(2nd Edition)", but in the majority of the state of the art this is not
done, following the convention that magnitudes in the tangent space of
the unit sphere represent geodesic distances traveled on that manifold.
The same scale factor appears in the Quaternion Manifold implementation
and will be studied in a further PR.
This PR also adds an additional case in the Sphere Minus operator when
hy_norm == 0. The value of y_minus_x was fixed to 0 but actually its
last term can also be Pi depending on y_last.
Finally, new unit tests for the Plus and Minus operator are added, along
with new tests for the 2D Sphere (a.k.a. Circle) Manifold.
Change-Id: I9456f1675b20da49bede5d6759aabf3cdfb26eae
Since Eigen does not allow to have a RowMajor column vector (see
https://gitlab.com/libeigen/eigen/-/issues/416), the storage order
must be set to ColMajor in that case. This fix adds that special
case when generating 2D sphere manifolds.
Change-Id: I594932e0dafc878e0b348f72524478588e61b34d
MSVC rightfully issues warning C4305: 'if': truncation from 'size_t' to
'bool' in a static_assert condition that implicitly converts sizeof
result to a boolean.
Change-Id: Ie3b913288bfeaa7a4b362ef7f83d2505ed368641
- Prior to 48cb54d1, Ceres' fmin/fmax() for Jets followed the convention
of std::min/max(), and always returned the first argument on equality,
irrespective of whether this argument was natively a scalar or a Jet.
- After 48cb54d1, Ceres' fmin/fmax() instead returned the second
argument on equality, again irrespective of whether this argument was
natively a scalar or a Jet.
- Now on equality we average the arguments as Jets, which ensures that
a consistent answer is produced irrespective of the ordering or type
(Jet or scalar) of the input arguments. This also ensures that we
preserve a non-zero derivative where it exists, excluding the edge
case of two Jet inputs with equal but oppositely signed infinitesimal
components.
- We retain the behaviour introduced in 48cb54d1 whereby NaNs are
treated as missing values, following the convention of
std::fmin/fmax().
- Raised as issue #816.
Change-Id: I01217c0e32c1be83be440e4515b57c79dd290923
* Unfortunately on some systems such as the Nvidia Jetson, while the
compiler supports C++17, the STL implementations are incomplete.
One such missing implementation is std::exclusive_scan, so this
patch reverts to the old way of manually computing prefix sums.
Change-Id: I4192257519b0083560a4b44e2659ee44d7421105
Eigen provides all the functionality that we need from CXSparse
with a more liberal license.
I will update the documentation in a follow up CL.
Change-Id: I0b9fd8be3c27754cc2986cc0e06595c8b3fdec0b
This was an ill-advised and complicated to interpret option
which offers nothing particularly useful.
Change-Id: Ia7741ed62ef977c96fa52299a884e404bee659ac
With this change, the user can now choose between Approximate Minimum
Degree and Nested Dissection as a fill reducing algorithm when using
a sparse direct factorization based linear solver like SPARSE_NORMAL_CHOLESKY
or SPARSE_SCHUR.
Currenly only SUITE_SPARSE is supported. It requires that
SuiteSparse be compiled with Metis support enabled.
On most problems AMD is still the better choice, but in some cases
like the grid3D dataset from https://lucacarlone.mit.edu/datasets/
the solution time with AMD is 57s and with NESDIS 38 on my M1 Mac.
On some other problems at Google we have observed speedups of 10x,
there is also a corresponding decrease in the total amount of memory
used.
This patch is based on the original work done by NeroBurner in
https://ceres-solver-review.googlesource.com/c/ceres-solver/+/20580
1. Add a new enum to the public api LinearSolverOrderingType and
a setting Solver::Options::linear_solver_ordering_type.
2. TrustRegionPreprocessor had some complicated logic which determined
when linear solvers should reorder their matrices on their own and not
this has been refactored into a more readable function that lives
inside reorder_program.h/cc.
3. Plumbing in reorder_program.cc and trust_region_processor.cc to use
nested dissection.
4. Update bundle_adjuster.cc to use nested dissection.
Change-Id: I388b027934f86c58b4da2b65a4fa5204ea73bf40
covariance.h was using SUITE_SPARSE even when SUITESPARSE
was disabled because it did not have config.h included in it
so it did not see that CERES_NO_SUITESPARSE was defined.
Add more config.h includes to files that are using these
configuration macros.
Change-Id: I6b1d2c2bd9e559de40a6332cd6be85ad4da3377b
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
Previously they were defined in manifold.h but their implementations
were in the internal directory and to prevent circular dependencies
the implementation headers were pushed to the bottom of manifold.h
This started out as one header and has become progressively worse
as more manifolds are templated.
This change moves the two manifolds into their own headers which
also contain their implementations.
Change-Id: I671da0279a47cd2ff1f52c69a1d159426f55bd80
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
Disable the definition of `min`/`max` macros by defining `NOMINMAX`
and prevent macro substitution in the public interface.
Also, quiet floating-point comparisons are defined as template functions
by the MSVC STL which causes compilation errors due to ambiguities in
resolving the template parameter types.
Fixes#668Fixes#716Fixes#718
Change-Id: I5fe7832a6a3a7ad0421a2557527528c34b88e9c7
1. Fix a stupid error in types.cc
2. Update documentation for Solver::Options::dense_linear_algebra_library_type
3. Add a note to installation.rst to update the installation docs.
4. Mention GPU acceleration in features.rst
Change-Id: Id63202ff090e23bbb211d2ee458559fb8046281d
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
This change is needed because compiler attributes and c++
annotations like [[deprecated]] do not mix well and we need that
for our public API.
https://github.com/ceres-solver/ceres-solver/issues/749
Change-Id: I79eda795f2912f9af9ab36ee24b8428b47104743
Add [[deprecate]] notices to everything LocalParameterization
related.
Make sure that Ceres can be compiled without triggering
deprecation warnings.
Update the documentation:
a. Add deprecation notices.
b. Document interaction between LocalParameterization and Manifold
coexisting in the Problem.
c. Add documentation for Manifold(s)
Change-Id: Ie4ad48963c83fded86e533c8c60561af402fbaff
This MR ports the LineParameterization of manifolds. The unit test are
rewritten to use the manifold test facilities.
The LineManifold is extended so that it can also handle dynamic size
ambient space dimensions.
Change-Id: I1fe3cd34b56f74b72ca028c34f5368e9df9fe4d7
Do not define trivial constructors or destructors unless necessary
(e.g., for implementing pimpl) following the rule of zero. Define
virtual base class destructors out-of-line to avoid emitting vtables in
every translation unit.
Change-Id: Iea2d8978e62a8ee5a97b86cbb4e858d56e0fb274
Applied changes correspond to clang-tidy fixes
stemming from the modernize-use-equals-default check.
Change-Id: I254b0908a76d464131564b637cd0e42a6b03fb5a
virtual can be ambiguous. Applied changes correspond to clang-tidy fixes
stemming from the modernize-use-override check.
Change-Id: I973afd4680a5df587419777504aeb94467196b89
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
This MR adds SphereManifold ported from
HomogeneousVectorParameterization. Additionally the minus operator
and jacobian evaluation was implemented.
The unit tests were almost completly reimplemented and uses the
test facilities provided for manifolds.
Change-Id: Iccf72a2333bc921ff24c4d831db35020c653ee86
Complete support for all floating-point classification functions
(fpclassify, signbit) and consistently apply all overloads recursively
to the scalar part of a Jet only. This is now inline with how comparison
operators work. Sanity checks of derivatives should be performed
explicitly on the dual part of a Jet due an ambiguity on reducing the
classification results of multiple values.
Provide an fdim overload (in addition to fmin and fmax) and support
quiet versions of comparison operators also applied recursively to the
scalar part of a Jet but without type promotion.
Additionally, deprecate Ceres legacy classification functions. New code
should use C++11 function names for consistency.
Finally, simplify expressions using introduced scalar classification and
comparison.
Change-Id: I397e37425760717b991eb7ae5da0892f20c5a365
- The intended use-case for these accessors is in client code tests to
support verification of the configuration with which cost functions
were constructed.
Change-Id: Ib77afa6409804ba7f724138f579e0c51b154f5ad
When computing the MinusJacobian we were passing two different
values to AutoDifferentiate for the output dimension. The template
argument was correct which is why the method was working correctly
but the function argument was incorrect (cut and paste error).
This would be fine in release mode, but in debug mode it would
trigger a check failure.
Change-Id: I0327656d1a4d34c82e4d3a8c04f27c264bce80eb