Hello,
I've just started to try using Boost.MPI, but I'm facing problems with
user-defined class serialization. Maybe I'm just missing something.
Basically, I have a pure virtual class "task" with the method execute
and I want to send classes that implement this interface through MPI.
For this to work, I have to register derived class for serialization.
Unfortunately, this causes compilation error under MSVC9.0.
Here is my code :
#include <iostream>
#include <exception>
#include
#include
#include
class task {
public:
virtual void execute() = 0;
};
class dtask : public task {
public:
dtask() {}
dtask(std::string text) : text(text) {}
virtual void execute() {
std::cout << text << std::endl;
}
private:
std::string text;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & text;
}
};
BOOST_CLASS_EXPORT(dtask)
int main(int argc, char* argv[])
{
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world;
try {
if (world.rank() == 0) {
task * t = new dtask("Blah");
world.send(1, 0, t);
} else if (world.rank() == 1) {
task * t;
world.recv(0, 0, t);
t->execute();
}
} catch (std::exception &e) {
std::cout << "Error : " << e.what() << std::endl;
}
return 0;
}
And the compilation error :
1>Compiling...
1>data_testbed.cpp
1>d:\grooviz\libs\boost_1_38\boost\mpi\datatype.hpp(184) : error C2664:
'boost::mpl::assertion_failed' : cannot convert parameter 1 from
'boost::mpl::failed ************boost::mpi::is_mpi_datatype<T>::*
***********' to 'boost::mpl::assert<false>::type'
1> with
1> [
1>
T=std::basic_string
1> ]
1> No constructor could take the source type, or constructor
overload resolution was ambiguous
1>
d:\grooviz\libs\boost_1_38\boost\mpi\detail\mpi_datatype_primitive.hpp(96)
: see reference to function template instantiation 'MPI_Datatype
boost::mpi::get_mpi_datatype<T>(const T &)' being compiled
1> with
1> [
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(95) :
see reference to function template instantiation 'void
boost::mpi::detail::mpi_datatype_primitive::save<T>(const T &)' being
compiled
1> with
1> [
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(212) :
see reference to function template instantiation 'void
boost::archive::save_access::save_primitive(Archive &,const T
&)' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(211) :
while compiling class template member function 'void
boost::archive::detail::save_non_pointer_type::save_primitive::invoke(Archive
&,const T &)'
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(294) :
see reference to class template instantiation
'boost::archive::detail::save_non_pointer_type::save_primitive'
being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(282) :
while compiling class template member function 'void
boost::archive::detail::save_non_pointer_type::invoke(Archive
&,const T &)'
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(506) :
see reference to class template instantiation
'boost::archive::detail::save_non_pointer_type' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\mpi\detail\ignore_skeleton_oarchive.hpp(46)
: see reference to function template instantiation 'void
boost::archive::save(Archive &,const T &)' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\interface_oarchive.hpp(64)
: see reference to function template instantiation 'void
boost::mpi::detail::ignore_skeleton_oarchive<Archive>::save_override<const
T>(const T &,int)' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\interface_oarchive.hpp(72)
: see reference to function template instantiation 'Archive
&boost::archive::detail::interface_oarchive<Archive>::operator <<<const
T>(T &)' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1> d:\grooviz\sandbox\test\data_testbed\data_testbed.cpp(30) :
see reference to function template instantiation 'Archive
&boost::archive::detail::interface_oarchive<Archive>::operator
&std::string(T &)' being compiled
1> with
1> [
1> Archive=boost::mpi::detail::content_oarchive,
1> T=std::string
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\access.hpp(109)
: see reference to function template instantiation 'void
dtask::serialize<Archive>(Archive &,const unsigned int)' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\serialization\serialization.hpp(74) :
see reference to function template instantiation 'void
boost::serialization::access::serialize(Archive &,T &,const
unsigned int)' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\serialization\serialization.hpp(133) :
see reference to function template instantiation 'void
boost::serialization::serialize(Archive &,T &,const unsigned
int)' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(148) :
see reference to function template instantiation 'void
boost::serialization::serialize_adl(Archive &,T &,const
unsigned int)' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(140) :
while compiling class template member function 'void
boost::archive::detail::oserializer::save_object_data(boost::archive::detail::basic_oarchive
&,const void *) const'
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(170) :
see reference to class template instantiation
'boost::archive::detail::oserializer' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\oserializer.hpp(167) :
while compiling class template member function 'const
boost::archive::detail::basic_oserializer
&boost::archive::detail::pointer_oserializer::get_basic_serializer(void)
const'
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(75)
: see reference to class template instantiation
'boost::archive::detail::pointer_oserializer' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> T=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(72)
: while compiling class template member function 'const
boost::archive::detail::basic_pointer_oserializer
&boost::archive::detail::export_impl::enable_save(boost::mpl::true_)'
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> Serializable=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(106)
: see reference to class template instantiation
'boost::archive::detail::export_impl' being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> Serializable=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(105)
: while compiling class template member function 'void
boost::archive::detail::ptr_serialization_support::instantiate(void)'
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> Serializable=dtask
1> ]
1>
d:\grooviz\libs\boost_1_38\boost\archive\detail\register_archive.hpp(27)
: see reference to class template instantiation
'boost::archive::detail::ptr_serialization_support'
being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> Serializable=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(128)
: see reference to class template instantiation
'boost::archive::detail::_ptr_serialization_support'
being compiled
1> with
1> [
1>
Archive=boost::mpi::detail::ignore_skeleton_oarchiveboost::mpi::detail::content_oarchive,
1> Serializable=dtask
1> ]
1> d:\grooviz\libs\boost_1_38\boost\serialization\export.hpp(124)
: while compiling class template member function 'const
boost::archive::detail::guid_initializer<T>
&boost::archive::detail::guid_initializer<T>::export_guid(const char
*,boost::mpl::false_)'
1> with
1> [
1> T=dtask
1> ]
1> d:\grooviz\sandbox\test\data_testbed\data_testbed.cpp(36) :
see reference to class template instantiation
'boost::archive::detail::guid_initializer<T>' being compiled
1> with
1> [
1> T=dtask
1> ]
Note that if I remove the BOOST_CLASS_EXPORT(dtask), the program
compiles fine but I get "unregistered class" exception at runtime.
Note also that if I use dtask pointer instead of task with send and
recv, the program runs fine.
Additionaly, if I use primitive type like "int" instead of std::string
in my derived class, the compilation goes fine with the export statement.
It seems to me that at some point the compiler tries to get the MPI
datatype of std::string even if it shouldn't since it's not a primitive
type.
What am I missing here ?
Thank you in advance,
Ariel Ouziel