Update of /cvsroot/boost/boost/boost/parallel/mpi/detail
In directory 
sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv657/boost/parallel/mpi/detail

Added Files:
        broadcast_sc.hpp communicator_sc.hpp computation_tree.hpp 
        content_oarchive.hpp forward_iprimitive.hpp 
        forward_oprimitive.hpp forward_skeleton_iarchive.hpp 
        forward_skeleton_oarchive.hpp ignore_iprimitive.hpp 
        ignore_oprimitive.hpp ignore_skeleton_oarchive.hpp 
        mpi_datatype_cache.hpp mpi_datatype_oarchive.hpp 
        mpi_datatype_primitive.hpp packed_iprimitive.hpp 
        packed_oprimitive.hpp point_to_point.hpp 
        text_skeleton_oarchive.hpp 
Log Message:
Import Boost.MPI with the beginnings of a BBv2-based build system

--- NEW FILE: broadcast_sc.hpp ---
// 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_PARALLEL_MPI_BROADCAST_SC_HPP
#define BOOST_PARALLEL_MPI_BROADCAST_SC_HPP

namespace boost { namespace parallel { namespace mpi {

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);
}

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;
  }
}

} } } // end namespace boost::parallel::mpi

#endif // BOOST_PARALLEL_MPI_BROADCAST_SC_HPP

--- NEW FILE: communicator_sc.hpp ---
// 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_PARALLEL_MPI_COMMUNICATOR_SC_HPP
#define BOOST_PARALLEL_MPI_COMMUNICATOR_SC_HPP

namespace boost { namespace parallel { 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.m_data = archive;
  return result;
}

namespace detail {
  template<typename T>
  struct serialized_irecv_data<const skeleton_proxy<T> >
  {
    serialized_irecv_data(const communicator& comm, int source, int tag, 
                          skeleton_proxy<T> proxy)
      : comm(comm), source(source), tag(tag), isa(comm), 
        ia(isa.get_skeleton()), proxy(proxy) { }

    void deserialize(status& stat) 
    { 
      isa >> proxy.object;
      stat.m_count = 1;
    }

    communicator comm;
    int source;
    int tag;
    std::size_t count;
    packed_skeleton_iarchive isa;
    packed_iarchive& ia;
    skeleton_proxy<T> 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, int source, int tag, 
                          const skeleton_proxy<T>& proxy)
      : inherited(comm, source, tag, proxy) { }
  };
}

} } } // end namespace boost::parallel::mpi

#endif // BOOST_PARALLEL_MPI_COMMUNICATOR_SC_HPP


--- NEW FILE: computation_tree.hpp ---
// 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_PARALLEL_MPI_COMPUTATION_TREE_HPP
#define BOOST_PARALLEL_MPI_COMPUTATION_TREE_HPP

namespace boost { namespace parallel { 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::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_COMPUTATION_TREE_HPP

--- NEW FILE: content_oarchive.hpp ---
// (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_PARALLEL_MPI_DETAIL_CONTENT_OARCHIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_CONTENT_OARCHIVE_HPP

#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/parallel/mpi/detail/ignore_skeleton_oarchive.hpp>
#include <boost/parallel/mpi/detail/mpi_datatype_primitive.hpp>
#include <boost/parallel/mpi/datatype.hpp>

namespace boost { namespace parallel { 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 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::parallel::mpi

#endif // BOOST_PARALLEL_MPI_DETAIL_CONTENT_OARCHIVE_HPP

--- NEW FILE: forward_iprimitive.hpp ---
// (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_PARALLEL_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP

namespace boost { namespace parallel { 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<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::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_FORWARD_IPRIMITIVE_HPP

--- NEW FILE: forward_oprimitive.hpp ---
// (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_PARALLEL_MPI_DETAIL_FORWARD_OPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_FORWARD_OPRIMITIVE_HPP

#include <boost/config.hpp>
#include <boost/serialization/array.hpp>

namespace boost { namespace parallel { 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<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::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_FORWARD_OPRIMITIVE_HPP

--- NEW FILE: forward_skeleton_iarchive.hpp ---
// (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_PARALLEL_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_FORWARD_SKELETON_IARCHIVE_HPP

#include <boost/pfto.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/array/iarchive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/iarchive.hpp>

namespace boost { namespace parallel { namespace mpi { namespace detail {

template<class Archive, class ImplementationArchive>
class forward_skeleton_iarchive 
  : public archive::array::iarchive<Archive>
{
public:

    typedef ImplementationArchive implementation_archive_type;
        
    forward_skeleton_iarchive(implementation_archive_type& ar) 
          : archive::array::iarchive<Archive>(archive::no_header),
            implementation_archive(ar)
        {
        }
                
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
    friend class archive::detail::interface_iarchive<Archive>;
    friend class archive::load_access;
protected:
#endif

    // intermediate level to support override of operators
    // for templates in the absence of partial function 
    // template ordering
    template<class T>
    void load_override(T & t, BOOST_PFTO int)
    {
        archive::load(* this->This(), t);
    }
        
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
    void load_override(T & t , int)             \
        {                                           \
          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::tracking_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_name_type)
BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(serialization::collection_size_type)

#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::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_FORWARD_STRUCTURE_IARCHIVE_HPP

--- NEW FILE: forward_skeleton_oarchive.hpp ---
// (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_PARALLEL_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_FORWARD_SKELETON_OARCHIVE_HPP

#include <boost/pfto.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/array/oarchive.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/archive/array/oarchive.hpp>

namespace boost { namespace parallel { namespace mpi { namespace detail {

template<class Archive, class ImplementationArchive>
class forward_skeleton_oarchive 
  : public archive::array::oarchive<Archive>
{
public:

    typedef ImplementationArchive implementation_archive_type;
        
    forward_skeleton_oarchive(implementation_archive_type& ar) 
          : archive::array::oarchive<Archive>(archive::no_header),
                implementation_archive(ar)
        {
        }
                
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
    friend class archive::detail::interface_oarchive<Archive>;
    friend class archive::save_access;
protected:
#endif

    // intermediate level to support override of operators
    // for templates in the absence of partial function 
    // template ordering
    template<class T>
    void save_override(T const& t, BOOST_PFTO int)
    {
        archive::save(* this->This(), t);
    }
        
#define BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(T) \
    void save_override(T const & t , int)       \
        {                                           \
          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)


#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::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_FORWARD_STRUCTURE_OARCHIVE_HPP

--- NEW FILE: ignore_iprimitive.hpp ---
// (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_PARALLEL_MPI_DETAIL_IGNORE_IPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_IGNORE_IPRIMITIVE_HPP

#include <boost/config.hpp>
#include <boost/parallel/mpi/datatype.hpp>
#include <boost/serialization/array.hpp>


namespace boost { namespace parallel { 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<T> &, unsigned int )
    {}

    typedef is_mpi_datatype<mpl::_1> use_array_optimization;

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    friend class archive::load_access;
protected:
#else
public:
#endif

        /// don't do anything when loading primitive types
    template<class T>
    void load(T & t)
        {
    }
};

} } } } // end namespace boost::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_IGNORE_IPRIMITIVE_HPP

--- NEW FILE: ignore_oprimitive.hpp ---
// (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_PARALLEL_MPI_DETAIL_IGNORE_OPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_IGNORE_OPRIMITIVE_HPP

#include <boost/config.hpp>
#include <boost/parallel/mpi/datatype.hpp>
#include <boost/serialization/array.hpp>

namespace boost { namespace parallel { 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<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 & t)
    {
    }
};

} } } } // end namespace boost::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_IGNORE_OPRIMITIVE_HPP

--- NEW FILE: ignore_skeleton_oarchive.hpp ---
// (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_PARALLEL_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP

#include <boost/pfto.hpp>

#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/array/oarchive.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/oserializer.hpp>
#include <boost/serialization/collection_size_type.hpp>

namespace boost { namespace parallel { namespace mpi { namespace detail {

template<class Archive>
class ignore_skeleton_oarchive 
  : public archive::array::oarchive<Archive>
{
public:
        
    ignore_skeleton_oarchive()
          : archive::array::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

    // intermediate level to support override of operators
    // for templates in the absence of partial function 
    // template ordering
    template<class T>
    void save_override(T const& t, BOOST_PFTO int)
    {
        archive::save(* this->This(), t);
    }
        
#define BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(T) \
    void save_override(T const & t , int)      \
        {}                                         \

BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::class_id_optional_type)
BOOST_ARCHIVE_IGNORE_IMPLEMENTATION(archive::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)

#undef BOOST_ARCHIVE_IGNORE_IMPLEMENTATION
};


} } } } // end namespace boost::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_IGNORE_SKELETON_OARCHIVE_HPP

--- NEW FILE: mpi_datatype_cache.hpp ---
// (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_PARALLEL_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP

#include <boost/parallel/mpi/datatype_fwd.hpp>
#include <boost/parallel/mpi/detail/mpi_datatype_oarchive.hpp>
#include <boost/parallel/mpi/exception.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/noncopyable.hpp>
#include <map>
#include <typeinfo>

namespace boost { namespace parallel { 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 mpi_datatype_map
 : private std::map<std::type_info const*,MPI_Datatype,type_info_compare>,
   public boost::noncopyable
{
public:
  mpi_datatype_map()
  {}

  ~mpi_datatype_map()
  {
    // do not free after call to MPI_FInalize
    int finalized=0;
    BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
    if (!finalized)
      free();
  }

  template <class T>
  MPI_Datatype datatype(const T& = T(), typename 
boost::enable_if<is_mpi_builtin_datatype<T> >::type* =0)
  {
    return get_mpi_datatype<T>();
  }

  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);
    const_iterator it = find(t);
    if(it ==end())
    {
      // need to create a type
      mpi_datatype_oarchive ar(x);
      insert(std::make_pair(t,ar.get_mpi_datatype()));
      it = find(t);
    }

