-
Notifications
You must be signed in to change notification settings - Fork 300
Serialization using cereal #1704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hi, I've run clang-format and found that the code needs formatting. To use the commit you can do
|
symengine/serialize-cereal.h
Outdated
|
||
#define SYMENGINE_ENUM(type, Class) \ | ||
template <class Archive> \ | ||
inline void save_basic(Archive &ar, const Class &b) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use save_basic(Archive &ar, const OneArgFunction &b)
and get rid of defining these multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, of course, will fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this really reduced the number of save_basic implementations. For load_basic
I haven't yet come up with anything as elegant. I have the gut feeling it should be possible to do something leaner, any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
load_basic(Archive &ar, RCP<const OneArgFunction> &b)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OneArgFunction is abstract, so I don't think that's possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean I can dispatch on it, but after that I'm at loss:
template <class Archive>
RCP<const Basic> load_basic(Archive &ar, RCP<const OneArgFunction> &)
{
RCP<const Basic> arg;
ar(arg);
return basic_rcp_from_type_code_and_args(type_code, arg);
}
I guess I could change the signature of all load_basic
dispatch functions to take type_code
as an arguemnt, but then we still need the hypothetical basic_rcp_from_type_code_and_args
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See f7ada37
OK, I'm done for tonight (GMT+1 in Stockholm). If you get the chance to take a look: let me know what you think so far ☺. |
symengine/serialize-cereal.h
Outdated
template <class Archive, typename T> | ||
RCP<const Basic> load_basic(Archive &ar, RCP<const T> &b) | ||
{ | ||
const auto t_code = b->get_type_code(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b
is a dummy to allow writing code with inheritance. Don't use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but isn't it guaranteed that it inherits from Basic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the pointer inside might be NULL, so you can't call methods on it.
symengine/basic.cpp
Outdated
@@ -24,6 +43,20 @@ std::string Basic::__str__() const | |||
return str(*this); | |||
} | |||
|
|||
std::string Basic::dumps() const { | |||
std::ostringstream oss; | |||
cereal::BinaryOutputArchive{oss}(this->rcp_from_this()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is BinaryOutputArchive
portable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, no it wasn't: endianness is handled by PortableBinaryOutputArchive. I just changed this.
As for TypeIDs not being stable across versions of symengine: Cereal supports versioned serialization. We could write one new migrator for each new version of SymEngine, translating TypeIDs from version x to version x + 1. No performance impact for users keeping their serialized data up to date, and probably an acceptable cost for users using old data? |
Ah, nice, |
Yes, it is SFINAE |
Thanks, I got rid of those helpers I introduced before your SFINAE design. So debugging SFINAE is a bit of a pain right? I'm trying to support URatPoly but it's not picking up my save_basic overload:
Excerpt from test_lambda_doubleEvaluate functions ------------------------------------------------------------------------------- ../symengine/tests/eval/test_lambda_double.cpp:187 ............................................................................... I guess some one or several of my overloads for the building blocks here ( |
Don't know how to debug the general case. In this case you probably need |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work!
One question: What would happen if attempting to serialize an object that isn't (yet) supported?
symengine/serialize-cereal.h
Outdated
@@ -0,0 +1,696 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is non-standard. Use include guards instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious: can you name a compiler which can compile symengine, but doesn't support #pragma once
? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen the #pragma once
used lately in C++. So far I always suggested to just use the old fashion include guards.
I am not against using #pragma once
, it is definitely simpler. However I want to make sure we do not break the compilation.
@bjodah can you summarize the support in compilers for #pragma once
? And why is it not standard?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. The only compiler I've seen is Oracle Development Studio which we have partial support for. #1646
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why it's not supported by the standard (the standard doesn't say much about the preprocessor from what I've seen). My question was genuine: I was curious about the existence of any compilers which lacks support for it (and I've seen multiple recommendations to prefer the pragma approach). But now we know: Oracle doesn't support it then. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to support Oracle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a big deal to keep using include guards instead of pragma once
. I think we are using Oracle for R wrappers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the guards then.
A |
Do we want to add a
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff! I only spotted two potential minor issues.
TODO:
serialize.h
->serialize-cereal.h
loads
,dumps
methods tobasic.h
and implement it usingcereal
inbasic.cpp
Use something else than typeid. They are not stable across versions.