2
0
mirror of https://github.com/boostorg/mpi.git synced 2026-02-25 04:22:17 +00:00

Moved Serialization and MPI fixes and updates from trunk to release branch

[SVN r46743]
This commit is contained in:
Matthias Troyer
2008-06-26 19:25:44 +00:00
parent 4bd63be33a
commit 97e9366a2f
39 changed files with 985 additions and 206 deletions

View File

@@ -1141,7 +1141,7 @@ communicator::array_send_impl(int dest, int tag, const T* values, int n,
{
BOOST_MPI_CHECK_RESULT(MPI_Send,
(const_cast<T*>(values), n,
get_mpi_datatype<T>(*values),
get_mpi_datatype<T>(*values),
dest, tag, MPI_Comm(*this)));
}
@@ -1174,7 +1174,7 @@ status communicator::recv_impl(int source, int tag, T& value, mpl::true_) const
BOOST_MPI_CHECK_RESULT(MPI_Recv,
(const_cast<T*>(&value), 1,
get_mpi_datatype<T>(value),
get_mpi_datatype<T>(value),
source, tag, MPI_Comm(*this), &stat.m_status));
return stat;
}
@@ -1209,7 +1209,7 @@ communicator::array_recv_impl(int source, int tag, T* values, int n,
status stat;
BOOST_MPI_CHECK_RESULT(MPI_Recv,
(const_cast<T*>(values), n,
get_mpi_datatype<T>(*values),
get_mpi_datatype<T>(*values),
source, tag, MPI_Comm(*this), &stat.m_status));
return stat;
}
@@ -1256,7 +1256,7 @@ communicator::isend_impl(int dest, int tag, const T& value, mpl::true_) const
request req;
BOOST_MPI_CHECK_RESULT(MPI_Isend,
(const_cast<T*>(&value), 1,
get_mpi_datatype<T>(value),
get_mpi_datatype<T>(value),
dest, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;
}
@@ -1291,7 +1291,7 @@ communicator::array_isend_impl(int dest, int tag, const T* values, int n,
request req;
BOOST_MPI_CHECK_RESULT(MPI_Isend,
(const_cast<T*>(values), n,
get_mpi_datatype<T>(*values),
get_mpi_datatype<T>(*values),
dest, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;
}
@@ -1531,7 +1531,7 @@ communicator::irecv_impl(int source, int tag, T& value, mpl::true_) const
request req;
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
(const_cast<T*>(&value), 1,
get_mpi_datatype<T>(value),
get_mpi_datatype<T>(value),
source, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;
}
@@ -1548,7 +1548,7 @@ communicator::irecv_impl(int source, int tag, T& value, mpl::false_) const
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
(&data->count, 1,
get_mpi_datatype<std::size_t>(data->count),
get_mpi_datatype<std::size_t>(data->count),
source, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;
@@ -1569,7 +1569,7 @@ communicator::array_irecv_impl(int source, int tag, T* values, int n,
request req;
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
(const_cast<T*>(values), n,
get_mpi_datatype<T>(*values),
get_mpi_datatype<T>(*values),
source, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;
}
@@ -1587,7 +1587,7 @@ communicator::array_irecv_impl(int source, int tag, T* values, int n,
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
(&data->count, 1,
get_mpi_datatype<std::size_t>(data->count),
get_mpi_datatype<std::size_t>(data->count),
source, tag, MPI_Comm(*this), &req.m_requests[0]));
return req;

View File

@@ -20,6 +20,11 @@
#include <mpi.h>
#include <boost/config.hpp>
/** @brief Define this macro to avoid expensice MPI_Pack/Unpack calls on
* homogeneous machines.
*/
//#define BOOST_MPI_HOMOGENEOUS
// If this is an MPI-2 implementation, define configuration macros for
// the features we are interested in.
#if defined(MPI_VERSION) && MPI_VERSION == 2

View File

@@ -23,6 +23,7 @@
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpi/detail/mpi_datatype_cache.hpp>
#include <boost/mpl/assert.hpp>
#include <utility> // for std::pair
@@ -198,6 +199,9 @@ template<> \
: boost::mpl::bool_<true> \
{}
/// INTERNAL ONLY
BOOST_MPI_DATATYPE(packed, MPI_PACKED, builtin);
/// INTERNAL ONLY
BOOST_MPI_DATATYPE(char, MPI_CHAR, builtin);
@@ -252,6 +256,13 @@ BOOST_MPI_DATATYPE(std::pair<BOOST_MPI_LIST2(short, int>), MPI_SHORT_INT,
BOOST_MPI_DATATYPE(std::pair<BOOST_MPI_LIST2(int, int>), MPI_2INT, builtin);
#undef BOOST_MPI_LIST2
/// specialization of is_mpi_datatype for pairs
template <class T, class U>
struct is_mpi_datatype<std::pair<T,U> >
: public mpl::and_<is_mpi_datatype<T>,is_mpi_datatype<U> >
{
};
// Define wchar_t specialization of is_mpi_datatype, if possible.
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && \
(defined(MPI_WCHAR) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
@@ -314,11 +325,16 @@ struct is_mpi_datatype<bool>
: boost::mpl::bool_<true>
{};
/// INTERNAL ONLY
template<typename T, typename U>
struct is_mpi_datatype<std::pair<T, U> >
: mpl::and_<is_mpi_datatype<T>, is_mpi_datatype<U> > { };
} } // end namespace boost::mpi
// define a macro to make explicit designation of this more transparent
#define BOOST_IS_MPI_DATATYPE(T) \
namespace boost { \
namespace mpi { \
template<> \
struct is_mpi_datatype< T > : mpl::true_ {}; \
}} \
/**/
#endif // BOOST_MPI_MPI_DATATYPE_HPP

View File

@@ -27,6 +27,8 @@ template<typename T> struct is_mpi_byte_datatype;
template<typename T> struct is_mpi_datatype;
template<typename T> MPI_Datatype get_mpi_datatype(const T& x = T());
/// a dummy data type giving MPI_PACKED as its MPI_Datatype
struct packed {};
} } // end namespace boost::mpi
#endif // BOOST_MPI_MPI_DATATYPE_FWD_HPP

View File

@@ -0,0 +1,122 @@
// (C) Copyright 2005-2007 Matthias Troyer
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Matthias Troyer
#ifndef BOOST_MPI_BINARY_BUFFER_IPRIMITIVE_HPP
#define BOOST_MPI_BINARY_BUFFER_IPRIMITIVE_HPP
#include <mpi.h>
#include <iostream>
#include <cstddef> // size_t
#include <boost/config.hpp>
#include <boost/mpi/exception.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <vector>
#include <boost/mpi/allocator.hpp>
#include <cstring> // for memcpy
namespace boost { namespace mpi {
/// deserialization using MPI_Unpack
class BOOST_MPI_DECL binary_buffer_iprimitive
{
public:
/// the type of the buffer from which the data is unpacked upon deserialization
typedef std::vector<char, allocator<char> > buffer_type;
binary_buffer_iprimitive(buffer_type & b, MPI_Comm const &, int position = 0)
: buffer_(b),
position(position)
{
}
void* address ()
{
return &buffer_.front();
}
void const* address () const
{
return &buffer_.front();
}
const std::size_t& size() const
{
return size_ = buffer_.size();
}
void resize(std::size_t s)
{
buffer_.resize(s);
}
void load_binary(void *address, std::size_t count)
{
load_impl(address,count);
}
// fast saving of arrays of fundamental types
template<class T>
void load_array(serialization::array<T> const& x, unsigned int /* file_version */)
{
BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>));
if (x.count())
load_impl(x.address(), sizeof(T)*x.count());
}
typedef serialization::is_bitwise_serializable<mpl::_1> use_array_optimization;
template<class T>
void load(serialization::array<T> const& x)
{
load_array(x,0u);
}
// default saving of primitives.
template<class T>
void load( T & t)
{
BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>));
load_impl(&t, sizeof(T));
}
void load( std::string & s)
{
unsigned int l;
load(l);
// borland de-allocator fixup
#if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
if(NULL != s.data())
#endif
s.resize(l);
// note breaking a rule here - could be a problem on some platform
load_impl(const_cast<char *>(s.data()),l);
}
private:
void load_impl(void * p, int l)
{
if (position+l > static_cast<int>(buffer_.size()))
std::cerr << position << " " << l << " " << buffer_.size() << "\n";
assert(position+l<=static_cast<int>(buffer_.size()));
std::memcpy(p,&buffer_[position],l);
position += l;
}
buffer_type & buffer_;
mutable std::size_t size_;
int position;
};
} } // end namespace boost::mpi
#endif // BOOST_MPI_PACKED_IPRIMITIVE_HPP

View File

@@ -0,0 +1,103 @@
// (C) Copyright 2005-2007 Matthias Troyer
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Matthias Troyer
#ifndef BOOST_MPI_BINARY_BUFFER_OPRIMITIVE_HPP
#define BOOST_MPI_BINARY_BUFFER_OPRIMITIVE_HPP
#include <mpi.h>
#include <iostream>
#include <cstddef> // size_t
#include <boost/config.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <vector>
#include <boost/mpi/allocator.hpp>
#include <boost/mpl/always.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost { namespace mpi {
/// serialization using binary copy into a buffer
class BOOST_MPI_DECL binary_buffer_oprimitive
{
public:
/// the type of the buffer into which the data is packed upon serialization
typedef std::vector<char, allocator<char> > buffer_type;
binary_buffer_oprimitive(buffer_type & b, MPI_Comm const &)
: buffer_(b)
{
}
void const * address() const
{
return &buffer_.front();
}
const std::size_t& size() const
{
return size_ = buffer_.size();
}
void save_binary(void const *address, std::size_t count)
{
save_impl(address,count);
}
// fast saving of arrays
template<class T>
void save_array(serialization::array<T> const& x, unsigned int /* file_version */)
{
BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>));
if (x.count())
save_impl(x.address(), x.count()*sizeof(T));
}
template<class T>
void save(serialization::array<T> const& x)
{
save_array(x,0u);
}
typedef serialization::is_bitwise_serializable<mpl::_1> use_array_optimization;
// default saving of primitives.
template<class T>
void save(const T & t)
{
BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>));
save_impl(&t, sizeof(T));
}
void save(const std::string &s)
{
unsigned int l = static_cast<unsigned int>(s.size());
save(l);
save_impl(s.data(),s.size());
}
private:
void save_impl(void const * p, int l)
{
char const* ptr = reinterpret_cast<char const*>(p);
buffer_.insert(buffer_.end(),ptr,ptr+l);
}
buffer_type& buffer_;
mutable std::size_t size_;
};
} } // end namespace boost::mpi
#endif // BOOST_MPI_BINARY_BUFFER_OPRIMITIVE_HPP

