Added boost header
This commit is contained in:
392
test/external/boost/mpi/skeleton_and_content.hpp
vendored
Normal file
392
test/external/boost/mpi/skeleton_and_content.hpp
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
// (C) Copyright 2005 Matthias Troyer
|
||||
// (C) Copyright 2006 Douglas Gregor <doug.gregor -at gmail.com>
|
||||
|
||||
// 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
|
||||
// Douglas Gregor
|
||||
|
||||
/** @file skeleton_and_content.hpp
|
||||
*
|
||||
* This header provides facilities that allow the structure of data
|
||||
* types (called the "skeleton") to be transmitted and received
|
||||
* separately from the content stored in those data types. These
|
||||
* facilities are useful when the data in a stable data structure
|
||||
* (e.g., a mesh or a graph) will need to be transmitted
|
||||
* repeatedly. In this case, transmitting the skeleton only once
|
||||
* saves both communication effort (it need not be sent again) and
|
||||
* local computation (serialization need only be performed once for
|
||||
* the content).
|
||||
*/
|
||||
#ifndef BOOST_MPI_SKELETON_AND_CONTENT_HPP
|
||||
#define BOOST_MPI_SKELETON_AND_CONTENT_HPP
|
||||
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/mpi/packed_iarchive.hpp>
|
||||
#include <boost/mpi/packed_oarchive.hpp>
|
||||
#include <boost/mpi/detail/forward_skeleton_iarchive.hpp>
|
||||
#include <boost/mpi/detail/forward_skeleton_oarchive.hpp>
|
||||
#include <boost/mpi/detail/ignore_iprimitive.hpp>
|
||||
#include <boost/mpi/detail/ignore_oprimitive.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
/**
|
||||
* @brief A proxy that requests that the skeleton of an object be
|
||||
* transmitted.
|
||||
*
|
||||
* The @c skeleton_proxy is a lightweight proxy object used to
|
||||
* indicate that the skeleton of an object, not the object itself,
|
||||
* should be transmitted. It can be used with the @c send and @c recv
|
||||
* operations of communicators or the @c broadcast collective. When a
|
||||
* @c skeleton_proxy is sent, Boost.MPI generates a description
|
||||
* containing the structure of the stored object. When that skeleton
|
||||
* is received, the receiving object is reshaped to match the
|
||||
* structure. Once the skeleton of an object as been transmitted, its
|
||||
* @c content can be transmitted separately (often several times)
|
||||
* without changing the structure of the object.
|
||||
*/
|
||||
template <class T>
|
||||
struct BOOST_MPI_DECL skeleton_proxy
|
||||
{
|
||||
/**
|
||||
* Constructs a @c skeleton_proxy that references object @p x.
|
||||
*
|
||||
* @param x the object whose structure will be transmitted or
|
||||
* altered.
|
||||
*/
|
||||
skeleton_proxy(T& x)
|
||||
: object(x)
|
||||
{}
|
||||
|
||||
T& object;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a skeleton proxy object.
|
||||
*
|
||||
* This routine creates an instance of the skeleton_proxy class. It
|
||||
* will typically be used when calling @c send, @c recv, or @c
|
||||
* broadcast, to indicate that only the skeleton (structure) of an
|
||||
* object should be transmitted and not its contents.
|
||||
*
|
||||
* @param x the object whose structure will be transmitted.
|
||||
*
|
||||
* @returns a skeleton_proxy object referencing @p x
|
||||
*/
|
||||
template <class T>
|
||||
inline const skeleton_proxy<T> skeleton(T& x)
|
||||
{
|
||||
return skeleton_proxy<T>(x);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
/// @brief a class holding an MPI datatype
|
||||
/// INTERNAL ONLY
|
||||
/// the type is freed upon destruction
|
||||
class BOOST_MPI_DECL mpi_datatype_holder : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
mpi_datatype_holder()
|
||||
: is_committed(false)
|
||||
{}
|
||||
|
||||
mpi_datatype_holder(MPI_Datatype t, bool committed = true)
|
||||
: d(t)
|
||||
, is_committed(committed)
|
||||
{}
|
||||
|
||||
void commit()
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&d));
|
||||
is_committed=true;
|
||||
}
|
||||
|
||||
MPI_Datatype get_mpi_datatype() const
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
~mpi_datatype_holder()
|
||||
{
|
||||
int finalized=0;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
|
||||
if (!finalized && is_committed)
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_free,(&d));
|
||||
}
|
||||
|
||||
private:
|
||||
MPI_Datatype d;
|
||||
bool is_committed;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
/** @brief A proxy object that transfers the content of an object
|
||||
* without its structure.
|
||||
*
|
||||
* The @c content class indicates that Boost.MPI should transmit or
|
||||
* receive the content of an object, but without any information
|
||||
* about the structure of the object. It is only meaningful to
|
||||
* transmit the content of an object after the receiver has already
|
||||
* received the skeleton for the same object.
|
||||
*
|
||||
* Most users will not use @c content objects directly. Rather, they
|
||||
* will invoke @c send, @c recv, or @c broadcast operations using @c
|
||||
* get_content().
|
||||
*/
|
||||
class BOOST_MPI_DECL content
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs an empty @c content object. This object will not be
|
||||
* useful for any Boost.MPI operations until it is reassigned.
|
||||
*/
|
||||
content() {}
|
||||
|
||||
/**
|
||||
* This routine initializes the @c content object with an MPI data
|
||||
* type that refers to the content of an object without its structure.
|
||||
*
|
||||
* @param d the MPI data type referring to the content of the object.
|
||||
*
|
||||
* @param committed @c true indicates that @c MPI_Type_commit has
|
||||
* already been excuted for the data type @p d.
|
||||
*/
|
||||
content(MPI_Datatype d, bool committed=true)
|
||||
: holder(new detail::mpi_datatype_holder(d,committed))
|
||||
{}
|
||||
|
||||
/**
|
||||
* Replace the MPI data type referencing the content of an object.
|
||||
*
|
||||
* @param d the new MPI data type referring to the content of the
|
||||
* object.
|
||||
*
|
||||
* @returns *this
|
||||
*/
|
||||
const content& operator=(MPI_Datatype d)
|
||||
{
|
||||
holder.reset(new detail::mpi_datatype_holder(d));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the MPI data type that refers to the content of the
|
||||
* object.
|
||||
*
|
||||
* @returns the MPI data type, which should only be transmitted or
|
||||
* received using @c MPI_BOTTOM as the address.
|
||||
*/
|
||||
MPI_Datatype get_mpi_datatype() const
|
||||
{
|
||||
return holder->get_mpi_datatype();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the MPI data type referring to the content of the
|
||||
* object.
|
||||
*/
|
||||
void commit()
|
||||
{
|
||||
holder->commit();
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<detail::mpi_datatype_holder> holder;
|
||||
};
|
||||
|
||||
/** @brief Returns the content of an object, suitable for transmission
|
||||
* via Boost.MPI.
|
||||
*
|
||||
* The function creates an absolute MPI datatype for the object,
|
||||
* where all offsets are counted from the address 0 (a.k.a. @c
|
||||
* MPI_BOTTOM) instead of the address @c &x of the object. This
|
||||
* allows the creation of MPI data types for complex data structures
|
||||
* containing pointers, such as linked lists or trees.
|
||||
*
|
||||
* The disadvantage, compared to relative MPI data types is that for
|
||||
* each object a new MPI data type has to be created.
|
||||
*
|
||||
* The contents of an object can only be transmitted when the
|
||||
* receiver already has an object with the same structure or shape as
|
||||
* the sender. To accomplish this, first transmit the skeleton of the
|
||||
* object using, e.g., @c skeleton() or @c skeleton_proxy.
|
||||
*
|
||||
* The type @c T has to allow creation of an absolute MPI data type
|
||||
* (content).
|
||||
*
|
||||
* @param x the object for which the content will be transmitted.
|
||||
*
|
||||
* @returns the content of the object @p x, which can be used for
|
||||
* transmission via @c send, @c recv, or @c broadcast.
|
||||
*/
|
||||
template <class T> const content get_content(const T& x);
|
||||
|
||||
/** @brief An archiver that reconstructs a data structure based on the
|
||||
* binary skeleton stored in a buffer.
|
||||
*
|
||||
* The @c packed_skeleton_iarchive class is an Archiver (as in the
|
||||
* Boost.Serialization library) that can construct the the shape of a
|
||||
* data structure based on a binary skeleton stored in a buffer. The
|
||||
* @c packed_skeleton_iarchive is typically used by the receiver of a
|
||||
* skeleton, to prepare a data structure that will eventually receive
|
||||
* content separately.
|
||||
*
|
||||
* Users will not generally need to use @c packed_skeleton_iarchive
|
||||
* directly. Instead, use @c skeleton or @c get_skeleton.
|
||||
*/
|
||||
class BOOST_MPI_DECL packed_skeleton_iarchive
|
||||
: public detail::ignore_iprimitive,
|
||||
public detail::forward_skeleton_iarchive<packed_skeleton_iarchive,packed_iarchive>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a @c packed_skeleton_iarchive for the given
|
||||
* communicator.
|
||||
*
|
||||
* @param comm The communicator over which this archive will be
|
||||
* transmitted.
|
||||
*
|
||||
* @param flags Control the serialization of the skeleton. Refer to
|
||||
* the Boost.Serialization documentation before changing the
|
||||
* default flags.
|
||||
*/
|
||||
packed_skeleton_iarchive(MPI_Comm const & comm,
|
||||
unsigned int flags = boost::archive::no_header)
|
||||
: detail::forward_skeleton_iarchive<packed_skeleton_iarchive,packed_iarchive>(skeleton_archive_)
|
||||
, skeleton_archive_(comm,flags)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Construct a @c packed_skeleton_iarchive that unpacks a skeleton
|
||||
* from the given @p archive.
|
||||
*
|
||||
* @param archive the archive from which the skeleton will be
|
||||
* unpacked.
|
||||
*
|
||||
*/
|
||||
explicit packed_skeleton_iarchive(packed_iarchive & archive)
|
||||
: detail::forward_skeleton_iarchive<packed_skeleton_iarchive,packed_iarchive>(archive)
|
||||
, skeleton_archive_(MPI_COMM_WORLD, boost::archive::no_header)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Retrieve the archive corresponding to this skeleton.
|
||||
*/
|
||||
const packed_iarchive& get_skeleton() const
|
||||
{
|
||||
return this->implementation_archive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the archive corresponding to this skeleton.
|
||||
*/
|
||||
packed_iarchive& get_skeleton()
|
||||
{
|
||||
return this->implementation_archive;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Store the actual archive that holds the structure, unless the
|
||||
/// user overrides this with their own archive.
|
||||
packed_iarchive skeleton_archive_;
|
||||
};
|
||||
|
||||
/** @brief An archiver that records the binary skeleton of a data
|
||||
* structure into a buffer.
|
||||
*
|
||||
* The @c packed_skeleton_oarchive class is an Archiver (as in the
|
||||
* Boost.Serialization library) that can record the shape of a data
|
||||
* structure (called the "skeleton") into a binary representation
|
||||
* stored in a buffer. The @c packed_skeleton_oarchive is typically
|
||||
* used by the send of a skeleton, to pack the skeleton of a data
|
||||
* structure for transmission separately from the content.
|
||||
*
|
||||
* Users will not generally need to use @c packed_skeleton_oarchive
|
||||
* directly. Instead, use @c skeleton or @c get_skeleton.
|
||||
*/
|
||||
class BOOST_MPI_DECL packed_skeleton_oarchive
|
||||
: public detail::ignore_oprimitive,
|
||||
public detail::forward_skeleton_oarchive<packed_skeleton_oarchive,packed_oarchive>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a @c packed_skeleton_oarchive for the given
|
||||
* communicator.
|
||||
*
|
||||
* @param comm The communicator over which this archive will be
|
||||
* transmitted.
|
||||
*
|
||||
* @param flags Control the serialization of the skeleton. Refer to
|
||||
* the Boost.Serialization documentation before changing the
|
||||
* default flags.
|
||||
*/
|
||||
packed_skeleton_oarchive(MPI_Comm const & comm,
|
||||
unsigned int flags = boost::archive::no_header)
|
||||
: detail::forward_skeleton_oarchive<packed_skeleton_oarchive,packed_oarchive>(skeleton_archive_)
|
||||
, skeleton_archive_(comm,flags)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Construct a @c packed_skeleton_oarchive that packs a skeleton
|
||||
* into the given @p archive.
|
||||
*
|
||||
* @param archive the archive to which the skeleton will be packed.
|
||||
*
|
||||
*/
|
||||
explicit packed_skeleton_oarchive(packed_oarchive & archive)
|
||||
: detail::forward_skeleton_oarchive<packed_skeleton_oarchive,packed_oarchive>(archive)
|
||||
, skeleton_archive_(MPI_COMM_WORLD, boost::archive::no_header)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Retrieve the archive corresponding to this skeleton.
|
||||
*/
|
||||
const packed_oarchive& get_skeleton() const
|
||||
{
|
||||
return this->implementation_archive;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Store the actual archive that holds the structure.
|
||||
packed_oarchive skeleton_archive_;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
typedef boost::mpi::detail::forward_skeleton_oarchive<boost::mpi::packed_skeleton_oarchive,boost::mpi::packed_oarchive> type1;
|
||||
typedef boost::mpi::detail::forward_skeleton_iarchive<boost::mpi::packed_skeleton_iarchive,boost::mpi::packed_iarchive> type2;
|
||||
}
|
||||
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#include <boost/mpi/detail/content_oarchive.hpp>
|
||||
|
||||
// For any headers that have provided declarations based on forward
|
||||
// declarations of the contents of this header, include definitions
|
||||
// for those declarations. This means that the inclusion of
|
||||
// skeleton_and_content.hpp enables the use of skeleton/content
|
||||
// transmission throughout the library.
|
||||
#ifdef BOOST_MPI_BROADCAST_HPP
|
||||
# include <boost/mpi/detail/broadcast_sc.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MPI_COMMUNICATOR_HPP
|
||||
# include <boost/mpi/detail/communicator_sc.hpp>
|
||||
#endif
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_skeleton_oarchive)
|
||||
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
|
||||
Reference in New Issue
Block a user