Commit Graph

1559 Commits

Author SHA1 Message Date
Johannes Beck 84fdac38e0 Add const to GetCovarianceMatrix*
This CL adds const to the functions GetCovarianceMatrix and
GetCovarianceMatrixInTangentSpace.

Change-Id: Ibe2cafebede47977a9aabcac8d245f30af184fd1
2020-03-24 16:19:55 +00:00
Johannes Beck 6bde61d6be Add line local parameterization.
This CL adds a local parameterization for a n-dimensional
line, which is represented as an origin point and a direction.
The line direction is updated in the same way as a
homogeneous vector and the origin point is updated
perpendicular to the line direction.

Change-Id: I733f395e5cc4250abf9778c26fe0a5ae1de6b624
2020-03-23 22:36:39 -07:00
Sameer Agarwal 2c1c0932e9 Update documentation in autodiff.h
Change-Id: Icc2753b4f5be95022ffd92e479cdd3d9d7959d4c
2020-03-23 11:15:32 -07:00
Darius Rueckert 8904fa4887 Inline Jet initialization in Autodiff
Inlining the Jet initialzation is mandatory for good performance
in autodiff, because all the constants in the dual part can be
propagated into the cost functor.

This patch unrolls the initialization loop with templates and adds
EIGEN_ALWAYS_INLINE to the constructors.

Change-Id: Ic89d645984f3e1df6c63948236da823ba60d9620
2020-03-23 15:20:57 +01:00
Sameer Agarwal 18a464d4e5 Remove an errant CR from local_parameterization.cc
Change-Id: Iff98a96f06de5755062a1c79523604dca78b298e
2020-03-23 07:12:12 -07:00
Darius Rueckert 5c85f21799 Use ArraySelector in Autodiff
The class ArraySelector is now used in autodiff to store the
parameters and residuals. This reduces overhead of FixedArray
for fixed-sized residuals and allows more optimizations due
to inlining and unrolling.

Change-Id: Ibadc5644e64d672f7a555e250fb1f8da262f9d4f
2020-03-23 14:06:02 +01:00
Darius Rueckert 80477ff073 Add class ArraySelector
The ArraySelector selects the best array implementation based on
template arguments.

Change-Id: I93c6db1a638e924b85292e63bca9525610ec2e2f
2020-03-20 19:12:25 +01:00
Darius Rueckert e7a30359ee Pass kNumResiduals to Autodiff
The compile-time constant kNumResiduals is now passed to the
autodiff functions as a template parameter. This will be used
by future patches to optimize autodiff performance.

Change-Id: Ia2b2cc99b88752e8f12f4ce2542b1963bda552f5
2020-03-20 15:57:34 +01:00
Sameer Agarwal f339d71dd6 Refactor the automatic differentiation benchmarks.
1. Merge them into a single binary.
2. All benchmarks now do the Residual and the Residual + Jacobian
evaluation.
3. Re-organize and simplify the CMake file in this directory.
4. Fix a bug in the file where the Clang compiler was not being matched.

autodiff_benchmarks
---------------------------------------------------------------------------
Benchmark                                 Time             CPU   Iterations
---------------------------------------------------------------------------
BM_Linear1CodeGen/0                    3.02 ns         3.01 ns    233870456
BM_Linear1CodeGen/1                    3.02 ns         3.01 ns    233059100
BM_Linear1AutoDiff/0                   3.78 ns         3.77 ns    185791712
BM_Linear1AutoDiff/1                   14.0 ns         13.8 ns     53927875
BM_Linear10CodeGen/0                   5.10 ns         5.10 ns    126745007
BM_Linear10CodeGen/1                   29.1 ns         29.1 ns     23949310
BM_Linear10AutoDiff/0                  6.50 ns         6.49 ns    107516972
BM_Linear10AutoDiff/1                   169 ns          169 ns      4153218
BM_Rat43AutoDiff/0                     52.7 ns         51.2 ns     16444586
BM_Rat43AutoDiff/1                     91.8 ns         91.5 ns      7302316
BM_SnavelyReprojectionCodeGen/0        38.0 ns         36.2 ns     21131501
BM_SnavelyReprojectionCodeGen/1         113 ns          112 ns      5627779
BM_SnavelyReprojectionAutoDiff/0       34.4 ns         34.3 ns     20476937
BM_SnavelyReprojectionAutoDiff/1        242 ns          240 ns      2930611
BM_BrdfCodeGen/0                       53.9 ns         53.7 ns     11950083
BM_BrdfCodeGen/1                        507 ns          505 ns      1396732
BM_BrdfAutoDiff/0                      58.3 ns         57.8 ns     12220670
BM_BrdfAutoDiff/1                      2034 ns         1999 ns       257003

