I am trying to use boost::mpi::broadcast to send a derived class to all nodes via a base class pointer. To do this, I am using the boost::serialization library to serialize my classes. My code, however, does not compile and I get the errors "class boost::mpi::packed_skeleton_iarchive’ has no member named ‘append’" and "class boost::mpi::packed_skeleton_iarchive’ has no member named ‘reset’."
Here is the rough source code for the program:
// Base.hpp
#include <boost/serialization/serialization.hpp>
class Base
{
public:
Base() {}
virtual ~Base() {}
virtual void foo() = 0;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& /*ar*/, const unsigned int /*version*/ ) {}
}
// Derived.hpp
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include "Base.hpp"
class Derived : public Base
{
public:
Derived( int param );
virtual ~Derived();
void foo();
private:
int param_;
std::vector< boost::shared_ptr > bar_;
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& ar, const unsigned int /*version*/ )
{
ar & param_;
ar & bar_;
ar & boost::serialization::base_object< Base >( *this );
}
}
namespace boost
{
namespace serialization
{
template<class Archive>
void load_construct_data( Archive& /*ar*/, Derived* d,
const unsigned int /*v*/ )
{
::new(d) Derived( 0 );
}
}
}
BOOST_CLASS_EXPORT_KEY( Derived )
// Derived.cpp
#include "Derived.hpp"
Derived::Derived( int param ) : param_( param ) {}
Derived::~Derived(){}
Derived::foo()
{
// some stuff
}
BOOST_CLASS_EXPORT_IMPLEMENT( Derived )
// Main.cpp
#include <boost/mpi.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/shared_ptr.hpp>
#include "Derived.hpp"
int main( int argc, char* argv[] )
{
boost::shared_ptr< Base > sp;
if ( world.rank() == 0 )
{
sp = boost::shared_ptr< Base >( new Derived( 5 ) );
boost::mpi::broadcast( world, sp, 0 );
// produce some stuff
} else
{
while ( 1 )
{
// consume some stuff
}
}
return 0;
}
BOOST_SERIALIZATION_ASSUME_ABSTRACT( Base )
I found only one Google Groups discussion about this problem but no solution so far https://groups.google.com/forum/#!msg/boost-developers-archive/Ee9_ilEDO7s/cJTy-8v5lEcJ. How can I get this to compile? I am using openmpi 1.2.8-17.4, gcc 4.5.1 and boost 1.54.
I was thankfully able to answer my own question (I think.) Boost doesn't handle through-base-pointer serialization properly when combined with boost::mpi::packed_skeleton_iarchive. The solution is then to use a different kind of archive, e.g. text_iarchive/text_oarchive, instead.
For example, to broadcast:
And to receive: