This change fixes a bug in ceres::CovarianceImpl where a new thread was always being created even when num_threads=1. After this fix, when num_threads=1, CovarianceImpl should run single-threaded and will not create any additional threads.
Change-Id: I784e359f8afe3e7e6d72930500a10e909bfe9308
Replace WallTimeInSeconds with absl::Now and use
absl::Time and absl::Duration objects instead of doubles.
wall_time.h/cc -> event_logger.h/cc
Change-Id: I41279961368840fbdf6bb3456ffdbdf2f9bfb85b
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
This reverts commit 4027f69975.
Reason for revert: This breaks the build because this constructor syntax is only present in the unstable/development version of eigen. So the macro check is incorrect.
Change-Id: I1e664208c7c50041e295aeb7c4b65259f9f2fc8f
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
Since c++11, we can depend on C++ threads always being available.
With the recent work on the performance of CXX threading, the
additional complexity of maintaining multiple backends for some
minor performance delta is not worth it
https://github.com/ceres-solver/ceres-solver/issues/886
Change-Id: Idee480b22a498daec9c4366da8589aa58eaf36a1
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
Thanks to nate-thirdwave@ for pointing this out and offering
a fix.
Also add a TODO about an odd loop in covariance_impl.cc which was
revealed as I was testing the bazel build
https: //github.com/ceres-solver/ceres-solver/issues/800
Change-Id: I87d17155ee43ea2a52b8031177d6b3ac5ae1460a
Applied changes correspond to clang-tidy fixes
stemming from the modernize-use-equals-default check.
Change-Id: I254b0908a76d464131564b637cd0e42a6b03fb5a
Manifolds are now part of the public API and co-exist
with LocalParameterizations.
1. Add Manifolds to the Problem API.
a. AddParameterBlock(double*, int, Manifold*)
b. SetParameterization(double*, Manifold*)
b. GetManifold(const double*)
c. HasManifold(const double*)
2. Internally Ceres now only uses Manifolds. When the user uses
a LocalParameterization, it is wrapped in a ManifoldAdapter.
3. To preserve the API semantics while keeping the internals clean
we need a new map in ProblemImpl which stores the association
between parameter blocks and local parameterizations. This
is temporary, it will go away once this transition is complete.
4. There are NO algorithmic changes, as in we are not using
any of the expanded interface of the Manifold objects yet.
That will come later.
5. All tests that use LocalParameterization have been duplicated
to use Manifolds, and when this transition is complete the
LocalParameterization based tests will be deleted.
6. Public documentation for the API has been updated. Deprecation
notices to the documentation as well as C++ annotations will come
later.
7. Similar changes have been made to GradientProblem.
Change-Id: I8e03c8ced6e141876ef3eca5740c113afa788f0c
Eigen::MappedSparseMatrix has been deprecated and removed from
Eigen at HEAD.
Thanks to rmlarsen@ for fixing this.
Change-Id: I34f3b0dda2bb91ee8cc65a20e53a3d7de6929221
A matrix reference was being incorrectly sized. It was using
the block_size number of rows, where as there are only block_local_size
number of rows that are present in the underlying matrix.
This did not affect the correctness of the resulting code, because
right after construction we then access a subblock with block_local_size
rows.
Thanks to William Gandler for reporting this.
Change-Id: I35e1f5a30b79e31b0b9fac79f7e361821d6073df
Make the rank deficiency warning in the covariance module a VLOG(1) instead of
LOG(ERROR) since this is a commonly occuring case.
Change-Id: Id46eba6dcf9afbaf0554c2d6f230b2af7a1fbdea
Switch from JacobiSVD to BDCSVD in
ComputeCovarianceValuesUsingDenseSVD. This should increase
the performance for larger covariance matrices. See
https://eigen.tuxfamily.org/dox/classEigen_1_1BDCSVD.html
Change-Id: Icde4dec89f506b638b0f9f1aee3b7cfc9e4d72fc
The CHECK was to see if SuiteSparseQR returns a non-null QR
factorization. However this can cause problems in production, so its
better to return false and let the user deal with the failure in
factorization.
Change-Id: I4e67f343e30547f4257d0315d507df9864c06dcc
- In light of the C++11 threads threading option this is no longer
necessary for cross-platform threading support and did not offer a
noticeable performance gain over either the C++11 threads
implementation or OpenMP.
Change-Id: Icb588d520888c19a1775171795b55bcaffb3d256
SuiteSparseQR sets permutation to NULL when the permutation is the
identity. Thus, instead of checking that permutation is not NULL, we
handle that case when building the inverse_permutation.
Change-Id: Ib0fcdf3462da765ac0d4b7aee47a1dff7b3a6c53
With the addition of C++11 support we can simplify the parallel for code by
removing the ifdef branching. Converts coordinate_descent_minimizer.cc to use
the thread_id ParallelFor API.
Tested by building with OpenMP, C++11 threads, TBB, and no threads. All tests
pass.
Also compared timing via the bundle adjuster.
./bin/bundle_adjuster --input=../problem-744-543562-pre.txt
With OpenMP num_threads=8
Head:
Time (in seconds):
Residual only evaluation 0.807753 (5)
Jacobian & residual evaluation 4.489404 (6)
Linear solver 41.826481 (5)
Minimizer 50.745857
Total 73.294424
CL:
Time (in seconds):
Residual only evaluation 0.970483 (5)
Jacobian & residual evaluation 4.647438 (6)
Linear solver 41.781892 (5)
Minimizer 50.848904
Total 73.089983
With OpenMP num_threads=1
HEAD:
Time (in seconds):
Residual only evaluation 2.990246 (5)
Jacobian & residual evaluation 14.132090 (6)
Linear solver 79.631951 (5)
Minimizer 100.281847
Total 122.946267
CL:
Time (in seconds):
Residual only evaluation 3.075178 (5)
Jacobian & residual evaluation 13.966451 (6)
Linear solver 77.005441 (5)
Minimizer 97.568712
Total 120.410454
Change-Id: I1857d7943073be7465b6c6476bf46ab11c5475a3
1. Replace HashMap and HashSet with std::unordered_map and
std::unordered_set respectively.
2. Extract the pair hasher into a struct pair_hash.
3. Delete collections_port.h
4. Convert explicit iterator based loops to auto based
loops where sensible.
Change-Id: Ib88bcd13a7463d18435639d3b771abaa52080efb
Covariance computation wants to do a triangular iteration but as a
single loop. Right now it iterates over a square and does nothing half
the time, which is inefficient and has bad worst-case threading
performance. This adds a utility that allows waste-free linear iteration
over a triangle.
Change-Id: I881d5683c65882f87dc2b5f8449a855d22ace755
Previously, the thread ID was acquired and released on every iteration
of the for loop. The C++11 concurrent queue implementation is much
slower than TBB's version and consequently this was a huge bottleneck.
This introduces another ParallelFor API which takes the thread ID as a
parameter in the evaluation function. This allows us to acquire and
release the thread ID for each block of work which drastically improves
the performance.
This change brings us on par with OpenMP and TBB. See below for a
timing comparison. Note: in this example this CLs C++11 version is
faster to compute the residuals because TBB still must acquire the
thread ID on every iteration, which has some overhead.
Tested by building and running tests for no threading, OpenMP, TBB, and
C++11 threads. Also ran bazel tests.
./bin/bundle_adjuster --input=problem-744-543562-pre.txt --num_threads=8
C++11 @Head
Time (in seconds):
Residual only evaluation 7.819692 (5)
Jacobian & residual evaluation 11.606063 (6)
Linear solver 47.860195 (5)
Minimizer 70.877072
Total 90.806338
---------------------------------------------------
C++11 (This CL)
Time (in seconds):
Residual only evaluation 1.217500 (5)
Jacobian & residual evaluation 5.796112 (6)
Linear solver 44.080873 (5)
Minimizer 54.635524
Total 77.640072
---------------------------------------------------
OpenMP
Time (in seconds):
Residual only evaluation 0.797023 (5)
Jacobian & residual evaluation 5.633916 (6)
Linear solver 43.280020 (5)
Minimizer 53.199058
Total 76.250861
---------------------------------------------------
TBB
Time (in seconds):
Residual only evaluation 1.911095 (5)
Jacobian & residual evaluation 5.557807 (6)
Linear solver 44.074680 (5)
Minimizer 55.002688
Total 78.052687
---------------------------------------------------
No Threads
Time (in seconds):
Residual only evaluation 2.939212 (5)
Jacobian & residual evaluation 18.519874 (6)
Linear solver 74.017837 (5)
Minimizer 98.980080
Total 122.216391
Change-Id: I3af959b0771bbdfe8cad8c13896191d6ac903181
This improves the readability and simplifies the logic
for interfacing with ParallelFor. More importantly, it paves the
way for ParallelFor refactoring to improve its performance.
Change-Id: I13b05596228900ee00d71f2ccce1db338844b9ab
A Ceres Context holds common global state that can be re-used within
Ceres. The Context current contains a thread pool if compiling with
C++11 threading support. Threads are expensive to create and destroy so
it is good to maintain across multiple Ceres solves.
Tested by compiling with and without TBB support and ran unit tests. Ran
bazel as well.
Change-Id: I82f598dfae642aa0e81a6039dc174608a5e8dbfb
This is in preparation for adding support for a c++11 based parallel
for implementation. The parallel for abstraction does not have the
ability to constrain the total number of threads in nested for loops.
This is solved by distributing the number of threads evenly between
the nested for loops. Adds a TODO to consolidate the next for loops
into a single loop that can be properly split between threads.
Tested by building with TBB and running tests.
Change-Id: I546973b9a4d19b9cdd53caff55d1c80bac8ea953
Fixes the current implementation where the desired number of threads may
not be honored if another tbb::task_scheduler_init is instantiated. We
are using tbb::task_arena to solve this which is only available in newer
versions of TBB.
Also increases the performance by not creating/destroying the TBB setup
via tbb::task_scheduler_init on every iteration evaluation. This
increases the performance in single threaded mode using TBB by 10x.
By not specifically calling tbb::task_scheduler_init, this will either
respect any active tbb::task_scheduler_init instantiations or use the
default TBB settings which is hardware dependent. Ceres will honor the
user's requested number of threads through the task_arenas.
Tested via compiling with TBB enabled and ran the unit tests.
Change-Id: I5538407563449cdb5a0eaf8b8ccab62263912110
There are platforms where OpenMP is not available. This
patch adds support for Intel Threading Building Blocks (TBB)
as an alternative threading backend.
Change-Id: I94497d7cba0c3cfaccfc992169236f17fe948ae9
THIS IS AN API BREAKING CHANGE.
Decouple the algorithm from the sparse linear algebra
library being used to perform the computation.
Before this change
Covariance::AlgorithmType had values
DENSE_SVD
EIGEN_SPARSE_QR
SUITE_SPARSE_QR
This has been replaced by two enums now.
Covariance::Options::sparse_linear_algebra_library_type
which can take values EIGEN_SPARSE, SUITE_SPARSE or CX_SPARSE.
The last one is currently not supported.
And Covariance::Options::algorithm_type takes values
DENSE_SVD
SPARSE_QR
This sets the stage for future extensions of the covariance
computation algorithm.
Also as part of this change, the covariance computation chapter
has been made a top level chapter on its own instead of being
buried deep inside the Solving Non-linear Least Squares problem.
Change-Id: Ibfbf60902d8d17694d9ff585047a5a57d329ab22
Intel C compiler strictly asks for parallel loops with collapse to be
perfectly nested. Otherwise, compiling Ceres with ICC will throw an
error at line 348 of covariance_impl.cc.
Change-Id: I1ecb68e89b7faf79e4153dfe6675c390d1780db4