Autodiff Codegen Part 2: Conditionals

- Expression types for if/else blocks
- CERES_IF/ELSE macros
- Multiple assignment to the same variable

Change-Id: If529516f243f31823d1ef7b8827bb6f2390e418d
This commit is contained in:
Darius Rueckert
2019-10-21 11:01:08 +08:00
parent 52d6477a42
commit 6fd4f072d0
10 changed files with 608 additions and 94 deletions
+38 -2
View File
@@ -52,8 +52,26 @@ struct ExpressionRef {
// it's automatically converted to the correct expression.
explicit ExpressionRef(double compile_time_constant);
// Returns v_id
std::string ToString() const;
// Create an ASSIGNMENT expression from other to this.
//
// For example:
// a = b; // With a.id = 5 and b.id = 3
// will generate the following assignment:
// v_5 = v_3;
//
// If this (lhs) ExpressionRef is currently not pointing to a variable
// (id==invalid), then we can eliminate the assignment by just letting "this"
// point to the same variable as "other".
//
// Example:
// a = b; // With a.id = invalid and b.id = 3
// will generate NO expression, but after this line the following will be
// true:
// a.id == b.id == 3
//
// If 'other' is not pointing to a variable (id==invalid), we found an
// uninitialized assignment, which is handled as an error.
ExpressionRef& operator=(const ExpressionRef& other);
// Compound operators
ExpressionRef& operator+=(ExpressionRef x);
@@ -61,6 +79,8 @@ struct ExpressionRef {
ExpressionRef& operator*=(ExpressionRef x);
ExpressionRef& operator/=(ExpressionRef x);
bool IsInitialized() const { return id != kInvalidExpressionId; }
// The index into the ExpressionGraph data array.
ExpressionId id = kInvalidExpressionId;
@@ -152,6 +172,22 @@ inline typename RuntimeConstant<T>::ReturnType MakeRuntimeConstant(
#define CERES_EXPRESSION_RUNTIME_CONSTANT(_v) \
ceres::internal::MakeRuntimeConstant<T>(_v, #_v)
// The CERES_CODEGEN macro is defined by the build system only during code
// generation. In all other cases the CERES_IF/ELSE macros just expand to the
// if/else keywords.
#ifdef CERES_CODEGEN
#define CERES_IF(condition_) Expression::CreateIf((condition_).id);
#define CERES_ELSE Expression::CreateElse();
#define CERES_ENDIF Expression::CreateEndIf();
#else
// clang-format off
#define CERES_IF(condition_) if (condition_) {
#define CERES_ELSE } else {
#define CERES_ENDIF }
// clang-format on
#endif
} // namespace internal
// See jet.h for more info on this type.