autodiff_benchmarks_fast_math
---------------------------------------------------------------------------
Benchmark                                 Time             CPU   Iterations
---------------------------------------------------------------------------
BM_Linear1CodeGen/0                    3.19 ns         3.16 ns    215313065
BM_Linear1CodeGen/1                    2.78 ns         2.76 ns    201497994
BM_Linear1AutoDiff/0                   3.27 ns         3.26 ns    206154598
BM_Linear1AutoDiff/1                   13.2 ns         13.1 ns     57257840
BM_Linear10CodeGen/0                   5.70 ns         5.51 ns    121849325
BM_Linear10CodeGen/1                   33.9 ns         33.3 ns     21829295
BM_Linear10AutoDiff/0                  6.85 ns         6.78 ns    106813153
BM_Linear10AutoDiff/1                   173 ns          171 ns      3849877
BM_Rat43AutoDiff/0                     44.8 ns         44.2 ns     15577017
BM_Rat43AutoDiff/1                     96.2 ns         94.6 ns      7374864
BM_SnavelyReprojectionCodeGen/0        33.9 ns         33.5 ns     20508373
BM_SnavelyReprojectionCodeGen/1        89.7 ns         88.4 ns      7620624
BM_SnavelyReprojectionAutoDiff/0       36.5 ns         35.8 ns     20546176
BM_SnavelyReprojectionAutoDiff/1        257 ns          252 ns      3044325
BM_BrdfCodeGen/0                       61.1 ns         58.5 ns     11334013
BM_BrdfCodeGen/1                        265 ns          265 ns      2625459
BM_BrdfAutoDiff/0                      52.5 ns         52.5 ns     12938763
BM_BrdfAutoDiff/1                      1560 ns         1560 ns       440909

Change-Id: I2d1a4293d3245a50f73af6cf5e5138084321ae6f
2020-03-19 12:18:52 -07:00
Sameer Agarwal d37b4cb150 Fix some include headers in codegen/test_utils.cc/h
Change-Id: I769029ce2797eba0de6c7baeb76dc3f2782b6305
2020-03-19 07:36:58 -07:00
Darius Rueckert 550766e6da Add Autodiff Brdf Benchmark
The disney brdf is a good benchmark cost functor, because it has
 - 28 parameters in 7 blocks
 - 3 residuals
 - Lots of low-level arithmetic

Change-Id: I62c8a717d0aecb64639158f971bdccf6afdfae36
2020-03-19 14:54:08 +01:00
Darius Rueckert 8da9876e7a Add more autodiff benchmarks
- Create new subdirectory internal/ceres/autodiff_benchmarks
- Move the ba-autodiff benchmark to the new subdir.
- Add new autodiff benchmarks for linear cost functions (1 and 10 params)

Change-Id: Ic0e31cf2c05389935bb90c6a4fd9c0382a7e1ed0
2020-03-18 16:31:07 +01:00
Enrique Fernandez 6da364713f Fix Tukey loss function
Since the output of LossFunction::Evaluate is multiplied by 0.5, the
current implementation of the Tukey loss function must be multiplied
by 2.

Change-Id: Ia94753eef1a375fe48cc2e0d2cc61350904c8248
2020-03-17 19:42:03 +00:00
Darius Rueckert cf4185c4e3 Add Codegen BA Benchmark
Add a benchmark that compares codegen-autodiff versus old autodiff
on the snavely reprojection error cost function. This creates two
new cmake targets:

codegen_ba_benchmark
codegen_ba_benchark_fast_math

