- changed milestone to GTSAM 4 Roadmap: Expressions
Remove result values in ExpressionTrace
The A value
in expression-inl.h is superfluous, really:
template<class T, class A, size_t N>
struct JacobianTrace {
A value;
ExecutionTrace<A> trace;
typename Jacobian<T, A>::type dTdA;
};
In an Expression chain like uncalibrate(project(pose,point))
the value and derivatives are computed here:
T Expression<T>::value(const Values& values, JacobianMap& jacobians) const {
char raw[traceSize()];
ExecutionTrace<T> trace;
T value(traceExecution(values, trace, raw));
trace.startReverseAD(jacobians);
return value;
}
but the function that actually calculates all Jacobians in this tree is traceExecution
above. After completion, the raw pointer points to a UnaryExpression::Record
that contains all Jacobians but also all function values. That takes up a lot of space. The reason is that the method FunctionalNode::trace
only returns a Record*
, which contains all intermediate values
- pose
- point
- project(pose,point)
Instead, a the trace should just return the function value of the argument A1, for a UnaryExpression, a pair<A1,A2> for a BinaryExpression, etc... Along with the Record*, of course. Then we would not have to store values these in the Record.
As I write this down, however (mostly for myself and @hannessommer and @ptf), it occurs to me that the savings might not be that great: all these values will be allocated on the stack at one point, as is the Record storage, and all will disappear after Expression<T>::value
returns. Is there really value in making char raw[traceSize()]
smaller?
To get an idea of the sizes involved, here is a snippet of testExpressionFactor:
#ifdef GTSAM_USE_QUATERNIONS
EXPECT_LONGS_EQUAL(352, sizeof(Binary::Record));
LONGS_EQUAL(112+352, expectedTraceSize);
#else
EXPECT_LONGS_EQUAL(400, sizeof(Binary::Record));
LONGS_EQUAL(112+400, expectedTraceSize);
#endif
Comments (1)
-
reporter - Log in to comment