Commit Graph

40 Commits

Author SHA1 Message Date
Sameer Agarwal 06bfe6ffac Remove OpenMP and No threading backends.
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
2022-11-27 21:06:33 -08:00
Sergiu Deitsch 388c142866 Fix GCC 12.1.1 LTO -Walloc-size-larger-than= warnings
With -flto=auto, GCC emits multiple warnings in release builds such as

In function ‘make_unique’,
    inlined from ‘Create’ at ceres-solver/internal/ceres/scratch_evaluate_preparer.cc:43:75,
    inlined from ‘CreateEvaluatePreparers’ at ceres-solver/internal/ceres/compressed_row_jacobian_writer.h:95:66,
    inlined from ‘__ct ’ at ceres-solver/internal/ceres/program_evaluator.h:120:9,
    inlined from ‘Evaluate.constprop.isra’ at ceres-solver/internal/ceres/problem_impl.cc:695:65:
/usr/include/c++/12.1.1/bits/unique_ptr.h:1080:30: warning: argument 1 value ‘18446744073709551615’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
 1080 |     { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
      |                              ^

because a signed integer is used to specify the size of allocated arrays
instead of the expected unsigned (specifically, std::size_t) without
checking for negative values at the call site.

Change-Id: I923b1d074241535426bfea041568ef1dc7f3ec86
2022-08-16 21:23:12 +00:00
Sameer Agarwal 84e1696f4e Add final specifier to internal classes.
This should help the compiler devirtualize a bunch of function
calls.

https://github.com/ceres-solver/ceres-solver/issues/747

Change-Id: I9913e68d85e0e9c9f955a249cc710a657875c869
2022-02-18 18:07:06 +00:00
Sergiu Deitsch f90833f5fa Simplify symbol export
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
2022-02-14 20:19:08 +01:00
Sameer Agarwal 44039af2cb Convert factory functions to return std::unique_ptrs.
https://github.com/ceres-solver/ceres-solver/issues/755

Change-Id: I8ff028ca6082a5f448f3891214af03971d565937
2022-02-10 16:16:37 -08:00
Sameer Agarwal ae65219e04 ClangTidy cleanups
1. NULL -> nullptr
2. foo.reset(new Bar) -> = foo = std::make_unique<Bar>()
3. Missing std library includes & prefixes

Change-Id: I260b261b484554be681ee5a7398126fdb3b3a789
2022-02-09 10:06:49 -08:00
Sameer Agarwal 125a0e9be5 LocalParameterization -> Manifold #1
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
2022-01-18 15:59:45 -08:00
Nikolaus Demmel 7b8f675bfd fix formatting for (non-generated) internal source files
- 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
2020-09-21 02:52:07 +02:00
Alex Stewart 7ef83e0759 Update minimum required C++ version for Ceres to C++14
- 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
2020-05-30 19:15:03 +01:00
Sameer Agarwal adb973e4a3 NULL -> nullptr
Change-Id: Iaeea2ef7912d328653a76b65976adc8025a5be35
2020-05-21 14:48:46 -07:00
Sameer Agarwal 2ffddaccfe Use override & final instead of just using virtual.
This is safer than using virtual and this lead to a minor
bug fixes.

Change-Id: Id69cb1cc569bf6bf245f22f029c7871b6c712568
2019-07-25 16:29:14 -07:00
Alex Stewart 16f9b34c3b Remove Intel TBB threading support.
- 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
2018-07-03 18:05:36 +00:00
Mike Vitus 5d8b494557 Adds a ParallelFor wrapper for no threads and OpenMP.
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
2018-04-09 10:10:03 -07:00
Keir Mierle 7c4e8a454e Replace scoped_ptr with C++11's unique_ptr
Change-Id: Ib5a504c491e3a79af52a95accf009df473470c6b
2018-04-02 14:47:47 -07:00
Keir Mierle 7bdceb46cf Evaluation callback API
This adds a callback mechanism to for users to get notified just
before jacobian and residual evaluations. This will enable
aggressive caching and sharing of compute between cost functions.

Change-Id: I67993726920218edf71ab9ae70c34c204756c71a
2018-03-07 12:41:22 -08:00
Mike Vitus f0c3b23684 Increases the performance of the C++11 threading.
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
2018-03-01 09:00:44 -08:00
Mike Vitus f408f89e8b Adds a Ceres Context structure.
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
2018-02-26 10:37:53 -08:00
Mike Vitus dc5ea0ea4d Adds a ParallelFor wrapper for tbb::parallel_for.
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
2018-02-16 14:24:17 -08:00
Sameer Agarwal 2145c10539 Improve ExecutionSummary
1. Replace two maps by 1.
2. Update number of calls and the time for the call at the cost
   of a single map lookup.
3. Add Solver::Summary::num_linear_solves.

Fixes https://github.com/ceres-solver/ceres-solver/issues/340

Change-Id: I71eb9be7fb363a8cb066591c4c1761f256c81677
2018-02-05 16:37:27 -08:00
Mike Vitus 852473b5f8 Changes TBB to use tbb::task_arena instead of tbb::task_scheduler_init.
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
2017-12-07 15:00:50 -08:00
Yury Prokazov 4ffec20a44 Add TBB threading support.
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
2017-09-25 12:43:14 +02:00
pmoulon afe93546b6 Use const keyword for 'int thread_id' variables.
Change-Id: I3afdf8a472cbc4f325b462bc9c42c03bc464f4b2
2017-08-06 00:57:38 +02:00
Keir Mierle 7492b0d8de Update copyright headers with new year and URL
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
2015-03-18 05:43:23 +00:00
Chris Sweeney 8db90ca2f6 Less strict check for multithreading.
Removes the CHECK-fail for num_threads > 1 when
OpenMP is not detected

Change-Id: I5c1d48aad66c8b7a1f73c93dae572b73953859a0
2015-03-15 19:13:42 +01:00
Sameer Agarwal 05a07ecc77 Remove using std::string from port.h
Change-Id: I7376f5e7eace22ec1fc05a61eaa858594f08682d
2015-01-07 15:10:46 -08:00
Sameer Agarwal bcc865f81c Remove using namespace std;
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
2015-01-07 14:26:53 -08:00
Alex Stewart ea76585068 Adding autogenerated Ceres config.h to #define Ceres compile options.
- 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
2014-05-09 10:57:31 +01:00
Richard Stebbing 32530788d0 Add dynamic_sparsity option.
The standard sparse normal Cholesky solver assumes a fixed
sparsity pattern which is useful for a large number of problems
presented to Ceres. However, some problems are symbolically dense
but numerically sparse i.e. each residual is a function of a
large number of parameters but at any given state the residual
only depends on a sparse subset of them. For these class of
problems it is faster to re-analyse the sparsity pattern of the
jacobian at each iteration of the non-linear optimisation instead
of including all of the zero entries in the step computation.

The proposed solution adds the dynamic_sparsity option which can
be used with SPARSE_NORMAL_CHOLESKY. A
DynamicCompressedRowSparseMatrix type (which extends
CompressedRowSparseMatrix) has been introduced which allows
dynamic addition and removal of elements. A Finalize method is
provided which then consolidates the matrix so that it can be
used in place of a regular CompressedRowSparseMatrix. An
associated jacobian writer has also been provided.

Changes that were required to make this extension were adding the
SetMaxNumNonZeros method to CompressedRowSparseMatrix and adding
a JacobianFinalizer template parameter to the ProgramEvaluator.

Change-Id: Ia5a8a9523fdae8d5b027bc35e70b4611ec2a8d01
2014-04-28 07:13:09 +00:00
Sameer Agarwal 367b65e17a Multiple dense linear algebra backends.
1. When a LAPACK implementation is present, then
DENSE_QR, DENSE_NORMAL_CHOLESKY and DENSE_SCHUR
can use it for doing dense linear algebra operations.

2. The user can switch dense linear algebra libraries
by setting Solver::Options::dense_linear_algebra_library_type.

3. Solver::Options::sparse_linear_algebra_library is now
Solver::Options::sparse_linear_algebra_library_type to be consistent
with all the other enums in Solver::Options.

4. Updated documentation as well as Solver::Summary::FullReport
to reflect these changes.

Change-Id: I5ab930bc15e90906b648bc399b551e6bd5d6498f
2013-08-13 14:57:03 -07:00
Sameer Agarwal a427c877f9 Lint cleanup.
Change-Id: Ie489f1ff182d99251ed8c0728cc6ea8e1c262ce0
2013-06-24 18:04:28 -07:00
Sameer Agarwal c3c3dd872b Use the evaluator to compute the gradient in TrustRegionMinimizer.
Evaluator now uses custom BLAS for gradient
computations.

Update the evaluator in trust_region_minimizer_test to compute
gradients.

Change-Id: I3f565bc203b47b2b795a0609d67f25775648653c
2013-04-26 07:38:13 -07:00
Sameer Agarwal 039ff07dd1 Evaluate ResidualBlocks without LossFunction if needed.
1. Add the ability to evaluate the problem without loss function.
2. Remove static Evaluator::Evaluate
3. Refactor the common code from problem_test.cc and
   evaluator_test.cc into evaluator_test_utils.cc

Change-Id: I1aa841580afe91d288fbb65288b0ffdd1e43e827
2013-02-27 05:38:28 +00:00
Sameer Agarwal 509f68cfe3 Problem::Evaluate implementation.
1. Add Problem::Evaluate and tests.
2. Remove Solver::Summary::initial/final_*
3. Remove Solver::Options::return_* members.
4. Various cpplint cleanups.

Change-Id: I4266de53489896f72d9c6798c5efde6748d68a47
2013-02-24 19:04:21 +00:00
Sameer Agarwal 42a84b87fa Expand reporting of timing information.
1. Add an ExecutionSummary object to record execution
   information about Ceres objects.
2. Add an EventLogger object to log events in a function call.
3. Add a ScopedExecutionTimer object to log times in ExecutionSummary.
4. Instrument ProgramEvaluator and all the linear solvers
   to report their timing statistics.
5. Connect the timing statistics to Summary::FullReport.
6. Add high precision timer on unix systems using
   gettimeofday() call.
7. Various minor clean ups all around.

Change-Id: I5e09804b730b09535484124be7dbc1c58eccd1d4
2013-02-06 01:00:38 -08:00
Sameer Agarwal 31432aeec4 Fix an initialization bug in ProgramEvaluator.
The buffers used to store the per thread value of the gradient
were not set to zero at the beginning of each call to evaluate.

Change-Id: I9c8afea54a4e2e0b805164025da3023166a309af
2012-11-25 18:36:04 -08:00
Sameer Agarwal 9123e2f624 An implementation of Ruhe & Wedin's Algorithm II.
A non-linear generalization of Ruhe & Wedin's algorithm
for separable non-linear least squares problem. It is implemented
as coordinate descent on an independent subset of the parameter
blocks at the end of every successful Newton step. The resulting
algorithm has much improved convergence at the cost of some
execution time.

Change-Id: I8fdc5edbd0ba1e702c9658b98041b2c2ae705402
2012-09-25 11:13:39 -07:00
Keir Mierle f44907f702 Compute the gradient if requested in the evaluator
This extends the Evaluator interface to support evaluating the
gradient in addition to the residuals and jacobian, if requested.

   bool Evaluate(const double* state,
                 double* cost,
                 double* residuals,
                 double* gradient,  <----------- NEW
                 SparseMatrix* jacobian) = 0;

The ProgramEvaluator is extended to support the new gradient
evaluation. This required some gymnastics around the block
evaluate preparer, which now contains a scratch evaluate preparer
for the case that no jacobian is requested but the gradient is.

Gradient evaluation is a prerequisite for the planned suite of
first order methods, including nonlinear conjugate gradient,
CG_DESCENT, L-BFGS, trust region with line search, and more.

This also considerably refactors the evaluator_test to make it
shorter and check the results for all combinations of the optional
parameters [residuals, gradient, jacobian].

Change-Id: Ic7d0fec028dc5ffebc08ee079ad04eeaf6e02582
2012-07-11 09:44:45 -07:00
Sameer Agarwal 319ef465e2 1. Zero out the residuals vector before it is used.
2. explicit comparison with NULL for jacobian and residuals pointers.
2012-05-22 20:44:52 -07:00
Keir Mierle cc38774d74 Clarify ProgramEvaluator comments. 2012-05-03 01:27:50 -07:00
Keir Mierle 8ebb073038 Initial commit of Ceres Solver. 2012-04-30 23:09:08 -07:00