The second one is only enabled on Clang and includes all known
optimizations.

Change-Id: Ibc30dc8b67b4c0fece41142914f9118f16ff1e20
2020-03-17 18:17:37 +01:00
Darius Rueckert 75dd30faed Simplify GenerateCodeForFunctor
- Don't trace residual -> Use input cost functor instead
- Remove unnecessary copy from tmp jacobian array
- Fix indent of generated Evaluate() function

Change-Id: I23e09987d8ec30f7202a93eb253648505dcaaa4e
2020-03-12 09:22:59 +01:00
Darius Rueckert 9049688c60 Default Initialize ExpressionRef to Zero
The default constructor of ExpressionRef now creates a compile
time constant zero assignment. This patch is required, because
a reason change in Jet assumes default 0 initialization.

Change-Id: I8185cef587c17ab828896bce1e768170f8229d4e
2020-03-10 09:30:34 +01:00
Julian Kent bf1aff2f0e Fix 3+ nested Jet constructor
In Jet types, there is an attempt to set the derivative to 0.
However, if the derivative is not directly a scalar but a Jet<Jet>,
this cannot be constructed directly from a 0 literal. This is solved
by using the default constructor for the scalar type instead of 0.

The typical use case for this is adding constraints to the second
derivative of a curve in an Autodiff cost function.

Change-Id: Id480096632a731f312be12e294b3d6e244211529
2020-03-07 12:23:16 +01:00
Darius Rueckert 92d6541c77 Move Codegen files into codegen/ directory
Change-Id: I0eec4ee0d27ab39afb971328efadf31807304011
2020-02-26 16:25:04 +01:00
Darius Rueckert 8e962f37d7 Add Autodiff Codegen Tests
This patch adds end-to-end tests for the autodiff codegen system.
First, code is generated for various functors. This code is then
executed with different arguments and the result is compared
to traditional autodiff.

Change-Id: Icba9996ece26384a795d5b50480ec8194cab572f
2020-02-25 08:57:22 +01:00
Darius Rueckert 13c7a22cee Codegen Optimizer API
This patch adds the classes Optimizer and OptimizationPass, which
define the core API of the codegen optimization.

A single (trivial) optimization is added that removes NOP
expressions from a graph.

Change-Id: I0430d6ffc61a474f997475ff787a81a9c69cfe23
2020-02-18 10:50:10 +01:00
Darius Rueckert 90799e29e1 Fix install and unnecessary string copy
- Fix the following issue when running "make install"
  https://github.com/ceres-solver/ceres-solver/issues/527

- Fix error that CeresCodeGeneration.cmake was not found
  after instalation. Issue:
  https://github.com/ceres-solver/ceres-solver/issues/561

- Removes the unnecessary string copy during code generation

Change-Id: I01963d01da6a9c4557aad6f89831647c1a149e38
2020-02-14 13:11:15 +01:00
Darius Rueckert 032d5844c2 AutoDiff Code Generation - CMake Integration
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
2020-02-13 13:57:14 +01:00
Darius Rueckert d82de91b88 Add ExpressionGraph::Erase(ExpressionId)
Add the function ExpressionGraph::Erase and a test-case for it.
Erase removes the given expression from the graph by shifting
all later expressions to the front. Indices and references
are updated accordingly.

Change-Id: Ic0449ccf28b369600fd2959a7e2a919d47f4cbe3
2020-02-10 16:19:55 +01:00
Darius Rueckert c8e35e19fd Add namespaces to generated functions and constants
The generated function names now include the containing namespace.
For example:
	std::abs(...)
	std::sin(...)
	ceres::Ternary(...)

This patch also fixes the generation of inf/nan compile time constants,
using std::numeric_limits.

Change-Id: I4a36b09c68dd2adabed49fd4f7f37c8229ab7377
2020-02-07 14:51:18 +01:00
Alex Stewart 75e575cae0 Fix use of incomplete type in defaulted Problem methods
- As Problem contains a unique_ptr<ProblemImpl> and as defaulted
  methods are declared inline where ProblemImpl's implementation is not
  available use of '= default' will generate compile errors on strict
  compilers.