View File

@@ -61,5 +61,5 @@ const content get_content(const T& x)
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::content_oarchive)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::ignore_skeleton_oarchive<boost::mpi::detail::content_oarchive>)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::detail::content_oarchive)
#endif // BOOST_MPI_DETAIL_CONTENT_OARCHIVE_HPP

View File

@@ -28,26 +28,26 @@ public:
/// the type of the archive to which the loading of primitive types will be forwarded
typedef ImplementationArchive implementation_archive_type;
/// the constructor takes a reference to the implementation archive used for loading primitve types
/// the constructor takes a reference to the implementation archive used for loading primitve types
forward_iprimitive(implementation_archive_type& ar)
: implementation_archive(ar)
: implementation_archive(ar)
{}
/// binary loading is forwarded to the implementation archive
/// binary loading is forwarded to the implementation archive
void load_binary(void * address, std::size_t count )
{
implementation_archive.load_binary(address,count);
}
/// loading of arrays is forwarded to the implementation archive
{
implementation_archive.load_binary(address,count);
}
/// loading of arrays is forwarded to the implementation archive
template<class T>
void load_array(serialization::array<T> & x, unsigned int file_version )
{
implementation_archive.load_array(x,file_version);
implementation_archive.load_array(x,file_version);
}
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
friend class archive::load_access;
@@ -60,9 +60,9 @@ public:
template<class T>
void load(T & t)
{
implementation_archive >> t;
implementation_archive >> t;
}
private:
implementation_archive_type& implementation_archive;
};

