cuDSS could be used as an alternative for SuiteSparse and EigenSparse
in case if CUDA capable GPU is available.
Change-Id: I7a567093ce91363478118153e181134ed5804573
If arguments are passed to a cost function that can be used to construct
the functor, the latter will be instantiated by the cost function using
std::make_unique to ensure exception safety. This not only avoids static
analysis warnings caused by calling new but also spelling the cost
functor type name multiple times.
Also expand deduction guides for instantiating
Dynamic(Auto|Numeric)DiffCostFunction from std::unique_ptr enabled
constructor overloads.
Finally, make CostFunction default move constructible and assignable but
only through derived classes. This in turn allows derived classes to be
movable without relying on custom implementations of corresponding
operators.
Change-Id: Idee8b9871d862bc9f9f8b5a8d0bedc52863e93c0
Move Bessel functions availability checks from configuration time to
inclusion time to be more robust and allow the use of ABI compatible
compilers (e.g., Ceres is compiled using Clang but is used in a project
compiled using GCC.)
Since libc++ does not yet implement special math functions, we fallback
to their POSIX implementation if available. However, then only the
deprecated BesselJ{0,1,n} are provided.
Fixes#814
Change-Id: Ic3e62452b36e90cb22644cc8e553e3dd1881193f
This eliminates an entire vector and computation of a square root
followed by a squaring.
Thanks to @rlabbe for pointing this out.
Change-Id: I0de117b31b9332c61e687f18466d7cb2e2ac611e
Previously, MSVC warning C4996 was suppressed unconditionally in the
entire code base which made it difficult identifying and fixing specific
problems, particularly those in the public interface.
Prefer now to disable warnings at the specific location they occur. This
approach, however, reveals an inconsistency in how Ceres handles POSIX
functions which are declared deprecated by MSVC. Specifically, Bessel
functions use the underscore form whereas the read function does not. To
simplify the logic, we revert to POSIX compatible functions.
C++23 also deprecates std::numeric_limits<T>::has_denorm which MSVC
warns about. Here, we disable the deprecation warning locally to avoid
the warning leaking into the user code.
Fixes#1013
Change-Id: Ida8457cc8dd8770b4384a7c49d16f213b02cdec4
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
Converting fixed size vectors to dynamic ones allows to avoid
segmentation faults in Eigen's packet math if the corresponding
expressions are invoked within GMock matchers.
Fixes#996
Change-Id: I7da5599883825ab0e580678d3d55de19095b41b1
In https://ceres-solver-review.git.corp.google.com/c/ceres-solver/+/23802
the computation of the norm of a quaternion
scale = 1/sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
was replaced by
scale = 1/hypot(q[0], q[1], hypot(q[2], q[3]));
while this appear to be a more accurate computation because of the
use of hypot which can handle over and underflow it introduces a
bug for the case where q[2] = q[3] = 0.
While the hypot(q[2], q[3]) == 0 as scalars, if q[2] and q[3] are
jets, then the derivative will be NaN. Which means that even though
q[0] or q[1] is non-zero and the norm of the quaternion is non-zero,
and the resulting derivative is finite, this way of computing the
scale will produce nans in the derivative of scale.
The following quaternion will replicate the problem described above.
using Jet = ceres::Jet<double, 4>;
std::array<Jet, 4> quaternion = {Jet(1.0, 0), Jet(0.0, 1), Jet(0.0, 2), Jet(0.0, 3)};
This CL reverts the change to QuaternionRotatePoint and
adds a test for it.
Thanks to Jonathan Taylor for reproducing this bug.
Change-Id: I0fbbcc77d6945a38563d82efba4429f4b5278cd5
Benchmark for evaluation of residuals and evaluation of both residuals
and jacobian.
For each input file (in BAL format) specified on the command line two
sets of benchmarks are created for different number of threads.
BAL data is preloaded before starting benchmark.
Usage:
./bin/evaluation_benchmark [flags] input_1.txt ... input_N.txt
Change-Id: I543df65f483e3b186f52785b68bd5e2b3e3552a3
Conversions function include Euler Angles to / from Rotation Matrices
and Quaternions. They are generalized for any Euler convention that can
be specified in the arguments. Algorithm is from "Euler angle
conversion", Ken Shoemake, Graphics Gems IV
Change-Id: I7f9ddc0b8d686efca16299d2ba374295744376ce
* 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