- This CL moves the definition of defaulted methods to the
  implementation.

Change-Id: I7d79757cf684378fadef8e6f4000c84387018cdb
2020-01-19 16:57:38 +00:00
Darius Rueckert 8def196166 Remove ExpressionRef Move Constructor
The move constructor and move =operator are not required. They make
the code more complex and prone to bugs. The few saved assignments
are all trivial and are optimized away by the compiler or our
optimizer.

In fact, there is a bug in the current move-constructor implementation
that occurs, for example, when moving Eigen matrices around.

Change-Id: I013796495bb39f3f27677111bd0aaf49e2454e20
2020-01-14 17:00:31 +01:00
Johannes Beck f26f954105 Fix windows MSVC build.
This CL improves the build experience with MSVC:
- It adds the build flag '/bigobj' otherwise the build of
  the unit test fails.
- It adds the flag '/wd4267' to suppress signed / unsigned int
  conversions (size_t to int).
- It removes the use of std::aligned_storage from FixedArray.
  This has been done from the Abseil Team and is in the
  absl::FixedArray. Those changes has been ported to ceres.
  This fixes the alignemnt for older MSVC versions due to a
  bug in the implementation of std::aligned_storage, and
  prevents the use of the macro '_ENABLE_EXTENDED_ALIGNED_STORAGE'
  for newer MSVC versions, which is problematic as it could affect
  user code.
- Fix of the fixed array unit test. Due to the use of std::tuple
  instead of absl::tuple in ceres::internal::FixedArray, the
  unit test needs to reflect that change as well.
- Replaces 'add_definitions' with 'add_compile_options' for
  compiler flags as suggested by the cmake documentation.

Change-Id: I63f08cd6c0a8db8c9931289b909b4deafd75b039
2020-01-07 17:25:54 +00:00
Darius Rueckert fdf9cfd320 Add functions to find the matching ELSE, ENDIF expressions
ExpressionId FindMatchingEndif(ExpressionId id)
   - Finds the closing ENDIF expression for a given IF expression.

ExpressionId FindMatchingElse(ExpressionId id)
   - Finds the ELSE expression for a given IF expression.
   - Returns -1, if this IF doesn't have an else

This patch is a preparation to the code analyzing required
for various optimization passes.

Change-Id: I893102a757c6a0bcacbcc1190c2b8ef08314eb97
2020-01-07 09:35:09 +01:00
Johannes Beck 678c05b289 Fix invert PSD matrix.
This CL fixes and simplifies the implementation of InvertPSDMatrix.
InvertPSDMatrix uses a JacobiSVD with thin U and V. This requires a
variable number of columns, which is not always the case, which
triggers an assert in debug mode. The type of the matrix is changed
to always use a dynamic number of columns.

In addition, instead of calculating the inverse of the matrix by hand,
the SVD solve method is used.

Change-Id: I353c741cf537b58eb5b18663902318babe1a66de
2020-01-03 01:44:17 +00:00
Johannes Beck a384a7e96e Remove not used using declaration
This CL removes a not used using declaration
which will cause a warning when compiled with
-Wunused-local-typedef under gcc.

Change-Id: Ie4cfd5d1fed9bee860e387545e60d92d257da4f4
2019-12-31 13:38:46 +01:00
Darius Rueckert a60136b7aa Add COMMENT ExpressionType
The comment expression allows the user to insert single-line
comments into the generated code. These will not be moved or
optimized away.

Comment expressions should make it easier to understand the
generated autodiff code.

Change-Id: Ie87d0698aa6af2aac8a437a13b25e0fef33dbfdc
2019-12-18 09:44:33 +01:00
Sameer Agarwal f212c92954 Let Problem::SetParameterization be called more than once.
https://github.com/ceres-solver/ceres-solver/issues/501

Change-Id: Ia94e6e62553e97fa2052db2cbebc5c472e26a406
2019-12-17 19:00:06 +00:00
NeroBurner a3696835b4 use CMake function to create CeresConfigVersion
Use the CMake provided module CMakePackageConfigHelpers and its function
write_basic_package_version_file() to write the CeresConfigVersion.cmake
file to be installed.