View File

@@ -29,26 +29,26 @@ public:
/// the type of the archive to which the saving of primitive types will be forwarded
typedef ImplementationArchive implementation_archive_type;
/// the constructor takes a reference to the implementation archive used for saving primitve types
/// the constructor takes a reference to the implementation archive used for saving primitve types
forward_oprimitive(implementation_archive_type& ar)
: implementation_archive(ar)
: implementation_archive(ar)
{}
/// binary saving is forwarded to the implementation archive
/// binary saving is forwarded to the implementation archive
void save_binary(const void * address, std::size_t count)
{
implementation_archive.save_binary(address,count);
}
/// saving of arrays is forwarded to the implementation archive
{
implementation_archive.save_binary(address,count);
}
/// saving of arrays is forwarded to the implementation archive
template<class T>
void save_array(serialization::array<T> const& x, unsigned int file_version )
{
implementation_archive.save_array(x,file_version);
implementation_archive.save_array(x,file_version);
}
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
friend class archive::save_access;
@@ -61,9 +61,9 @@ public:
template<class T>
void save(const T & t)
{
implementation_archive << t;
implementation_archive << t;
}
private:
implementation_archive_type& implementation_archive;
};

View File

@@ -14,26 +14,25 @@
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/iserializer.hpp>
#include <boost/archive/detail/interface_iarchive.hpp>
#include <boost/archive/array/iarchive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/iarchive.hpp>
namespace boost { namespace mpi { namespace detail {
template<class Archive, class ImplementationArchive>
class forward_skeleton_iarchive
: public archive::array::iarchive<Archive>
: public archive::detail::common_iarchive<Archive>
{
public:
typedef ImplementationArchive implementation_archive_type;
forward_skeleton_iarchive(implementation_archive_type& ar)
: archive::array::iarchive<Archive>(archive::no_header),
implementation_archive(ar)
{
}
: archive::detail::common_iarchive<Archive>(archive::no_header),
implementation_archive(ar)
{
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
@@ -50,12 +49,12 @@ protected:
{
archive::load(* this->This(), t);
}
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
void load_override(T & t , int) \
{ \
implementation_archive >> t; \
}
{ \
implementation_archive >> t; \
}
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_optional_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type)

View File

@@ -14,26 +14,25 @@
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/interface_oarchive.hpp>
#include <boost/archive/array/oarchive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/oarchive.hpp>
namespace boost { namespace mpi { namespace detail {
template<class Archive, class ImplementationArchive>
class forward_skeleton_oarchive
: public archive::array::oarchive<Archive>
: public archive::detail::common_oarchive<Archive>
{
public:
typedef ImplementationArchive implementation_archive_type;
forward_skeleton_oarchive(implementation_archive_type& ar)
: archive::array::oarchive<Archive>(archive::no_header),
implementation_archive(ar)
{
}
: archive::detail::common_oarchive<Archive>(archive::no_header),
implementation_archive(ar)
{
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
@@ -50,12 +49,12 @@ protected:
{
archive::save(* this->This(), t);
}
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
void save_override(T const & t , int) \
{ \
implementation_archive << t; \
}
{ \
implementation_archive << t; \
}
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_optional_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type)

View File

@@ -12,7 +12,7 @@
#include <boost/pfto.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/array/oarchive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/serialization/collection_size_type.hpp>
@@ -21,15 +21,14 @@ namespace boost { namespace mpi { namespace detail {
template<class Archive>
class ignore_skeleton_oarchive
: public archive::array::oarchive<Archive>
: public archive::detail::common_oarchive<Archive>
{
public:
ignore_skeleton_oarchive()
: archive::array::oarchive<Archive>(archive::no_header)
{
}
: archive::detail::common_oarchive<Archive>(archive::no_header)
{
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
@@ -46,10 +45,10 @@ protected:
{
archive::save(* this->This(), t);
}
#define BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(T) \
void save_override(T const & , int) \
{}
{}
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_optional_type)
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::version_type)

View File

@@ -69,12 +69,12 @@ public:
// check whether the type already exists
std::type_info const* t = &typeid(T);
MPI_Datatype datatype = get(t);
if (datatype == MPI_DATATYPE_NULL) {
MPI_Datatype datatype = get(t);
if (datatype == MPI_DATATYPE_NULL) {
// need to create a type
mpi_datatype_oarchive ar(x);
datatype = ar.get_mpi_datatype();
set(t, datatype);
datatype = ar.get_mpi_datatype();
set(t, datatype);
}
return datatype;

View File

@@ -43,5 +43,6 @@ public:
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::mpi_datatype_oarchive)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::ignore_skeleton_oarchive<boost::mpi::detail::mpi_datatype_oarchive>)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::detail::mpi_datatype_oarchive)
#endif // BOOST_MPI_DETAIL_MPI_DATATYPE_OARCHIVE_HPP

View File

@@ -65,20 +65,19 @@ public:
// fast saving of arrays of fundamental types
template<class T>
void load_array(serialization::array<T> & x, unsigned int /* file_version */)
void load_array(serialization::array<T> const& x, unsigned int /* file_version */)
{
if (x.count())
load_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
}
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
template<class T>
void load(serialization::array<T> const& x)
{
load_array(x,0u);
}
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
friend class archive::load_access;
protected:
#else
public:
#endif
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
// default saving of primitives.
template<class T>

View File

@@ -13,7 +13,6 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/mpi/detail/forward_skeleton_oarchive.hpp>
#include <boost/mpi/detail/ignore_oprimitive.hpp>
#include <boost/archive/array/oarchive.hpp>
namespace boost { namespace mpi {
@@ -25,9 +24,9 @@ class text_skeleton_oarchive
{
public:
text_skeleton_oarchive(std::ostream & s, unsigned int flags = 0)
: detail::forward_skeleton_oarchive<text_skeleton_oarchive,boost::archive::text_oarchive>(skeleton_archive_)
: detail::forward_skeleton_oarchive<text_skeleton_oarchive,boost::archive::text_oarchive>(skeleton_archive_)
, skeleton_archive_(s,flags)
{}
{}
private:
boost::archive::text_oarchive skeleton_archive_;

View File

@@ -23,10 +23,17 @@
#include <boost/archive/basic_binary_iarchive.hpp>
#include <boost/archive/shared_ptr_helper.hpp>
#include <boost/mpi/detail/packed_iprimitive.hpp>
#include <boost/mpi/detail/binary_buffer_iprimitive.hpp>
#include <boost/assert.hpp>
namespace boost { namespace mpi {
#ifdef BOOST_MPI_HOMOGENEOUS
typedef binary_buffer_iprimitive iprimitive;
#else
typedef packed_iprimitive iprimitive;
#endif
/** @brief An archive that packs binary data into an MPI buffer.
*
* The @c packed_iarchive class is an Archiver (as in the
@@ -36,7 +43,7 @@ namespace boost { namespace mpi {
* implementation to perform serialization.
*/
class BOOST_MPI_DECL packed_iarchive
: public packed_iprimitive
: public iprimitive
, public archive::basic_binary_iarchive<packed_iarchive>
, public archive::detail::shared_ptr_helper
{
@@ -59,7 +66,7 @@ public:
* deserialization will begin.
*/
packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0)
: packed_iprimitive(b,comm,position),
: iprimitive(b,comm,position),
archive::basic_binary_iarchive<packed_iarchive>(flags)
{}
@@ -70,16 +77,44 @@ public:
* @param comm The communicator over which this archive will be
* sent.
*
* @param s The size of the buffer to be received.
*
* @param flags Control the serialization of the data types. Refer
* to the Boost.Serialization documentation before changing the
* default flags.
*/
packed_iarchive
( MPI_Comm const & comm , unsigned int flags = boost::archive::no_header)
: packed_iprimitive(internal_buffer_,comm),
archive::basic_binary_iarchive<packed_iarchive>(flags)
( MPI_Comm const & comm , std::size_t s=0,
unsigned int flags = boost::archive::no_header)
: iprimitive(internal_buffer_,comm)
, archive::basic_binary_iarchive<packed_iarchive>(flags)
, internal_buffer_(s)
{}
// Load everything else in the usual way, forwarding on to the Base class
template<class T>
void load_override(T& x, int version, mpl::false_)
{
archive::basic_binary_iarchive<packed_iarchive>::load_override(x,version);
}
// Load it directly using the primnivites
template<class T>
void load_override(T& x, int version, mpl::true_)
{
iprimitive::load(x);
}
// Load all supported datatypes directly
template<class T>
void load_override(T& x, int version)
{
typedef typename mpl::apply1<use_array_optimization
, BOOST_DEDUCED_TYPENAME remove_const<T>::type
>::type use_optimized;
load_override(x, version, use_optimized());
}
private:
/// An internal buffer to be used when the user does not supply his
/// own buffer.
@@ -90,5 +125,6 @@ private:
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(boost::mpi::packed_iarchive)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_iarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_iarchive)
#endif // BOOST_MPI_PACKED_IARCHIVE_HPP

View File

@@ -22,9 +22,16 @@
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/basic_binary_oarchive.hpp>
#include <boost/mpi/detail/packed_oprimitive.hpp>
#include <boost/mpi/detail/binary_buffer_oprimitive.hpp>
namespace boost { namespace mpi {
#ifdef BOOST_MPI_HOMOGENEOUS
typedef binary_buffer_oprimitive oprimitive;
#else
typedef packed_oprimitive oprimitive;
#endif
/** @brief An archive that unpacks binary data from an MPI buffer.
*
* The @c packed_oarchive class is an Archiver (as in the
@@ -33,8 +40,9 @@ namespace boost { namespace mpi {
* type and will use the @c MPI_Unpack function of the underlying MPI
* implementation to perform deserialization.
*/
class BOOST_MPI_DECL packed_oarchive
: public packed_oprimitive,
: public oprimitive,
public archive::basic_binary_oarchive<packed_oarchive>
{
public:
@@ -53,7 +61,7 @@ public:
* default flags.
*/
packed_oarchive( MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header)
: packed_oprimitive(b,comm),
: oprimitive(b,comm),
archive::basic_binary_oarchive<packed_oarchive>(flags)
{}
@@ -69,10 +77,31 @@ public:
* default flags.
*/
packed_oarchive ( MPI_Comm const & comm, unsigned int flags = boost::archive::no_header)
: packed_oprimitive(internal_buffer_,comm),
: oprimitive(internal_buffer_,comm),
archive::basic_binary_oarchive<packed_oarchive>(flags)
{}
// Save everything else in the usual way, forwarding on to the Base class
template<class T>
void save_override(T const& x, int version, mpl::false_)
{
archive::basic_binary_oarchive<packed_oarchive>::save_override(x,version);
}
// Save it directly using the primnivites
template<class T>
void save_override(T const& x, int version, mpl::true_)
{
oprimitive::save(x);
}
// Save all supported datatypes directly
template<class T>
void save_override(T const& x, int version)
{
typedef typename mpl::apply1<use_array_optimization,T>::type use_optimized;
save_override(x, version, use_optimized());
}
private:
/// An internal buffer to be used when the user does not supply his
@@ -84,6 +113,8 @@ private:
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_oarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_oarchive)
#endif // BOOST_MPI_PACKED_OARCHIVE_HPP

View File

@@ -385,4 +385,7 @@ BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_skeleton_iarchive)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::type1)
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::type2)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_skeleton_oarchive)
BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_skeleton_iarchive)
#endif // BOOST_MPI_SKELETON_AND_CONTENT_HPP

View File

@@ -34,6 +34,8 @@ class BOOST_MPI_DECL status
{
public:
status() : m_count(-1) { }
status(MPI_Status const& s) : m_status(s), m_count(-1) {}
/**
* Retrieve the source of the message.