  return it->second;
  }

private:
  // free all MPI data types
  void free()
  {
    // ignore errors in the destructor
    for (iterator it=begin(); it !=end(); ++it)
          MPI_Type_free(&(it->second));
  }

};

extern mpi_datatype_map mpi_datatype_cache;

} } } } // end namespace boost::parallel::mpi::detail


#endif // BOOST_PARALLEL_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP

--- NEW FILE: mpi_datatype_oarchive.hpp ---
// (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_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OARCHIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OARCHIVE_HPP

#include <boost/archive/detail/oserializer.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/basic_archive.hpp>
#include <boost/parallel/mpi/detail/ignore_skeleton_oarchive.hpp>
#include <boost/parallel/mpi/detail/mpi_datatype_primitive.hpp>
#include <boost/parallel/mpi/datatype_fwd.hpp>
#include <boost/mpl/assert.hpp>

namespace boost { namespace parallel { 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
        }
};

} } } } // end namespace boost::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OARCHIVE_HPP

--- NEW FILE: mpi_datatype_primitive.hpp ---
// (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_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP

#include <mpi.h>
#include <cstddef> // size_t

#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
    using ::size_t;
} // namespace std
#endif

#include <boost/parallel/mpi/datatype_fwd.hpp>
#include <boost/parallel/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 parallel { 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()
    {
      BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
    }

    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<T> const& x, unsigned int /* version 
*/)
    {
      if (x.count())
        save_impl(x.address(), 
boost::parallel::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)
      {
        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_
                    ));

        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::parallel::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;
      BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));

      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::parallel::mpi::detail


#endif // BOOST_PARALLEL_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP

--- NEW FILE: packed_iprimitive.hpp ---
// (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_PARALLEL_MPI_PACKED_IPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_PACKED_IPRIMITIVE_HPP

#include <mpi.h>
#include <iostream>
#include <cstddef> // size_t
#include <boost/config.hpp>
#include <boost/parallel/mpi/datatype.hpp>
#include <boost/parallel/mpi/exception.hpp>
#include <boost/assert.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <vector>
#include <boost/parallel/mpi/allocator.hpp>

namespace boost { namespace parallel { namespace mpi {

/// deserialization using MPI_Unpack

class 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 &buffer_[0];
    }

    void const* address () const
    {
      return &buffer_[0];
    }

    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<T> & x, unsigned int /* file_version 
*/)
    {
      if (x.count())
        load_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
    }

    typedef is_mpi_datatype<mpl::_1> use_array_optimization;

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    friend class archive::load_access;
protected:
#else
public:
#endif

