This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Problem in adding Boost Serialization support

Tags: None
(comma "," separated)
hijokpayne
Registered Member
Posts
25
Karma
0
I need have Boost serialization for my Eigen types, so I made the following DenseBase plugin:

Code: Select all
///@file EigenDenseBaseAddons.h
#ifndef EIGEN_DENSE_BASE_ADDONS_H_
#define EIGEN_DENSE_BASE_ADDONS_H_

friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const {
  size_t rows = derived().rows(), cols = derived().cols();
  ar & rows;
  ar & cols;
  ar & boost::serialization::make_array(derived().data(), derived().size());
}

template<class Archive>
void load(Archive & ar, const unsigned int version) {
  size_t rows, cols;
  ar & rows;
  ar & cols;
  if (rows * cols != static_cast<size_t>(derived().size()))
    derived().resize(rows, cols);
  ar & boost::serialization::make_array(derived().data(), derived().size());
}

template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {
  boost::serialization::split_member(ar, *this, file_version);
}
#endif // EIGEN_DENSE_BASE_ADDONS_H_


This works fine for many of useful cases like

Code: Select all
/// Boost Serialization Helper
template <typename T>
bool serialize(const T& data, const std::string& filename) {
  std::ofstream ofs(filename.c_str(), std::ios::out);
  if (!ofs.is_open())
    return false;
  {
    boost::archive::text_oarchive oa(ofs); // or binary archive or XML
    oa << data;
  }
  ofs.close();
  return true;
}

template <typename T>
bool deSerialize(T& data, const std::string& filename) {
  std::ifstream ifs(filename.c_str(), std::ios::in);
  if (!ifs.is_open())
    return false;
  {
    boost::archive::text_iarchive ia(ifs); // or binary archive or XML
    ia >> data;
  }
  ifs.close();
  return true;
}

/// Working cases

VectorXf vec(100);
vec.setRandom();
serialize(vec.tail<5>(), "vec.txt");

MatrixXf vec_in;
deSerialize(vec_in, "vec.txt");
assert(vec_in.isApprox(vec.tail<5>()));

serialize(Vector2f(0.5f,0.5f), "a.tmp");
Vector2f a2f;
deSerialize(a2f, "a.tmp");
assert(a2f.isApprox(Vector2f(0.5f,0.5f)));
VectorXf axf;
deSerialize(axf, "a.tmp");
assert(aXf.isApprox(Vector2f(0.5f,0.5f)));

boost::shared_ptr<Vector4f> b = boost::make_shared<Vector4f>(Vector4f::Random());
serialize(b, "b.tmp");
boost::shared_ptr<Vector4f> b_in;
deSerialize(b_in, "b.tmp");
BOOST_CHECK_EQUAL(*b, *b_in);

EigenAligned<Vector2d>::std_vector vector1, vector2;
  for (size_t i = 0; i< 100; ++i) {
    vector1.push_back(Vector2d::Random());
 }
serializeBinary(vector1, "vector.bin");
deSerializeBinary(vector2, "vector.bin");
for (size_t i =0; i < vector1.size(); ++i)
   BOOST_CHECK_EQUAL(vector1[i], vector2[i]);




However it fails for the use cases like following :
Code: Select all
Matrix4f m(Matrix4f::Random());
serialize(m.topRows<2>(), "m.txt");
deSerialize(m_in, "m.txt");


In above case m and m_in will not same and m_in will store the first two columns instead.

So my question is how do I go about correcting this behavior?
hijokpayne
Registered Member
Posts
25
Karma
0
I made some modications to my plugin code and it now works for submatrices.

Code: Select all
#ifndef EIGEN_DENSE_BASE_ADDONS_H_
#define EIGEN_DENSE_BASE_ADDONS_H_

friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const {
  derived().eval();
  const Index rows = derived().rows(), cols = derived().cols();
  ar & rows;
  ar & cols;
  for (Index j = 0; j < cols; ++j )
    for (Index i = 0; i < rows; ++i )
      ar & derived().coeff(i, j);
}

template<class Archive>
void load(Archive & ar, const unsigned int version) {
  Index rows, cols;
  ar & rows;
  ar & cols;
  if (rows != derived().rows() || cols != derived().cols() )
    derived().resize(rows, cols);
  ar & boost::serialization::make_array(derived().data(), derived().size());
}

template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {
  boost::serialization::split_member(ar, *this, file_version);
}
#endif // EIGEN_DENSE_BASE_ADDONS_H_


But still let me know if you see any obvious problem in doing it this way or if you have suggestion on improving it.


Bookmarks



Who is online

Registered users: Baidu [Spider], Bing [Bot], Google [Bot], rblackwell