How to serialize Expressions

Issue #171 new
Paul Furgale created an issue

Serializing optimization problems is good news for debugging. I spent some time today looking into the possibility of serializing Expressions but it looks like bad news all around (c.f. https://groups.google.com/forum/#!topic/boost-list/sHWRPlpPsf4 or http://bit.ly/1FoRooA).

The only real solution that I can see would be to create our own FunctionPointer hierarchy and keep a serializable base class.

like:

template<ReturnValue, Argument1, Argument2>
struct Function2 {
  // typedefs for discerning the matrix sizes using traits.
  virtual ReturnValue f(const Argument1& a1, const Argument2& a2, 
                                    boost::optional<H1Matrix&> H1, boost::optional<H2Matrix&> H2) = 0; 
  // boost::serialization code here...

};

struct MyBadFunction : public Function2< Point3, Rot3, Point3 > {
  virtual Point3 f(const Rot3& R, const Point3& p, 
                          boost::optional<H1Matrix&> H1, boost::optional<H2Matrix&> H2) {
    // implementation...
  } 
  // more boost::serialization stuff...
};

Somewhat less elegant than the current setup. And a little ugly. But not that much more code in the end.

Thoughts?

Comments (13)

  1. Frank Dellaert

    Hmmm. I think we should have expressions.h files in geometry/sam/sfm. We can attempt to make those expressions serializable, but we should not take away the ability of users to add custom expressions based simply on their own free functions/methods, IMHO.

  2. Paul Furgale reporter

    No. There is no magic to serialize function pointers. That is why you need functors. The functor type is used to look up the correct function during serialization/deserialization.

  3. Paul Furgale reporter

    OK, I looked in to this a bit. The short answer is: UnaryExpression, BinaryExpression, and others that include a boost::function as a member are not serializable.

    We should be able to implement serialization for expressions that use the pattern above (instead of plain old function pointers) but then support function pointers as non-serializable expressions (i.e. just throw an exception if you try to serialize them.

    I can try to do this.

  4. Frank Dellaert

    No, I was not imagining that fully generic serialization was possible. But we have started having expressions.h files in several application directories, and say, the transform_to expression in slam/expressions.h could implement serialization, as it knows which function it refers to (Pose3::*transform). So, as long as each Expression in a tree has a serialize, you should be able to serialize the entire tree, no?

  5. Paul Furgale reporter

    So, as long as each Expression in a tree has a serialize, you should be able to serialize the entire tree, no?

    This is true, but in your example (https://bitbucket.org/gtborg/gtsam/src/c8b59b28855822c4601723bc8933cc046c07b89f/gtsam_unstable/slam/expressions.h?at=develop#cl-36) transform_to isn't an expression. The underlying ExpressionNode<Point3> stores a boost::function and there is no way to serialize that.

    This is where you would need to either implement custom ExpressionNode<T> with a serialize function, or just abstract the "function and Jacobians" in a serializable form.

    Right?

  6. Frank Dellaert

    No idea how to do this. Feel free to add to roadmap if you think it is important, it is definitely not on my (personal) priority list :-)

  7. Frank Dellaert

    Correct. But it could just as well be implemented by deriving from Expression and overriding serialize, no?. The idea is to create a dummy serialize in the base that will throw an exception if ever called.

  8. Paul Furgale reporter

    Understood. I'm still pretty strapped for time this week. I'll check with Mike when he gets in today.

  9. Log in to comment