Based on the excellent answers here, I tried to build a method to serialize Eigen tensors.
Based on the cereal package I tried the following:
namespace cereal
{
template <class Archive, class Derived> inline
typename std::enable_if<traits::is_output_serializable<BinaryData<typename Derived::Scalar>, Archive>::value, void>::type
save(Archive & ar, Eigen::PlainObjectBase<Derived> const & m){
const auto& d = m.dimensions();
const int dims = d.size;
for(int i=0;i<dims;i++)
{
ar(d[i]);
}
ar(binary_data(m.data(),m.size()*sizeof(typename Derived::Scalar)));
}
template <class Archive, class Derived> inline
typename std::enable_if<traits::is_input_serializable<BinaryData<typename Derived::Scalar>, Archive>::value, void>::type
load(Archive & ar, Eigen::PlainObjectBase<Derived> const & m){
const auto& d = m.dimensions();
const int dims = d.size;
for(int i=0;i<dims;i++)
{
ar(d[i]);
}
ar(binary_data(m.data(),static_cast<std::size_t>(m.size()*sizeof(typename Derived::Scalar))));
}
}
Together with the save/load pair:
Eigen::Tensor<double, 3> tensor3dmaus = {4, 3, 2};
tensor3dmaus.setValues( {{{1, 2}, {3, 4}, {5, 6}},
{{7, 8}, {9, 10}, {11, 12}},
{{13, 14}, {15, 16}, {17, 18}},
{{19, 20}, {21, 22}, {23, 24}}} );
{
std::ofstream out("eigen.cereal", std::ios::binary);
cereal::BinaryOutputArchive archive_o(out);
archive_o(tensor3dmaus);
}
std::cout << "test:" << std::endl << tensor3dmaus << std::endl;
Tensor<double,3> test_loaded;
{
std::ifstream in("eigen.cereal", std::ios::binary);
cereal::BinaryInputArchive archive_i(in);
archive_i(test_loaded);
}
std::cout << "test loaded:" << std::endl << test_loaded << std::endl;
However, when compiling, I obtain the following error message:
Types must either have a serialize function, load/save pair, or
load_minimal/save_minimal pair (you may not mix these).
Serialize functions generally have the following signature:
template<class Archive>
void serialize(Archive & ar)
{
ar( member1, member2, member3 );
}
Can someone help me get this right? I tried to use Eigen's tensor base class instead of the PlainObject base with access level 3, which did not work unfortunately.
Any hints on how to adapt the code to function with tensors would be highly appreciated, thank you!