Use SameMajorVersion compatibility flag.

Change-Id: I353aa8ede1ffee34e58b41371958ed5dedca4104
2019-12-17 18:40:26 +00:00
Sameer Agarwal 67fcff9182 Make Problem movable.
Add a default move constructor and move assignment operator.

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

Change-Id: I16ecf367a800fde564c29e2b824cd4fb44111366
2019-12-17 05:32:29 -08:00
Sameer Agarwal 19728e72d4 Add documentation for Problem::IsParameterBlockConstant
https://github.com/ceres-solver/ceres-solver/issues/485

Change-Id: I1d3d7e6bb2a33e2202b71c989164dd805fb54b89
2019-12-16 16:59:34 -08:00
NeroBurner ba6e5fb4ad Make the custom uninstall target optional
Ceres-solver provides a custom uninstall target to ease the removal of
installed files from the system. This clashes with other projects, that
too provide an uninstall target (like Eigen3).

Related issue: https://github.com/ceres-solver/ceres-solver/issues/451#issuecomment-565571090

Change-Id: Id153830ae20a880d23c7468acb39f55f48a2129a
2019-12-16 19:25:42 +00:00
Sameer Agarwal 8547cbd55f Make EventLogger more efficient.
If VLOG(3) is not enabled, then eliminate all work done by the
EventLogger constructor.

Change-Id: I0f8512dcb275b68ad443b2e26bc1da58a3238b0a
2019-12-15 14:40:53 -08:00
Sameer Agarwal edb8322bda Update the minimum required version of Eigen to 3.3.
Change-Id: I6e6bd745311b7d4f1d5b749ec70d314f9e765438
2019-12-13 09:43:10 -08:00
Alex Stewart aa6ef417f3 Specify Eigen3_DIR in iOS and Android Travis CI builds
- Required after updates to use Eigen's own Eigen3Config.cmake instead
  of our original FindEigen.cmake module.

Change-Id: I9b5ad43fa153713c64fc01d638611e9bae3a169b
2019-12-13 13:52:39 +00:00
Alex Stewart 4655f2549c Use find_package() instead of find_dependency() in CeresConfig.cmake
- Revert to original usage for compatibility with the stated minimum
  required CMake version: 3.5

Change-Id: Ifb15f97a1d8e9cc5742564bc22a8761840c08e06
2019-12-13 11:56:06 +00:00
NeroBurner a548766d14 Use glfags target
Update the usage of Google Flags (gflags) library the same way Glog
updated it [1]. This pushes the minimum required gflags version to
v2.2.0.

Remove the ceres specific define of CERES_GFLAGS_NAMESPACE and directly
use GFLAGS_NAMESPACE defined in gflags/gflags_declare.h [2].

In CeresConfig.cmake the hard coded paths for gflags are ommited.
Instead we rely on the gflagsConfig file to get closer to a relocatable
CeresConfig.cmake.
Furthermore use the find_dependency() [4] cmake function specifically
created for cmake-config files.

This change builds upon the explicit PUBLIC/PRIVATE link change [3].

[1] https://github.com/google/glog/pull/199
[2] https://github.com/gflags/gflags/blob/d9b184bd0026b16bb4c2fded75d56fb2cce50d66/src/gflags_declare.h.in#L43
[3] https://ceres-solver-review.googlesource.com/c/ceres-solver/+/16220
[4] https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html

Change-Id: I9861a2699f2702bf1a5e99d07863a7e6639b7c39
2019-12-12 14:00:59 +00:00
NeroBurner 33dd469a53 Use Eigen3::Eigen target
Since version 3.3 Eigen provides Eigen3Config.cmake with the imported
target Eigen3::Eigen. [1]
Use this imported target as descibed in Eigen-Wiki [2]

In the CeresConfig file improve relocatability by removing absolute
paths to the compiled dependencies. Instead find the used Eigen3::Eigen.
Furthermore use the find_dependency() [4] CMake function instead of the
find_package() call in CeresConfig.

This commit relies on all targets to be explicitly linked private or
public as done in the the change [3]

