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
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
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
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
- 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
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
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
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
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
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
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
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
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
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
- 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
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
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
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
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
This CL removes a not used using declaration
which will cause a warning when compiled with
-Wunused-local-typedef under gcc.
Change-Id: Ie4cfd5d1fed9bee860e387545e60d92d257da4f4
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
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
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
- Required after updates to use Eigen's own Eigen3Config.cmake instead
of our original FindEigen.cmake module.
Change-Id: I9b5ad43fa153713c64fc01d638611e9bae3a169b
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
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
- 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
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
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
when using the command target_link_libraries explicitly state if the
linked library needs to be linked publicly or only private
Change-Id: I44eb7cb7ed06fdab12412963e6ce705b1fb718b4