    // default saving of primitives.
    template<class T>
    void load( T & t)
    {
        load_impl(&t, get_mpi_datatype(t), 1);
    }

    void load( std::string & s)
    {
       unsigned int l;
        load(l);
        // borland de-allocator fixup
        #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
        if(NULL != s.data())
        #endif
        s.resize(l);
        // note breaking a rule here - could be a problem on some platform
        load_impl(const_cast<char *>(s.data()),MPI_CHAR,l);
        }

private:

    void load_impl(void * p, MPI_Datatype t, int l)
        {
        BOOST_MPI_CHECK_RESULT(MPI_Unpack,
        (const_cast<char*>(boost::serialization::detail::get_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::parallel::mpi

#endif // BOOST_PARALLEL_MPI_PACKED_IPRIMITIVE_HPP

--- NEW FILE: packed_oprimitive.hpp ---
// (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_PARALLEL_MPI_PACKED_OPRIMITIVE_HPP
#define BOOST_PARALLEL_MPI_PACKED_OPRIMITIVE_HPP

#include <mpi.h>
#include <iostream>
#include <cstddef> // size_t
#include <boost/config.hpp>

#include <boost/parallel/mpi/datatype.hpp>
#include <boost/parallel/mpi/exception.hpp>
#include <boost/serialization/detail/get_data.hpp>
#include <boost/serialization/array.hpp>
#include <boost/assert.hpp>
#include <vector>
#include <boost/parallel/mpi/allocator.hpp>

namespace boost { namespace parallel { namespace mpi {

/// serialization using MPI::Pack

class 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 &buffer_[0];
    }

    const std::size_t& size() const
    {
      return size_ = buffer_.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<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>(), 1);
    }

        void save(const std::string &s)
        {
      unsigned int l = static_cast<unsigned int>(s.size());
      save(l);
      save_impl(s.data(),MPI_CHAR,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, 
boost::serialization::detail::get_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);
        }

  buffer_type& buffer_;
  mutable std::size_t size_;
  MPI_Comm comm;
};

} } } // end namespace boost::parallel::mpi

#endif // BOOST_PARALLEL_MPI_PACKED_OPRIMITIVE_HPP

--- NEW FILE: point_to_point.hpp ---
// 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_PARALLEL_MPI_DETAIL_POINT_TO_POINT_HPP
#define BOOST_PARALLEL_MPI_DETAIL_POINT_TO_POINT_HPP

// For (de-)serializing sends and receives
#include <boost/parallel/mpi/packed_oarchive.hpp>
#include <boost/parallel/mpi/packed_iarchive.hpp>

namespace boost { namespace parallel { namespace mpi { namespace detail {

/** Sends a packed archive using MPI_Send. */
void
packed_archive_send(MPI_Comm 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.
 *
 * @pre num_out_requests >= 2
 */
int
packed_archive_isend(MPI_Comm comm, int dest, int tag,
                     const packed_oarchive& ar,
                     MPI_Request* out_requests, int num_out_requests);

/**
 * \overload
 */
int
packed_archive_isend(MPI_Comm comm, int dest, int tag,
                     const packed_iarchive& ar,
                     MPI_Request* out_requests, int num_out_requests);

/** Receives a packed archive using MPI_Recv. */
void
packed_archive_recv(MPI_Comm comm, int source, int tag, packed_iarchive& ar,
                    MPI_Status& status);

} } } } // end namespace boost::parallel::mpi::detail

#endif // BOOST_PARALLEL_MPI_DETAIL_POINT_TO_POINT_HPP

--- NEW FILE: text_skeleton_oarchive.hpp ---
// (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_PARALLEL_MPI_TEXT_SKELETON_OARCHIVE_HPP
#define BOOST_PARALLEL_MPI_TEXT_SKELETON_OARCHIVE_HPP

#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/parallel/mpi/detail/forward_skeleton_oarchive.hpp>
#include <boost/parallel/mpi/detail/ignore_oprimitive.hpp>
#include <boost/archive/array/oarchive.hpp>

namespace boost { namespace parallel { 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_;
};

} } } // end namespace boost::parallel::mpi


#endif // BOOST_PARALLEL_MPI_TEXT_SKELETON_OARCHIVE_HPP


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to