[1] https://bitbucket.org/eigen/eigen/pull-requests/257/cmake-imported-target-take-2/diff
[2] https://eigen.tuxfamily.org/dox/TopicCMakeGuide.html
[3] https://ceres-solver-review.googlesource.com/c/ceres-solver/+/16220
[4] https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html

Change-Id: I44f44a089083f7169bcf430b59775242e4eb72d1
2019-12-12 14:56:00 +01:00
Darius Rueckert 47e784bb41 NULL-jacobians are handled correctly in generated autodiff code
The autodiff code generator is extended in the following ways:
  - Evaluate the complete jacobian into a temporary array
  - Copy the temporary jacobian to the result if != NULL

Change-Id: If5ed0bff3b31e93a2d7d5dc718862cb648dba474
2019-12-10 15:19:48 +01:00
Darius Rueckert edd54b83e1 Update Jet.h and rotation.h to use the new IF/ELSE macros
Also use branchless implementation for isfinite(Jet),
isinf(Jet), isnan(Jet), and isnormal(Jet).

Change-Id: Ia881df03ba873e0560d67e976ab1e99e199eb523
2019-12-09 18:30:30 +01:00
Darius Rueckert 848c1f90c0 Update return type in code generator and add tests for logical functions
Change-Id: I128f8ccc21c2c3a2c79674ac28dd9a5b26b58772
2019-12-09 17:57:10 +01:00
Darius Rueckert 5010421bb7 Add the expression return type as a member to Expression
Before this patch the return type was implicitly defined by the
ExpressionType. This patch separates this connection and allows
each Expression to have one of the predefined types (scalar,
boolean, void).

This patch is required to add support for the functions isfinite,
isinf, isnan, and isnormal. These are function taking a double and
returning a bool.

This also moves some complexity of the code generator to the
Expression, because the generator can direclty get the c++ type.

Change-Id: I8b32bab1bfab2f668875e506d6f3b789a5d1f3fd
2019-12-09 17:13:05 +01:00
Darius Rueckert f4dc670ee8 Improve testing of the codegen system
- Move codegen tests to a sub directory
- Add tests for all functions of Expression, ExpressionRef, and ExpressionGraph
- Respect dependencies during tests: The ExpressionGraph test doesn't
  use ExpressionRef anymore.

The new tests revealed a few bugs so the following changes were made:

- Expression::MakeNop now resets the current expression with the default
  constructed NOP expression
- ExpressionGraph::Insert now updates the lhs_id the same way as
  InsertBack()

Change-Id: I6a18925c1e4d972c29ec1219f2073b4eaf2df737
2019-12-09 15:13:07 +01:00
Darius Rueckert 572ec4a5a5 Rework Expression creation and insertion
Objects of 'Expression' can now be freely created and copied around.
This creation does NOT add them to the active ExpressionGraph any
more. The insertion into the graph is now done by ExpressionRef,
which explicitly call graph.add(...) in each operation.

This change brings the following advantages:

1. 'Expression' is now stand-alone and side-effect free
   - Remove the dependency Expression->ExpressionGraph
   - Expressions can be created by the optimizer

2. Explicit graph insertion
  - Previously CreateCompileTimeConstant not only created an
    expression, but also inserted it into the active graph. Now
    this insertion is done explicitly by ExpressionRef

3. It is now easier to insert new types and members
  - Should be straight forward now, because we got rid of the
    3-way dependency
  - This is a preparation patch for the new return-type member in
    https://ceres-solver-review.googlesource.com/c/ceres-solver/+/16224

Change-Id: Icef2fe529a4db001a10d1fb6816c9dc681b14ff2
2019-12-06 13:35:21 +01:00
Darius Rueckert c7337154e9 Disable the code generation module by default
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
2019-12-05 17:44:07 +01:00
NeroBurner 7fa0f3db41 Explicitly state PUBLIC/PRIVATE when linking
when using the command target_link_libraries explicitly state if the
linked library needs to be linked publicly or only private

Change-Id: I44eb7cb7ed06fdab12412963e6ce705b1fb718b4
2019-12-04 07:08:09 +00:00