Initial Commit
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
// (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/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/serialization/array.hpp>
|
||||
#include <boost/serialization/detail/get_data.hpp>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
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 defined(MPI_VERSION) && 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 defined(MPI_VERSION) && MPI_VERSION >= 2
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_create_struct,
|
||||
(
|
||||
addresses.size(),
|
||||
boost::serialization::detail::get_data(lengths),
|
||||
boost::serialization::detail::get_data(addresses),
|
||||
boost::serialization::detail::get_data(types),
|
||||
&datatype_
|
||||
));
|
||||
#else
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
|
||||
(
|
||||
addresses.size(),
|
||||
boost::serialization::detail::get_data(lengths),
|
||||
boost::serialization::detail::get_data(addresses),
|
||||
boost::serialization::detail::get_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 defined(MPI_VERSION) && 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);
|
||||
}
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user