feat():initial version
This commit is contained in:
40
install/boost_1_75_0/include/boost/mpi/detail/antiques.hpp
Normal file
40
install/boost_1_75_0/include/boost/mpi/detail/antiques.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright Alain Miniussi 2014.
|
||||
// Distributed under 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: Alain Miniussi
|
||||
|
||||
#ifndef BOOST_MPI_ANTIQUES_HPP
|
||||
#define BOOST_MPI_ANTIQUES_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Support for some obsolette compilers
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
namespace detail {
|
||||
// Some old gnu compiler have no support for vector<>::data
|
||||
// Use this in the mean time, the cumbersome syntax should
|
||||
// serve as an incentive to get rid of this when those compilers
|
||||
// are dropped.
|
||||
template <typename T, typename A>
|
||||
T* c_data(std::vector<T,A>& v) { return v.empty() ? static_cast<T*>(0) : &(v[0]); }
|
||||
|
||||
template <typename T, typename A>
|
||||
T const* c_data(std::vector<T,A> const& v) { return v.empty() ? static_cast<T const*>(0) : &(v[0]); }
|
||||
|
||||
// Some old MPI implementation (OpenMPI 1.6 for example) have non
|
||||
// conforming API w.r.t. constness.
|
||||
// We choose to fix this trhough this converter in order to
|
||||
// explain/remember why we're doing this and remove it easilly
|
||||
// when support for those MPI is dropped.
|
||||
// The fix is as specific (un templatized, for one) as possible
|
||||
// in order to encourage it usage for the probleme at hand.
|
||||
// Problematic API include MPI_Send
|
||||
inline
|
||||
void *unconst(void const* addr) { return const_cast<void*>(addr); }
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
// (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
|
||||
#include <cassert>
|
||||
|
||||
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 detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
void const* address () const
|
||||
{
|
||||
return detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
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_wrapper<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_wrapper<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));
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
void load(std::basic_string<CharType> & 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)
|
||||
{
|
||||
assert(position+l<=static_cast<int>(buffer_.size()));
|
||||
if (l)
|
||||
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
|
||||
@@ -0,0 +1,109 @@
|
||||
// (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 detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
const std::size_t& size() const
|
||||
{
|
||||
return size_ = buffer_.size();
|
||||
}
|
||||
|
||||
const std::size_t* size_ptr() const
|
||||
{
|
||||
return &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_wrapper<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_wrapper<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));
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
void save(const std::basic_string<CharType> &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
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2005, 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)
|
||||
|
||||
// Allows broadcast of skeletons via proxy.
|
||||
|
||||
// This header may only be included after both the broadcast.hpp and
|
||||
// and skeleton_and_content.hpp headers have been included.
|
||||
#ifndef BOOST_MPI_BROADCAST_SC_HPP
|
||||
#define BOOST_MPI_BROADCAST_SC_HPP
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
broadcast(const communicator& comm, const skeleton_proxy<T>& proxy, int root)
|
||||
{
|
||||
if (comm.rank() == root) {
|
||||
packed_skeleton_oarchive oa(comm);
|
||||
oa << proxy.object;
|
||||
broadcast(comm, oa, root);
|
||||
} else {
|
||||
packed_skeleton_iarchive ia(comm);
|
||||
broadcast(comm, ia, root);
|
||||
ia >> proxy.object;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void
|
||||
broadcast(const communicator& comm, skeleton_proxy<T>& proxy, int root)
|
||||
{
|
||||
const skeleton_proxy<T>& const_proxy(proxy);
|
||||
broadcast(comm, const_proxy, root);
|
||||
}
|
||||
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_BROADCAST_SC_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (C) 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)
|
||||
|
||||
// Skeleton and content support for communicators
|
||||
|
||||
// This header should be included only after both communicator.hpp and
|
||||
// skeleton_and_content.hpp have been included.
|
||||
#ifndef BOOST_MPI_COMMUNICATOR_SC_HPP
|
||||
#define BOOST_MPI_COMMUNICATOR_SC_HPP
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
communicator::send(int dest, int tag, const skeleton_proxy<T>& proxy) const
|
||||
{
|
||||
packed_skeleton_oarchive ar(*this);
|
||||
ar << proxy.object;
|
||||
send(dest, tag, ar);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
status
|
||||
communicator::recv(int source, int tag, const skeleton_proxy<T>& proxy) const
|
||||
{
|
||||
packed_skeleton_iarchive ar(*this);
|
||||
status result = recv(source, tag, ar);
|
||||
ar >> proxy.object;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
status communicator::recv(int source, int tag, skeleton_proxy<T>& proxy) const
|
||||
{
|
||||
packed_skeleton_iarchive ar(*this);
|
||||
status result = recv(source, tag, ar);
|
||||
ar >> proxy.object;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request
|
||||
communicator::isend(int dest, int tag, const skeleton_proxy<T>& proxy) const
|
||||
{
|
||||
shared_ptr<packed_skeleton_oarchive>
|
||||
archive(new packed_skeleton_oarchive(*this));
|
||||
|
||||
*archive << proxy.object;
|
||||
request result = isend(dest, tag, *archive);
|
||||
result.preserve(archive);
|
||||
return result;
|
||||
}
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_COMMUNICATOR_SC_HPP
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (C) 2005 Douglas Gregor.
|
||||
|
||||
// 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)
|
||||
|
||||
// Compute parents, children, levels, etc. to effect a parallel
|
||||
// computation tree.
|
||||
#ifndef BOOST_MPI_COMPUTATION_TREE_HPP
|
||||
#define BOOST_MPI_COMPUTATION_TREE_HPP
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Aids tree-based parallel collective algorithms.
|
||||
*
|
||||
* Objects of this type
|
||||
*/
|
||||
class computation_tree
|
||||
{
|
||||
public:
|
||||
computation_tree(int rank, int size, int root, int branching_factor = -1);
|
||||
|
||||
/// Returns the branching factor of the tree.
|
||||
int branching_factor() const { return branching_factor_; }
|
||||
|
||||
/// Returns the level in the tree on which this process resides.
|
||||
int level() const { return level_; }
|
||||
|
||||
/**
|
||||
* Returns the index corresponding to the n^th level of the tree.
|
||||
*
|
||||
* @param n The level in the tree whose index will be returned.
|
||||
*/
|
||||
int level_index(int n) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the parent of this process.
|
||||
*
|
||||
* @returns If this process is the root, returns itself. Otherwise,
|
||||
* returns the process number that is the parent in the computation
|
||||
* tree.
|
||||
*/
|
||||
int parent() const;
|
||||
|
||||
/// Returns the index for the first child of this process.
|
||||
int child_begin() const;
|
||||
|
||||
/**
|
||||
* @brief The default branching factor within the computation tree.
|
||||
*
|
||||
* This is the default branching factor for the computation tree, to
|
||||
* be used by any computation tree that does not fix the branching
|
||||
* factor itself. The default is initialized to 3, but may be
|
||||
* changed by the application so long as all processes have the same
|
||||
* branching factor.
|
||||
*/
|
||||
static int default_branching_factor;
|
||||
|
||||
protected:
|
||||
/// The rank of this process in the computation tree.
|
||||
int rank;
|
||||
|
||||
/// The number of processes participating in the computation tree.
|
||||
int size;
|
||||
|
||||
/// The process number that is acting as the root in the computation
|
||||
/// tree.
|
||||
int root;
|
||||
|
||||
/**
|
||||
* @brief The branching factor within the computation tree.
|
||||
*
|
||||
* This is the default number of children that each node in a
|
||||
* computation tree will have. This value will be used for
|
||||
* collective operations that use tree-based algorithms.
|
||||
*/
|
||||
int branching_factor_;
|
||||
|
||||
/// The level in the tree at which this process resides.
|
||||
int level_;
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_COMPUTATION_TREE_HPP
|
||||
@@ -0,0 +1,66 @@
|
||||
// (C) Copyright 2005 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_DETAIL_CONTENT_OARCHIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_CONTENT_OARCHIVE_HPP
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/basic_archive.hpp>
|
||||
#include <boost/mpi/detail/ignore_skeleton_oarchive.hpp>
|
||||
#include <boost/mpi/detail/mpi_datatype_primitive.hpp>
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
namespace detail {
|
||||
// an archive wrapper that stores only the data members but not the
|
||||
// special types defined by the serialization library
|
||||
// to define the data skeletons (classes, pointers, container sizes, ...)
|
||||
|
||||
class BOOST_MPI_DECL content_oarchive
|
||||
: public mpi_datatype_primitive,
|
||||
public ignore_skeleton_oarchive<content_oarchive>
|
||||
{
|
||||
public:
|
||||
content_oarchive()
|
||||
: committed(false)
|
||||
{}
|
||||
|
||||
content get_content()
|
||||
{
|
||||
if (!committed)
|
||||
{
|
||||
// create the content holder only once
|
||||
c=this->get_mpi_datatype();
|
||||
committed=true;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private:
|
||||
bool committed;
|
||||
content c;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
template <class T>
|
||||
const content get_content(const T& x)
|
||||
{
|
||||
detail::content_oarchive ar;
|
||||
ar << x;
|
||||
return ar.get_content();
|
||||
}
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,72 @@
|
||||
// (C) Copyright 2005 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
|
||||
|
||||
#include <boost/serialization/array.hpp>
|
||||
|
||||
#ifndef BOOST_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/// @brief a minimal input archive, which forwards reading to another archive
|
||||
///
|
||||
/// This class template is designed to use the loading facilities of another
|
||||
/// input archive (the "implementation archive", whose type is specified by
|
||||
/// the template argument, to handle serialization of primitive types,
|
||||
/// while serialization for specific types can be overriden independently
|
||||
/// of that archive.
|
||||
|
||||
template <class ImplementationArchive>
|
||||
class forward_iprimitive
|
||||
{
|
||||
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
|
||||
forward_iprimitive(implementation_archive_type& ar)
|
||||
: implementation_archive(ar)
|
||||
{}
|
||||
|
||||
/// 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
|
||||
template<class T>
|
||||
void load_array(serialization::array_wrapper<T> & x, unsigned int file_version )
|
||||
{
|
||||
implementation_archive.load_array(x,file_version);
|
||||
}
|
||||
|
||||
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
friend class archive::load_access;
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
|
||||
/// loading of primitives is forwarded to the implementation archive
|
||||
template<class T>
|
||||
void load(T & t)
|
||||
{
|
||||
implementation_archive >> t;
|
||||
}
|
||||
|
||||
private:
|
||||
implementation_archive_type& implementation_archive;
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP
|
||||
@@ -0,0 +1,73 @@
|
||||
// (C) Copyright 2005 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_DETAIL_FORWARD_OPRIMITIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_FORWARD_OPRIMITIVE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/// @brief a minimal output archive, which forwards saving to another archive
|
||||
///
|
||||
/// This class template is designed to use the saving facilities of another
|
||||
/// output archive (the "implementation archive", whose type is specified by
|
||||
/// the template argument, to handle serialization of primitive types,
|
||||
/// while serialization for specific types can be overriden independently
|
||||
/// of that archive.
|
||||
|
||||
template <class ImplementationArchive>
|
||||
class forward_oprimitive
|
||||
{
|
||||
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
|
||||
forward_oprimitive(implementation_archive_type& ar)
|
||||
: implementation_archive(ar)
|
||||
{}
|
||||
|
||||
/// 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
|
||||
template<class T>
|
||||
void save_array(serialization::array_wrapper<T> const& x, unsigned int file_version )
|
||||
{
|
||||
implementation_archive.save_array(x,file_version);
|
||||
}
|
||||
|
||||
typedef typename ImplementationArchive::use_array_optimization use_array_optimization;
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
friend class archive::save_access;
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
|
||||
/// saving of primitives is forwarded to the implementation archive
|
||||
template<class T>
|
||||
void save(const T & t)
|
||||
{
|
||||
implementation_archive << t;
|
||||
}
|
||||
|
||||
private:
|
||||
implementation_archive_type& implementation_archive;
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_FORWARD_OPRIMITIVE_HPP
|
||||
@@ -0,0 +1,80 @@
|
||||
// (C) Copyright 2005 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_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/detail/iserializer.hpp>
|
||||
#include <boost/archive/detail/interface_iarchive.hpp>
|
||||
#include <boost/archive/detail/common_iarchive.hpp>
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
template<class Archive, class ImplementationArchive>
|
||||
class forward_skeleton_iarchive
|
||||
: public archive::detail::common_iarchive<Archive>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ImplementationArchive implementation_archive_type;
|
||||
|
||||
forward_skeleton_iarchive(implementation_archive_type& ar)
|
||||
: archive::detail::common_iarchive<Archive>(archive::no_header),
|
||||
implementation_archive(ar)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class archive::detail::interface_iarchive<Archive>;
|
||||
friend class archive::load_access;
|
||||
protected:
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
void load_override(T & t)
|
||||
{
|
||||
archive::load(* this->This(), t);
|
||||
}
|
||||
|
||||
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
|
||||
void load_override(T & t) \
|
||||
{ \
|
||||
implementation_archive >> t; \
|
||||
}
|
||||
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_optional_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_reference_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_id_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_reference_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::tracking_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_name_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(serialization::collection_size_type)
|
||||
|
||||
void load_override(std::string & s)
|
||||
{
|
||||
serialization::collection_size_type length(s.size());
|
||||
load_override(length);
|
||||
s.resize(length);
|
||||
}
|
||||
|
||||
#undef BOOST_ARCHIVE_FORWARD_IMPLEMENTATION
|
||||
protected:
|
||||
/// the actual archive used to serialize the information we actually want to store
|
||||
implementation_archive_type& implementation_archive;
|
||||
};
|
||||
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
|
||||
@@ -0,0 +1,78 @@
|
||||
// (C) Copyright 2005 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_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/detail/oserializer.hpp>
|
||||
#include <boost/archive/detail/interface_oarchive.hpp>
|
||||
#include <boost/archive/detail/common_oarchive.hpp>
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
template<class Archive, class ImplementationArchive>
|
||||
class forward_skeleton_oarchive
|
||||
: public archive::detail::common_oarchive<Archive>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ImplementationArchive implementation_archive_type;
|
||||
|
||||
forward_skeleton_oarchive(implementation_archive_type& ar)
|
||||
: archive::detail::common_oarchive<Archive>(archive::no_header),
|
||||
implementation_archive(ar)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class archive::detail::interface_oarchive<Archive>;
|
||||
friend class archive::save_access;
|
||||
protected:
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
void save_override(T const& t)
|
||||
{
|
||||
archive::save(* this->This(), t);
|
||||
}
|
||||
|
||||
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
|
||||
void save_override(T const & t) \
|
||||
{ \
|
||||
implementation_archive << t; \
|
||||
}
|
||||
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_optional_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_reference_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_id_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_reference_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::tracking_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_name_type)
|
||||
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(serialization::collection_size_type)
|
||||
|
||||
void save_override(std::string const & t)
|
||||
{
|
||||
save_override(serialization::collection_size_type(t.size()));
|
||||
}
|
||||
|
||||
|
||||
#undef BOOST_ARCHIVE_FORWARD_IMPLEMENTATION
|
||||
protected:
|
||||
/// the actual archive used to serialize the information we actually want to store
|
||||
implementation_archive_type& implementation_archive;
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
|
||||
@@ -0,0 +1,54 @@
|
||||
// (C) Copyright 2005 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_DETAIL_IGNORE_IPRIMITIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_IGNORE_IPRIMITIVE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/// @brief a minimal input archive, which ignores any load
|
||||
///
|
||||
/// This class implements a minimal input archive, probably an input archive
|
||||
/// archetype, doing nothing at any load. It's use, besides acting as an
|
||||
/// archetype is as a base class to implement special archives that ignore
|
||||
/// loading of most types
|
||||
|
||||
class ignore_iprimitive
|
||||
{
|
||||
public:
|
||||
/// a trivial default constructor
|
||||
ignore_iprimitive()
|
||||
{}
|
||||
|
||||
|
||||
/// don't do anything when loading binary data
|
||||
void load_binary(void *, std::size_t )
|
||||
{}
|
||||
|
||||
/// don't do anything when loading arrays
|
||||
template<class T>
|
||||
void load_array(serialization::array_wrapper<T> &, unsigned int )
|
||||
{}
|
||||
|
||||
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
|
||||
|
||||
/// don't do anything when loading primitive types
|
||||
template<class T>
|
||||
void load(T &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_IGNORE_IPRIMITIVE_HPP
|
||||
@@ -0,0 +1,62 @@
|
||||
// (C) Copyright 2005 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_DETAIL_IGNORE_OPRIMITIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_IGNORE_OPRIMITIVE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/// @brief a minimal output archive, which ignores any save
|
||||
///
|
||||
/// This class implements a minimal output archive, probably an output archive
|
||||
/// archetype, doing nothing at any save. It's use, besides acting as an
|
||||
/// archetype is as a base class to implement special archives that ignore
|
||||
/// saving of most types
|
||||
|
||||
class ignore_oprimitive
|
||||
{
|
||||
public:
|
||||
/// a trivial default constructor
|
||||
ignore_oprimitive()
|
||||
{}
|
||||
|
||||
/// don't do anything when saving binary data
|
||||
void save_binary(const void *, std::size_t )
|
||||
{
|
||||
}
|
||||
|
||||
/// don't do anything when saving arrays
|
||||
template<class T>
|
||||
void save_array(serialization::array_wrapper<T> const&, unsigned int )
|
||||
{
|
||||
}
|
||||
|
||||
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
|
||||
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
friend class archive::save_access;
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
|
||||
/// don't do anything when saving primitive types
|
||||
template<class T>
|
||||
void save(const T &)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_IGNORE_OPRIMITIVE_HPP
|
||||
@@ -0,0 +1,73 @@
|
||||
// (C) Copyright 2005 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_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.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>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/serialization/item_version_type.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
template<class Archive>
|
||||
class ignore_skeleton_oarchive
|
||||
: public archive::detail::common_oarchive<Archive>
|
||||
{
|
||||
public:
|
||||
ignore_skeleton_oarchive()
|
||||
: archive::detail::common_oarchive<Archive>(archive::no_header)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
friend class archive::detail::interface_oarchive<Archive>;
|
||||
friend class archive::save_access;
|
||||
protected:
|
||||
#endif
|
||||
template<class T>
|
||||
void save_override(T const& t)
|
||||
{
|
||||
archive::save(* this->This(), t);
|
||||
}
|
||||
|
||||
#define BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(T) \
|
||||
void save_override(T const &) \
|
||||
{}
|
||||
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_optional_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::version_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::library_version_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_reference_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::object_id_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::object_reference_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::tracking_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_name_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(serialization::collection_size_type)
|
||||
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(serialization::item_version_type)
|
||||
|
||||
void save_override(std::string const & s)
|
||||
{
|
||||
if (s.size())
|
||||
save_override(serialization::make_array(s.data(),s.size()));
|
||||
}
|
||||
|
||||
#undef BOOST_ARCHIVE_IGNORE_IMPLEMENTATION
|
||||
};
|
||||
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
|
||||
@@ -0,0 +1,99 @@
|
||||
// (C) Copyright 2005 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_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
|
||||
#define BOOST_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
|
||||
|
||||
#include <boost/mpi/datatype_fwd.hpp>
|
||||
#include <boost/mpi/detail/mpi_datatype_oarchive.hpp>
|
||||
#include <boost/mpi/exception.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
// The std::type_info::before function in Visual C++ 8.0 (and probably earlier)
|
||||
// incorrectly returns an "int" instead of a "bool". Then the compiler has the
|
||||
// audacity to complain when that "int" is converted to a "bool". Silence
|
||||
// this warning.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4800)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/// @brief comparison function object for two std::type_info pointers
|
||||
///
|
||||
/// is implemented using the before() member function of the std::type_info
|
||||
/// class
|
||||
|
||||
struct type_info_compare
|
||||
{
|
||||
bool operator()(std::type_info const* lhs, std::type_info const* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// @brief a map of MPI data types, indexed by their type_info
|
||||
///
|
||||
///
|
||||
class BOOST_MPI_DECL mpi_datatype_map
|
||||
: public boost::noncopyable
|
||||
{
|
||||
struct implementation;
|
||||
|
||||
implementation *impl;
|
||||
|
||||
public:
|
||||
mpi_datatype_map();
|
||||
~mpi_datatype_map();
|
||||
|
||||
template <class T>
|
||||
MPI_Datatype datatype(const T& x = T(), typename boost::enable_if<is_mpi_builtin_datatype<T> >::type* =0)
|
||||
{
|
||||
return get_mpi_datatype<T>(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
MPI_Datatype datatype(const T& x =T(), typename boost::disable_if<is_mpi_builtin_datatype<T> >::type* =0 )
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_mpi_datatype<T>));
|
||||
|
||||
// check whether the type already exists
|
||||
std::type_info const* t = &typeid(T);
|
||||
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);
|
||||
}
|
||||
|
||||
return datatype;
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
MPI_Datatype get(const std::type_info* t);
|
||||
void set(const std::type_info* t, MPI_Datatype datatype);
|
||||
};
|
||||
|
||||
/// Retrieve the MPI datatype cache
|
||||
BOOST_MPI_DECL mpi_datatype_map& mpi_datatype_cache();
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
|
||||
@@ -0,0 +1,75 @@
|
||||
// (C) Copyright 2005 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_DETAIL_MPI_DATATYPE_OARCHIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_MPI_DATATYPE_OARCHIVE_HPP
|
||||
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/archive/detail/oserializer.hpp>
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/basic_archive.hpp>
|
||||
#include <boost/mpi/detail/ignore_skeleton_oarchive.hpp>
|
||||
#include <boost/mpi/detail/mpi_datatype_primitive.hpp>
|
||||
#include <boost/mpi/datatype_fwd.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
|
||||
// an archive wrapper that stores only the data members but not the
|
||||
// special types defined by the serialization library
|
||||
// to define the data skeletons (classes, pointers, container sizes, ...)
|
||||
|
||||
class mpi_datatype_oarchive
|
||||
: public mpi_datatype_primitive,
|
||||
public ignore_skeleton_oarchive<mpi_datatype_oarchive>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
mpi_datatype_oarchive(const T& x)
|
||||
: mpi_datatype_primitive(&x) // register address
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_mpi_datatype<T>));
|
||||
*this << x; // serialize the object
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void save_override(T const& t)
|
||||
{
|
||||
save_enum(t,boost::is_enum<T>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void save_enum(T const& t, mpl::false_)
|
||||
{
|
||||
ignore_skeleton_oarchive<mpi_datatype_oarchive>::save_override(t);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void save_enum(T const& t, mpl::true_)
|
||||
{
|
||||
// select the right sized integer for the enum
|
||||
typedef typename boost::uint_t<8*sizeof(T)>::least int_type;
|
||||
BOOST_STATIC_ASSERT((sizeof(T)==sizeof(int_type)));
|
||||
this->save(*reinterpret_cast<int_type const*>(&t));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,152 @@
|
||||
// (C) Copyright 2005 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_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
|
||||
#define BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
|
||||
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::size_t;
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#include <boost/mpi/datatype_fwd.hpp>
|
||||
#include <boost/mpi/exception.hpp>
|
||||
#include <boost/mpi/detail/antiques.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/mpi/detail/antiques.hpp>
|
||||
|
||||
namespace boost { namespace mpi { namespace detail {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// class mpi_data_type_oprimitive - creation of custom MPI data types
|
||||
|
||||
class mpi_datatype_primitive
|
||||
{
|
||||
public:
|
||||
|
||||
// trivial default constructor
|
||||
mpi_datatype_primitive()
|
||||
: is_committed(false),
|
||||
origin(0)
|
||||
{}
|
||||
|
||||
mpi_datatype_primitive(void const* orig)
|
||||
: is_committed(false),
|
||||
origin()
|
||||
{
|
||||
#if BOOST_MPI_VERSION >= 2
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(orig), &origin));
|
||||
#else
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
|
||||
#endif
|
||||
}
|
||||
|
||||
void save_binary(void const *address, std::size_t count)
|
||||
{
|
||||
save_impl(address,MPI_BYTE,count);
|
||||
}
|
||||
|
||||
// fast saving of arrays of MPI types
|
||||
template<class T>
|
||||
void save_array(serialization::array_wrapper<T> const& x, unsigned int /* version */)
|
||||
{
|
||||
if (x.count())
|
||||
save_impl(x.address(), boost::mpi::get_mpi_datatype(*x.address()), x.count());
|
||||
}
|
||||
|
||||
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
|
||||
|
||||
// create and return the custom MPI data type
|
||||
MPI_Datatype get_mpi_datatype()
|
||||
{
|
||||
if (!is_committed)
|
||||
{
|
||||
#if BOOST_MPI_VERSION >= 2
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_create_struct,
|
||||
(
|
||||
addresses.size(),
|
||||
c_data(lengths),
|
||||
c_data(addresses),
|
||||
c_data(types),
|
||||
&datatype_
|
||||
));
|
||||
#else
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
|
||||
(
|
||||
addresses.size(),
|
||||
c_data(lengths),
|
||||
c_data(addresses),
|
||||
c_data(types),
|
||||
&datatype_
|
||||
));
|
||||
#endif
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_));
|
||||
|
||||
is_committed = true;
|
||||
}
|
||||
|
||||
return datatype_;
|
||||
}
|
||||
|
||||
// default saving of primitives.
|
||||
template<class T>
|
||||
void save(const T & t)
|
||||
{
|
||||
save_impl(&t, boost::mpi::get_mpi_datatype(t), 1);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void save_impl(void const * p, MPI_Datatype t, int l)
|
||||
{
|
||||
BOOST_ASSERT ( !is_committed );
|
||||
|
||||
// store address, type and length
|
||||
|
||||
MPI_Aint a;
|
||||
#if BOOST_MPI_VERSION >= 2
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(p), &a));
|
||||
#else
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
|
||||
#endif
|
||||
addresses.push_back(a-origin);
|
||||
types.push_back(t);
|
||||
lengths.push_back(l);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T* get_data(std::vector<T>& v)
|
||||
{
|
||||
return detail::c_data(v);
|
||||
}
|
||||
|
||||
std::vector<MPI_Aint> addresses;
|
||||
std::vector<MPI_Datatype> types;
|
||||
std::vector<int> lengths;
|
||||
|
||||
bool is_committed;
|
||||
MPI_Datatype datatype_;
|
||||
MPI_Aint origin;
|
||||
};
|
||||
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
|
||||
48
install/boost_1_75_0/include/boost/mpi/detail/offsets.hpp
Normal file
48
install/boost_1_75_0/include/boost/mpi/detail/offsets.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright Alain Miniussi 2014.
|
||||
// Distributed under 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: Alain Miniussi
|
||||
|
||||
#ifndef BOOST_MPI_OFFSETS_HPP
|
||||
#define BOOST_MPI_OFFSETS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <boost/mpi/communicator.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
namespace detail {
|
||||
|
||||
// Convert a sequence of sizes [S0..Sn] to a sequence displacement
|
||||
// [O0..On] where O[0] = 0 and O[k+1] = O[k]+S[k].
|
||||
void BOOST_MPI_DECL sizes2offsets(int const* sizes, int* offsets, int n);
|
||||
|
||||
// Same as size2offset(sizes.data(), offsets.data(), sizes.size())
|
||||
void BOOST_MPI_DECL sizes2offsets(std::vector<int> const& sizes, std::vector<int>& offsets);
|
||||
|
||||
// Given a sequence of sizes (typically the number of records dispatched
|
||||
// to each process in a scater) and a sequence of displacements (typically the
|
||||
// slot index at with those record starts), convert the later to a number
|
||||
// of skipped slots.
|
||||
void offsets2skipped(int const* sizes, int const* offsets, int* skipped, int n);
|
||||
|
||||
// Reconstruct offsets from sizes assuming no padding.
|
||||
// Only takes place if on the root process and if
|
||||
// displs are not already provided.
|
||||
// If memory was allocated, returns a pointer to it
|
||||
// otherwise null.
|
||||
int* make_offsets(communicator const& comm, int const* sizes, int const* displs, int root = -1);
|
||||
|
||||
// Reconstruct skip slots from sizes and offsets.
|
||||
// Only takes place if on the root process and if
|
||||
// displs are provided.
|
||||
// If memory was allocated, returns a pointer to it
|
||||
// otherwise null.
|
||||
int* make_skipped_slots(communicator const& comm, int const* sizes, int const* displs, int root = -1);
|
||||
|
||||
}
|
||||
}}// end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_OFFSETS_HPP
|
||||
@@ -0,0 +1,118 @@
|
||||
// (C) Copyright 2005 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_PACKED_IPRIMITIVE_HPP
|
||||
#define BOOST_MPI_PACKED_IPRIMITIVE_HPP
|
||||
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <cstddef> // size_t
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/mpi/exception.hpp>
|
||||
#include <boost/mpi/detail/antiques.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <vector>
|
||||
#include <boost/mpi/detail/antiques.hpp>
|
||||
#include <boost/mpi/allocator.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
/// deserialization using MPI_Unpack
|
||||
|
||||
class BOOST_MPI_DECL packed_iprimitive
|
||||
{
|
||||
public:
|
||||
/// the type of the buffer from which the data is unpacked upon deserialization
|
||||
typedef std::vector<char, allocator<char> > buffer_type;
|
||||
|
||||
packed_iprimitive(buffer_type & b, MPI_Comm const & comm, int position = 0)
|
||||
: buffer_(b),
|
||||
comm(comm),
|
||||
position(position)
|
||||
{
|
||||
}
|
||||
|
||||
void* address ()
|
||||
{
|
||||
return detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
void const* address () const
|
||||
{
|
||||
return detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
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,MPI_BYTE,count);
|
||||
}
|
||||
|
||||
// fast saving of arrays of fundamental types
|
||||
template<class T>
|
||||
void load_array(serialization::array_wrapper<T> const& x, unsigned int /* file_version */)
|
||||
{
|
||||
if (x.count())
|
||||
load_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
|
||||
}
|
||||
|
||||
/*
|
||||
template<class T>
|
||||
void load(serialization::array_wrapper<T> const& x)
|
||||
{
|
||||
load_array(x,0u);
|
||||
}
|
||||
*/
|
||||
|
||||
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
|
||||
|
||||
// default saving of primitives.
|
||||
template<class T>
|
||||
void load( T & t)
|
||||
{
|
||||
load_impl(&t, get_mpi_datatype(t), 1);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
void load(std::basic_string<CharType> & s)
|
||||
{
|
||||
unsigned int l;
|
||||
load(l);
|
||||
s.resize(l);
|
||||
// note breaking a rule here - could be a problem on some platform
|
||||
if (l)
|
||||
load_impl(const_cast<CharType *>(s.data()),
|
||||
get_mpi_datatype(CharType()),l);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void load_impl(void * p, MPI_Datatype t, int l)
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Unpack,
|
||||
(const_cast<char*>(detail::c_data(buffer_)), buffer_.size(), &position, p, l, t, comm));
|
||||
}
|
||||
|
||||
buffer_type & buffer_;
|
||||
mutable std::size_t size_;
|
||||
MPI_Comm comm;
|
||||
int position;
|
||||
};
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_PACKED_IPRIMITIVE_HPP
|
||||
@@ -0,0 +1,127 @@
|
||||
// (C) Copyright 2005 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_PACKED_OPRIMITIVE_HPP
|
||||
#define BOOST_MPI_PACKED_OPRIMITIVE_HPP
|
||||
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <cstddef> // size_t
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/mpi/exception.hpp>
|
||||
#include <boost/mpi/detail/antiques.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <vector>
|
||||
#include <boost/mpi/allocator.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
/// serialization using MPI::Pack
|
||||
|
||||
class BOOST_MPI_DECL packed_oprimitive
|
||||
{
|
||||
public:
|
||||
/// the type of the buffer into which the data is packed upon serialization
|
||||
typedef std::vector<char, allocator<char> > buffer_type;
|
||||
|
||||
packed_oprimitive(buffer_type & b, MPI_Comm const & comm)
|
||||
: buffer_(b),
|
||||
comm(comm)
|
||||
{
|
||||
}
|
||||
|
||||
void const * address() const
|
||||
{
|
||||
return detail::c_data(buffer_);
|
||||
}
|
||||
|
||||
const std::size_t& size() const
|
||||
{
|
||||
return size_ = buffer_.size();
|
||||
}
|
||||
|
||||
const std::size_t* size_ptr() const
|
||||
{
|
||||
return &size();
|
||||
}
|
||||
|
||||
void save_binary(void const *address, std::size_t count)
|
||||
{
|
||||
save_impl(address,MPI_BYTE,count);
|
||||
}
|
||||
|
||||
// fast saving of arrays
|
||||
template<class T>
|
||||
void save_array(serialization::array_wrapper<T> const& x, unsigned int /* file_version */)
|
||||
{
|
||||
if (x.count())
|
||||
save_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
|
||||
}
|
||||
|
||||
typedef is_mpi_datatype<mpl::_1> use_array_optimization;
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
friend class archive::save_access;
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
|
||||
// default saving of primitives.
|
||||
template<class T>
|
||||
void save(const T & t)
|
||||
{
|
||||
save_impl(&t, get_mpi_datatype<T>(t), 1);
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
void save(const std::basic_string<CharType> &s)
|
||||
{
|
||||
unsigned int l = static_cast<unsigned int>(s.size());
|
||||
save(l);
|
||||
if (l)
|
||||
save_impl(s.data(),get_mpi_datatype(CharType()),s.size());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void save_impl(void const * p, MPI_Datatype t, int l)
|
||||
{
|
||||
// allocate enough memory
|
||||
int memory_needed;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Pack_size,(l,t,comm,&memory_needed));
|
||||
|
||||
int position = buffer_.size();
|
||||
buffer_.resize(position + memory_needed);
|
||||
|
||||
// pack the data into the buffer
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Pack,
|
||||
(const_cast<void*>(p),l,t,
|
||||
detail::c_data(buffer_),
|
||||
buffer_.size(),
|
||||
&position,comm));
|
||||
// reduce the buffer size if needed
|
||||
BOOST_ASSERT(std::size_t(position) <= buffer_.size());
|
||||
if (std::size_t(position) < buffer_.size())
|
||||
buffer_.resize(position);
|
||||
}
|
||||
|
||||
static buffer_type::value_type* get_data(buffer_type& b)
|
||||
{
|
||||
return detail::c_data(b);
|
||||
}
|
||||
|
||||
buffer_type& buffer_;
|
||||
mutable std::size_t size_;
|
||||
MPI_Comm comm;
|
||||
};
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
#endif // BOOST_MPI_PACKED_OPRIMITIVE_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2005 Douglas Gregor.
|
||||
|
||||
// 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)
|
||||
|
||||
// Message Passing Interface 1.1 -- Section 3. MPI Point-to-point
|
||||
#ifndef BOOST_MPI_DETAIL_POINT_TO_POINT_HPP
|
||||
#define BOOST_MPI_DETAIL_POINT_TO_POINT_HPP
|
||||
|
||||
// For (de-)serializing sends and receives
|
||||
#include <boost/mpi/config.hpp>
|
||||
#include <boost/mpi/packed_oarchive.hpp>
|
||||
#include <boost/mpi/packed_iarchive.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
class request;
|
||||
class communicator;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Sends a packed archive using MPI_Send. */
|
||||
BOOST_MPI_DECL void
|
||||
packed_archive_send(communicator const& comm, int dest, int tag,
|
||||
const packed_oarchive& ar);
|
||||
|
||||
/** Sends a packed archive using MPI_Isend.
|
||||
*
|
||||
* This routine may split sends into multiple packets. The MPI_Request
|
||||
* for each packet will be placed into the out_requests array, up to
|
||||
* num_out_requests packets. The number of packets sent will be
|
||||
* returned from the function.
|
||||
*/
|
||||
BOOST_MPI_DECL request
|
||||
packed_archive_isend(communicator const& comm, int dest, int tag,
|
||||
const packed_oarchive& ar);
|
||||
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
BOOST_MPI_DECL request
|
||||
packed_archive_isend(communicator const& comm, int dest, int tag,
|
||||
const packed_iarchive& ar);
|
||||
|
||||
/** Receives a packed archive using MPI_Recv. */
|
||||
BOOST_MPI_DECL void
|
||||
packed_archive_recv(communicator const& comm, int source, int tag, packed_iarchive& ar,
|
||||
MPI_Status& status);
|
||||
|
||||
} } } // end namespace boost::mpi::detail
|
||||
|
||||
#endif // BOOST_MPI_DETAIL_POINT_TO_POINT_HPP
|
||||
@@ -0,0 +1,631 @@
|
||||
// Copyright (C) 2018 Alain Miniussi <alain.miniussi@oca.eu>.
|
||||
|
||||
// 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)
|
||||
|
||||
// Request implementation dtails
|
||||
|
||||
// This header should be included only after the communicator and request
|
||||
// classes has been defined.
|
||||
#ifndef BOOST_MPI_REQUEST_HANDLERS_HPP
|
||||
#define BOOST_MPI_REQUEST_HANDLERS_HPP
|
||||
|
||||
#include <boost/mpi/skeleton_and_content_types.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
namespace detail {
|
||||
/**
|
||||
* Internal data structure that stores everything required to manage
|
||||
* the receipt of serialized data via a request object.
|
||||
*/
|
||||
template<typename T>
|
||||
struct serialized_irecv_data {
|
||||
serialized_irecv_data(const communicator& comm, T& value)
|
||||
: m_ia(comm), m_value(value) {}
|
||||
|
||||
void deserialize(status& stat)
|
||||
{
|
||||
m_ia >> m_value;
|
||||
stat.m_count = 1;
|
||||
}
|
||||
|
||||
std::size_t m_count;
|
||||
packed_iarchive m_ia;
|
||||
T& m_value;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct serialized_irecv_data<packed_iarchive>
|
||||
{
|
||||
serialized_irecv_data(communicator const&, packed_iarchive& ia) : m_ia(ia) { }
|
||||
|
||||
void deserialize(status&) { /* Do nothing. */ }
|
||||
|
||||
std::size_t m_count;
|
||||
packed_iarchive& m_ia;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal data structure that stores everything required to manage
|
||||
* the receipt of an array of serialized data via a request object.
|
||||
*/
|
||||
template<typename T>
|
||||
struct serialized_array_irecv_data
|
||||
{
|
||||
serialized_array_irecv_data(const communicator& comm, T* values, int n)
|
||||
: m_count(0), m_ia(comm), m_values(values), m_nb(n) {}
|
||||
|
||||
void deserialize(status& stat);
|
||||
|
||||
std::size_t m_count;
|
||||
packed_iarchive m_ia;
|
||||
T* m_values;
|
||||
int m_nb;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void serialized_array_irecv_data<T>::deserialize(status& stat)
|
||||
{
|
||||
T* v = m_values;
|
||||
T* end = m_values+m_nb;
|
||||
while (v < end) {
|
||||
m_ia >> *v++;
|
||||
}
|
||||
stat.m_count = m_nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal data structure that stores everything required to manage
|
||||
* the receipt of an array of primitive data but unknown size.
|
||||
* Such an array can have been send with blocking operation and so must
|
||||
* be compatible with the (size_t,raw_data[]) format.
|
||||
*/
|
||||
template<typename T, class A>
|
||||
struct dynamic_array_irecv_data
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(is_mpi_datatype<T>::value, "Can only be specialized for MPI datatypes.");
|
||||
|
||||
dynamic_array_irecv_data(std::vector<T,A>& values)
|
||||
: m_count(-1), m_values(values) {}
|
||||
|
||||
std::size_t m_count;
|
||||
std::vector<T,A>& m_values;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_irecv_data<const skeleton_proxy<T> >
|
||||
{
|
||||
serialized_irecv_data(const communicator& comm, skeleton_proxy<T> proxy)
|
||||
: m_isa(comm), m_ia(m_isa.get_skeleton()), m_proxy(proxy) { }
|
||||
|
||||
void deserialize(status& stat)
|
||||
{
|
||||
m_isa >> m_proxy.object;
|
||||
stat.m_count = 1;
|
||||
}
|
||||
|
||||
std::size_t m_count;
|
||||
packed_skeleton_iarchive m_isa;
|
||||
packed_iarchive& m_ia;
|
||||
skeleton_proxy<T> m_proxy;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_irecv_data<skeleton_proxy<T> >
|
||||
: public serialized_irecv_data<const skeleton_proxy<T> >
|
||||
{
|
||||
typedef serialized_irecv_data<const skeleton_proxy<T> > inherited;
|
||||
|
||||
serialized_irecv_data(const communicator& comm, const skeleton_proxy<T>& proxy)
|
||||
: inherited(comm, proxy) { }
|
||||
};
|
||||
}
|
||||
|
||||
#if BOOST_MPI_VERSION >= 3
|
||||
template<class Data>
|
||||
class request::probe_handler
|
||||
: public request::handler,
|
||||
protected Data {
|
||||
|
||||
protected:
|
||||
template<typename I1>
|
||||
probe_handler(communicator const& comm, int source, int tag, I1& i1)
|
||||
: Data(comm, i1),
|
||||
m_comm(comm),
|
||||
m_source(source),
|
||||
m_tag(tag) {}
|
||||
// no variadic template for now
|
||||
template<typename I1, typename I2>
|
||||
probe_handler(communicator const& comm, int source, int tag, I1& i1, I2& i2)
|
||||
: Data(comm, i1, i2),
|
||||
m_comm(comm),
|
||||
m_source(source),
|
||||
m_tag(tag) {}
|
||||
|
||||
public:
|
||||
bool active() const { return m_source != MPI_PROC_NULL; }
|
||||
optional<MPI_Request&> trivial() { return boost::none; }
|
||||
void cancel() { m_source = MPI_PROC_NULL; }
|
||||
|
||||
status wait() {
|
||||
MPI_Message msg;
|
||||
status stat;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Mprobe, (m_source,m_tag,m_comm,&msg,&stat.m_status));
|
||||
return unpack(msg, stat);
|
||||
}
|
||||
|
||||
optional<status> test() {
|
||||
status stat;
|
||||
int flag = 0;
|
||||
MPI_Message msg;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Improbe, (m_source,m_tag,m_comm,&flag,&msg,&stat.m_status));
|
||||
if (flag) {
|
||||
return unpack(msg, stat);
|
||||
} else {
|
||||
return optional<status>();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class request;
|
||||
|
||||
status unpack(MPI_Message& msg, status& stat) {
|
||||
int count;
|
||||
MPI_Datatype datatype = this->Data::datatype();
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Get_count, (&stat.m_status, datatype, &count));
|
||||
this->Data::resize(count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Mrecv, (this->Data::buffer(), count, datatype, &msg, &stat.m_status));
|
||||
this->Data::deserialize();
|
||||
m_source = MPI_PROC_NULL;
|
||||
stat.m_count = 1;
|
||||
return stat;
|
||||
}
|
||||
|
||||
communicator const& m_comm;
|
||||
int m_source;
|
||||
int m_tag;
|
||||
};
|
||||
#endif // BOOST_MPI_VERSION >= 3
|
||||
|
||||
namespace detail {
|
||||
template<class A>
|
||||
struct dynamic_primitive_array_data {
|
||||
dynamic_primitive_array_data(communicator const&, A& arr) : m_buffer(arr) {}
|
||||
|
||||
void* buffer() { return m_buffer.data(); }
|
||||
void resize(std::size_t sz) { m_buffer.resize(sz); }
|
||||
void deserialize() {}
|
||||
MPI_Datatype datatype() { return get_mpi_datatype<typename A::value_type>(); }
|
||||
|
||||
A& m_buffer;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_data {
|
||||
serialized_data(communicator const& comm, T& value) : m_archive(comm), m_value(value) {}
|
||||
|
||||
void* buffer() { return m_archive.address(); }
|
||||
void resize(std::size_t sz) { m_archive.resize(sz); }
|
||||
void deserialize() { m_archive >> m_value; }
|
||||
MPI_Datatype datatype() { return MPI_PACKED; }
|
||||
|
||||
packed_iarchive m_archive;
|
||||
T& m_value;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct serialized_data<packed_iarchive> {
|
||||
serialized_data(communicator const& comm, packed_iarchive& ar) : m_archive(ar) {}
|
||||
|
||||
void* buffer() { return m_archive.address(); }
|
||||
void resize(std::size_t sz) { m_archive.resize(sz); }
|
||||
void deserialize() {}
|
||||
MPI_Datatype datatype() { return MPI_PACKED; }
|
||||
|
||||
packed_iarchive& m_archive;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_data<const skeleton_proxy<T> > {
|
||||
serialized_data(communicator const& comm, skeleton_proxy<T> skel)
|
||||
: m_proxy(skel),
|
||||
m_archive(comm) {}
|
||||
|
||||
void* buffer() { return m_archive.get_skeleton().address(); }
|
||||
void resize(std::size_t sz) { m_archive.get_skeleton().resize(sz); }
|
||||
void deserialize() { m_archive >> m_proxy.object; }
|
||||
MPI_Datatype datatype() { return MPI_PACKED; }
|
||||
|
||||
skeleton_proxy<T> m_proxy;
|
||||
packed_skeleton_iarchive m_archive;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_data<skeleton_proxy<T> >
|
||||
: public serialized_data<const skeleton_proxy<T> > {
|
||||
typedef serialized_data<const skeleton_proxy<T> > super;
|
||||
serialized_data(communicator const& comm, skeleton_proxy<T> skel)
|
||||
: super(comm, skel) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct serialized_array_data {
|
||||
serialized_array_data(communicator const& comm, T* values, int nb)
|
||||
: m_archive(comm), m_values(values), m_nb(nb) {}
|
||||
|
||||
void* buffer() { return m_archive.address(); }
|
||||
void resize(std::size_t sz) { m_archive.resize(sz); }
|
||||
void deserialize() {
|
||||
T* end = m_values + m_nb;
|
||||
T* v = m_values;
|
||||
while (v != end) {
|
||||
m_archive >> *v++;
|
||||
}
|
||||
}
|
||||
MPI_Datatype datatype() { return MPI_PACKED; }
|
||||
|
||||
packed_iarchive m_archive;
|
||||
T* m_values;
|
||||
int m_nb;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class BOOST_MPI_DECL request::legacy_handler : public request::handler {
|
||||
public:
|
||||
legacy_handler(communicator const& comm, int source, int tag);
|
||||
|
||||
void cancel() {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (m_requests[i] != MPI_REQUEST_NULL) {
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Cancel, (m_requests+i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool active() const;
|
||||
optional<MPI_Request&> trivial();
|
||||
|
||||
MPI_Request m_requests[2];
|
||||
communicator m_comm;
|
||||
int m_source;
|
||||
int m_tag;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class request::legacy_serialized_handler
|
||||
: public request::legacy_handler,
|
||||
protected detail::serialized_irecv_data<T> {
|
||||
public:
|
||||
typedef detail::serialized_irecv_data<T> extra;
|
||||
legacy_serialized_handler(communicator const& comm, int source, int tag, T& value)
|
||||
: legacy_handler(comm, source, tag),
|
||||
extra(comm, value) {
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(&this->extra::m_count, 1,
|
||||
get_mpi_datatype(this->extra::m_count),
|
||||
source, tag, comm, m_requests+0));
|
||||
|
||||
}
|
||||
|
||||
status wait() {
|
||||
status stat;
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Wait for the count message to complete
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests, &stat.m_status));
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_ia.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(this->extra::m_ia.address(), this->extra::m_ia.size(), MPI_PACKED,
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
}
|
||||
|
||||
// Wait until we have received the entire message
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests + 1, &stat.m_status));
|
||||
|
||||
this->deserialize(stat);
|
||||
return stat;
|
||||
}
|
||||
|
||||
optional<status> test() {
|
||||
status stat;
|
||||
int flag = 0;
|
||||
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Check if the count message has completed
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_ia.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(this->extra::m_ia.address(), this->extra::m_ia.size(),MPI_PACKED,
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
} else
|
||||
return optional<status>(); // We have not finished yet
|
||||
}
|
||||
|
||||
// Check if we have received the message data
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests + 1, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
this->deserialize(stat);
|
||||
return stat;
|
||||
} else
|
||||
return optional<status>();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class request::legacy_serialized_array_handler
|
||||
: public request::legacy_handler,
|
||||
protected detail::serialized_array_irecv_data<T> {
|
||||
typedef detail::serialized_array_irecv_data<T> extra;
|
||||
|
||||
public:
|
||||
legacy_serialized_array_handler(communicator const& comm, int source, int tag, T* values, int n)
|
||||
: legacy_handler(comm, source, tag),
|
||||
extra(comm, values, n) {
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(&this->extra::m_count, 1,
|
||||
get_mpi_datatype(this->extra::m_count),
|
||||
source, tag, comm, m_requests+0));
|
||||
}
|
||||
|
||||
status wait() {
|
||||
status stat;
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Wait for the count message to complete
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests, &stat.m_status));
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_ia.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(this->extra::m_ia.address(), this->extra::m_ia.size(), MPI_PACKED,
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
}
|
||||
|
||||
// Wait until we have received the entire message
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests + 1, &stat.m_status));
|
||||
|
||||
this->deserialize(stat);
|
||||
return stat;
|
||||
}
|
||||
|
||||
optional<status> test() {
|
||||
status stat;
|
||||
int flag = 0;
|
||||
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Check if the count message has completed
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_ia.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(this->extra::m_ia.address(), this->extra::m_ia.size(),MPI_PACKED,
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
} else
|
||||
return optional<status>(); // We have not finished yet
|
||||
}
|
||||
|
||||
// Check if we have received the message data
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests + 1, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
this->deserialize(stat);
|
||||
return stat;
|
||||
} else
|
||||
return optional<status>();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, class A>
|
||||
class request::legacy_dynamic_primitive_array_handler
|
||||
: public request::legacy_handler,
|
||||
protected detail::dynamic_array_irecv_data<T,A>
|
||||
{
|
||||
typedef detail::dynamic_array_irecv_data<T,A> extra;
|
||||
|
||||
public:
|
||||
legacy_dynamic_primitive_array_handler(communicator const& comm, int source, int tag, std::vector<T,A>& values)
|
||||
: legacy_handler(comm, source, tag),
|
||||
extra(values) {
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(&this->extra::m_count, 1,
|
||||
get_mpi_datatype(this->extra::m_count),
|
||||
source, tag, comm, m_requests+0));
|
||||
}
|
||||
|
||||
status wait() {
|
||||
status stat;
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Wait for the count message to complete
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests, &stat.m_status));
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_values.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(detail::c_data(this->extra::m_values), this->extra::m_values.size(), get_mpi_datatype<T>(),
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
}
|
||||
// Wait until we have received the entire message
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Wait,
|
||||
(m_requests + 1, &stat.m_status));
|
||||
return stat;
|
||||
}
|
||||
|
||||
optional<status> test() {
|
||||
status stat;
|
||||
int flag = 0;
|
||||
|
||||
if (m_requests[1] == MPI_REQUEST_NULL) {
|
||||
// Check if the count message has completed
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
// Resize our buffer and get ready to receive its data
|
||||
this->extra::m_values.resize(this->extra::m_count);
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(detail::c_data(this->extra::m_values), this->extra::m_values.size(), get_mpi_datatype<T>(),
|
||||
stat.source(), stat.tag(),
|
||||
MPI_Comm(m_comm), m_requests + 1));
|
||||
} else
|
||||
return optional<status>(); // We have not finished yet
|
||||
}
|
||||
|
||||
// Check if we have received the message data
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test,
|
||||
(m_requests + 1, &flag, &stat.m_status));
|
||||
if (flag) {
|
||||
return stat;
|
||||
} else
|
||||
return optional<status>();
|
||||
}
|
||||
};
|
||||
|
||||
class BOOST_MPI_DECL request::trivial_handler : public request::handler {
|
||||
|
||||
public:
|
||||
trivial_handler();
|
||||
|
||||
status wait();
|
||||
optional<status> test();
|
||||
void cancel();
|
||||
|
||||
bool active() const;
|
||||
optional<MPI_Request&> trivial();
|
||||
|
||||
private:
|
||||
friend class request;
|
||||
MPI_Request m_request;
|
||||
};
|
||||
|
||||
class request::dynamic_handler : public request::handler {
|
||||
dynamic_handler();
|
||||
|
||||
status wait();
|
||||
optional<status> test();
|
||||
void cancel();
|
||||
|
||||
bool active() const;
|
||||
optional<MPI_Request&> trivial();
|
||||
|
||||
private:
|
||||
friend class request;
|
||||
MPI_Request m_requests[2];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
request request::make_serialized(communicator const& comm, int source, int tag, T& value) {
|
||||
#if defined(BOOST_MPI_USE_IMPROBE)
|
||||
return request(new probe_handler<detail::serialized_data<T> >(comm, source, tag, value));
|
||||
#else
|
||||
return request(new legacy_serialized_handler<T>(comm, source, tag, value));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request request::make_serialized_array(communicator const& comm, int source, int tag, T* values, int n) {
|
||||
#if defined(BOOST_MPI_USE_IMPROBE)
|
||||
return request(new probe_handler<detail::serialized_array_data<T> >(comm, source, tag, values, n));
|
||||
#else
|
||||
return request(new legacy_serialized_array_handler<T>(comm, source, tag, values, n));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T, class A>
|
||||
request request::make_dynamic_primitive_array_recv(communicator const& comm, int source, int tag,
|
||||
std::vector<T,A>& values) {
|
||||
#if defined(BOOST_MPI_USE_IMPROBE)
|
||||
return request(new probe_handler<detail::dynamic_primitive_array_data<std::vector<T,A> > >(comm,source,tag,values));
|
||||
#else
|
||||
return request(new legacy_dynamic_primitive_array_handler<T,A>(comm, source, tag, values));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request
|
||||
request::make_trivial_send(communicator const& comm, int dest, int tag, T const* values, int n) {
|
||||
trivial_handler* handler = new trivial_handler;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Isend,
|
||||
(const_cast<T*>(values), n,
|
||||
get_mpi_datatype<T>(),
|
||||
dest, tag, comm, &handler->m_request));
|
||||
return request(handler);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request
|
||||
request::make_trivial_send(communicator const& comm, int dest, int tag, T const& value) {
|
||||
return make_trivial_send(comm, dest, tag, &value, 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request
|
||||
request::make_trivial_recv(communicator const& comm, int dest, int tag, T* values, int n) {
|
||||
trivial_handler* handler = new trivial_handler;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(values, n,
|
||||
get_mpi_datatype<T>(),
|
||||
dest, tag, comm, &handler->m_request));
|
||||
return request(handler);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
request
|
||||
request::make_trivial_recv(communicator const& comm, int dest, int tag, T& value) {
|
||||
return make_trivial_recv(comm, dest, tag, &value, 1);
|
||||
}
|
||||
|
||||
template<typename T, class A>
|
||||
request request::make_dynamic_primitive_array_send(communicator const& comm, int dest, int tag,
|
||||
std::vector<T,A> const& values) {
|
||||
#if defined(BOOST_MPI_USE_IMPROBE)
|
||||
return make_trivial_send(comm, dest, tag, values.data(), values.size());
|
||||
#else
|
||||
{
|
||||
// non blocking recv by legacy_dynamic_primitive_array_handler
|
||||
// blocking recv by status recv_vector(source,tag,value,primitive)
|
||||
boost::shared_ptr<std::size_t> size(new std::size_t(values.size()));
|
||||
dynamic_handler* handler = new dynamic_handler;
|
||||
request req(handler);
|
||||
req.preserve(size);
|
||||
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Isend,
|
||||
(size.get(), 1,
|
||||
get_mpi_datatype(*size),
|
||||
dest, tag, comm, handler->m_requests+0));
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Isend,
|
||||
(const_cast<T*>(values.data()), *size,
|
||||
get_mpi_datatype<T>(),
|
||||
dest, tag, comm, handler->m_requests+1));
|
||||
return req;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
request::legacy_handler::legacy_handler(communicator const& comm, int source, int tag)
|
||||
: m_comm(comm),
|
||||
m_source(source),
|
||||
m_tag(tag)
|
||||
{
|
||||
m_requests[0] = MPI_REQUEST_NULL;
|
||||
m_requests[1] = MPI_REQUEST_NULL;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPI_REQUEST_HANDLERS_HPP
|
||||
@@ -0,0 +1,50 @@
|
||||
// (C) Copyright 2005 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_TEXT_SKELETON_OARCHIVE_HPP
|
||||
#define BOOST_MPI_TEXT_SKELETON_OARCHIVE_HPP
|
||||
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/mpi/detail/forward_skeleton_oarchive.hpp>
|
||||
#include <boost/mpi/detail/ignore_oprimitive.hpp>
|
||||
#include <boost/archive/detail/register_archive.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
// an archive that writes a text skeleton into a stream
|
||||
|
||||
class text_skeleton_oarchive
|
||||
: public detail::ignore_oprimitive,
|
||||
public detail::forward_skeleton_oarchive<text_skeleton_oarchive,boost::archive::text_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_)
|
||||
, skeleton_archive_(s,flags)
|
||||
{}
|
||||
|
||||
private:
|
||||
boost::archive::text_oarchive skeleton_archive_;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
typedef boost::mpi::detail::forward_skeleton_oarchive<boost::mpi::text_skeleton_oarchive,boost::archive::text_oarchive> type3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
// required by export
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::text_skeleton_oarchive)
|
||||
BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::detail::type3)
|
||||
|
||||
|
||||
#endif // BOOST_MPI_TEXT_SKELETON_OARCHIVE_HPP
|
||||
Reference in New Issue
Block a user