PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/mpi/detail/mpi_datatype_primitive.hpp

http://hadesmem.googlecode.com/
C++ Header | 128 lines | 86 code | 30 blank | 12 comment | 2 complexity | c4344c7ac457f1e0c5a65645e6d77e29 MD5 | raw file
  1// (C) Copyright 2005 Matthias Troyer
  2
  3// Use, modification and distribution is subject to the Boost Software
  4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5// http://www.boost.org/LICENSE_1_0.txt)
  6
  7//  Authors: Matthias Troyer
  8
  9#ifndef BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
 10#define BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
 11
 12#include <boost/mpi/config.hpp>
 13#include <cstddef> // size_t
 14
 15#include <boost/config.hpp>
 16#if defined(BOOST_NO_STDC_NAMESPACE)
 17namespace std{
 18    using ::size_t;
 19} // namespace std
 20#endif
 21
 22#include <boost/mpi/datatype_fwd.hpp>
 23#include <boost/mpi/exception.hpp>
 24#include <boost/throw_exception.hpp>
 25#include <boost/assert.hpp>
 26#include <boost/mpl/placeholders.hpp>
 27#include <boost/serialization/array.hpp>
 28#include <boost/serialization/detail/get_data.hpp>
 29#include <stdexcept>
 30#include <iostream>
 31#include <vector>
 32
 33namespace boost { namespace mpi { namespace detail {
 34
 35/////////////////////////////////////////////////////////////////////////
 36// class mpi_data_type_oprimitive - creation of custom MPI data types
 37
 38class mpi_datatype_primitive
 39{
 40public:
 41
 42    // trivial default constructor
 43    mpi_datatype_primitive()
 44     : is_committed(false),
 45       origin(0)
 46    {}
 47
 48    mpi_datatype_primitive(void const* orig)
 49     : is_committed(false),
 50       origin()
 51    {
 52      BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
 53    }
 54
 55    void save_binary(void const *address, std::size_t count)
 56    {
 57      save_impl(address,MPI_BYTE,count);
 58    }
 59
 60    // fast saving of arrays of MPI types
 61    template<class T>
 62    void save_array(serialization::array<T> const& x, unsigned int /* version */)
 63    {
 64      if (x.count())
 65        save_impl(x.address(), boost::mpi::get_mpi_datatype(*x.address()), x.count());
 66    }
 67
 68    typedef is_mpi_datatype<mpl::_1> use_array_optimization;
 69
 70    // create and return the custom MPI data type
 71    MPI_Datatype get_mpi_datatype()
 72    {
 73      if (!is_committed)
 74      {
 75        BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
 76                    (
 77                      addresses.size(),
 78                      boost::serialization::detail::get_data(lengths),
 79                      boost::serialization::detail::get_data(addresses),
 80                      boost::serialization::detail::get_data(types),
 81                      &datatype_
 82                    ));
 83
 84        BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_));
 85
 86        is_committed = true;
 87      }
 88
 89      return datatype_;
 90    }
 91
 92    // default saving of primitives.
 93    template<class T>
 94    void save(const T & t)
 95    {
 96        save_impl(&t, boost::mpi::get_mpi_datatype(t), 1);
 97    }
 98
 99private:
100
101    void save_impl(void const * p, MPI_Datatype t, int l)
102    {
103      BOOST_ASSERT ( !is_committed );
104
105      // store address, type and length
106
107      MPI_Aint a;
108      BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
109
110      addresses.push_back(a-origin);
111      types.push_back(t);
112      lengths.push_back(l);
113    }
114
115    std::vector<MPI_Aint> addresses;
116    std::vector<MPI_Datatype> types;
117    std::vector<int> lengths;
118
119    bool is_committed;
120    MPI_Datatype datatype_;
121    MPI_Aint origin;
122};
123
124
125} } } // end namespace boost::mpi::detail
126
127
128#endif // BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP