Added boost header
This commit is contained in:
84
test/external/boost/graph/parallel/algorithm.hpp
vendored
Normal file
84
test/external/boost/graph/parallel/algorithm.hpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
#ifndef BOOST_PARALLEL_ALGORITHM_HPP
|
||||
#define BOOST_PARALLEL_ALGORITHM_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace boost { namespace parallel {
|
||||
template<typename BinaryOp>
|
||||
struct is_commutative
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct minimum : std::binary_function<T, T, T>
|
||||
{
|
||||
const T& operator()(const T& x, const T& y) const { return x < y? x : y; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct maximum : std::binary_function<T, T, T>
|
||||
{
|
||||
const T& operator()(const T& x, const T& y) const { return x < y? y : x; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct sum : std::binary_function<T, T, T>
|
||||
{
|
||||
const T operator()(const T& x, const T& y) const { return x + y; }
|
||||
};
|
||||
|
||||
template<typename ProcessGroup, typename InputIterator,
|
||||
typename OutputIterator, typename BinaryOperation>
|
||||
OutputIterator
|
||||
reduce(ProcessGroup pg, typename ProcessGroup::process_id_type root,
|
||||
InputIterator first, InputIterator last, OutputIterator out,
|
||||
BinaryOperation bin_op);
|
||||
|
||||
template<typename ProcessGroup, typename T, typename BinaryOperation>
|
||||
inline T
|
||||
all_reduce(ProcessGroup pg, const T& value, BinaryOperation bin_op)
|
||||
{
|
||||
T result;
|
||||
all_reduce(pg,
|
||||
const_cast<T*>(&value), const_cast<T*>(&value+1),
|
||||
&result, bin_op);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename ProcessGroup, typename T, typename BinaryOperation>
|
||||
inline T
|
||||
scan(ProcessGroup pg, const T& value, BinaryOperation bin_op)
|
||||
{
|
||||
T result;
|
||||
scan(pg,
|
||||
const_cast<T*>(&value), const_cast<T*>(&value+1),
|
||||
&result, bin_op);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename ProcessGroup, typename InputIterator, typename T>
|
||||
void
|
||||
all_gather(ProcessGroup pg, InputIterator first, InputIterator last,
|
||||
std::vector<T>& out);
|
||||
} } // end namespace boost::parallel
|
||||
|
||||
#include <boost/graph/parallel/detail/inplace_all_to_all.hpp>
|
||||
|
||||
#endif // BOOST_PARALLEL_ALGORITHM_HPP
|
||||
42
test/external/boost/graph/parallel/basic_reduce.hpp
vendored
Normal file
42
test/external/boost/graph/parallel/basic_reduce.hpp
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2005 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
#ifndef BOOST_PARALLEL_BASIC_REDUCE_HPP
|
||||
#define BOOST_PARALLEL_BASIC_REDUCE_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace parallel {
|
||||
|
||||
/** Reduction operation used to reconcile differences between local
|
||||
* and remote values for a particular key in a property map. The
|
||||
* type @c T is typically the @c value_type of the property
|
||||
* map. This basic reduction returns a default-constructed @c T as
|
||||
* the default value and always resolves to the remote value.
|
||||
*/
|
||||
template<typename T>
|
||||
struct basic_reduce
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, non_default_resolver = false);
|
||||
|
||||
/// Returns a default-constructed T object
|
||||
template<typename Key>
|
||||
T operator()(const Key&) const { return T(); }
|
||||
|
||||
/// Returns the remote value
|
||||
template<typename Key>
|
||||
const T& operator()(const Key&, const T&, const T& remote) const
|
||||
{ return remote; }
|
||||
};
|
||||
|
||||
} } // end namespace boost::parallel
|
||||
|
||||
#endif // BOOST_PARALLEL_BASIC_REDUCE_HPP
|
||||
45
test/external/boost/graph/parallel/container_traits.hpp
vendored
Normal file
45
test/external/boost/graph/parallel/container_traits.hpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2004-2006 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
//
|
||||
// This file contains traits that describe
|
||||
//
|
||||
#ifndef BOOST_GRAPH_PARALLEL_CONTAINER_TRAITS_HPP
|
||||
#define BOOST_GRAPH_PARALLEL_CONTAINER_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace graph { namespace parallel {
|
||||
|
||||
template<typename T>
|
||||
struct process_group_type
|
||||
{
|
||||
typedef typename T::process_group_type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline typename process_group_type<T>::type
|
||||
process_group(const T& x)
|
||||
{ return x.process_group(); }
|
||||
|
||||
// Helper function that algorithms should use to get the process group
|
||||
// out of a container.
|
||||
template<typename Container>
|
||||
inline typename process_group_type<Container>::type
|
||||
process_group_adl(const Container& container)
|
||||
{
|
||||
return process_group(container);
|
||||
}
|
||||
|
||||
|
||||
} } } // end namespace boost::graph::parallel
|
||||
|
||||
#endif // BOOST_GRAPH_PARALLEL_CONTAINER_TRAITS_HPP
|
||||
78
test/external/boost/graph/parallel/detail/inplace_all_to_all.hpp
vendored
Normal file
78
test/external/boost/graph/parallel/detail/inplace_all_to_all.hpp
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2005 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
#ifndef BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP
|
||||
#define BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
//
|
||||
// Implements the inplace all-to-all communication algorithm.
|
||||
//
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost { namespace parallel {
|
||||
|
||||
template<typename ProcessGroup, typename T>
|
||||
// where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>}
|
||||
void
|
||||
inplace_all_to_all(ProcessGroup pg,
|
||||
const std::vector<std::vector<T> >& outgoing,
|
||||
std::vector<std::vector<T> >& incoming)
|
||||
{
|
||||
typedef typename std::vector<T>::size_type size_type;
|
||||
|
||||
typedef typename ProcessGroup::process_size_type process_size_type;
|
||||
typedef typename ProcessGroup::process_id_type process_id_type;
|
||||
|
||||
process_size_type p = num_processes(pg);
|
||||
|
||||
// Make sure there are no straggling messages
|
||||
synchronize(pg);
|
||||
|
||||
// Send along the count (always) and the data (if count > 0)
|
||||
for (process_id_type dest = 0; dest < p; ++dest) {
|
||||
if (dest != process_id(pg)) {
|
||||
send(pg, dest, 0, outgoing[dest].size());
|
||||
if (!outgoing[dest].empty())
|
||||
send(pg, dest, 1, &outgoing[dest].front(), outgoing[dest].size());
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all of the data gets transferred
|
||||
synchronize(pg);
|
||||
|
||||
// Receive the sizes and data
|
||||
for (process_id_type source = 0; source < p; ++source) {
|
||||
if (source != process_id(pg)) {
|
||||
size_type size;
|
||||
receive(pg, source, 0, size);
|
||||
incoming[source].resize(size);
|
||||
if (size > 0)
|
||||
receive(pg, source, 1, &incoming[source].front(), size);
|
||||
} else if (&incoming != &outgoing) {
|
||||
incoming[source] = outgoing[source];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ProcessGroup, typename T>
|
||||
// where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>}
|
||||
void
|
||||
inplace_all_to_all(ProcessGroup pg, std::vector<std::vector<T> >& data)
|
||||
{
|
||||
inplace_all_to_all(pg, data, data);
|
||||
}
|
||||
|
||||
} } // end namespace boost::parallel
|
||||
|
||||
#endif // BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP
|
||||
152
test/external/boost/graph/parallel/detail/property_holders.hpp
vendored
Normal file
152
test/external/boost/graph/parallel/detail/property_holders.hpp
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2007 Douglas Gregor and 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
|
||||
//
|
||||
// This file contains helper data structures for use in transmitting
|
||||
// properties. The basic idea is to optimize away any storage for the
|
||||
// properties when no properties are specified.
|
||||
#ifndef BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
|
||||
#define BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/graph/parallel/detail/untracked_pair.hpp>
|
||||
|
||||
namespace boost { namespace detail { namespace parallel {
|
||||
|
||||
/**
|
||||
* This structure contains an instance of @c Property, unless @c
|
||||
* Property is a placeholder for "no property". Always access the
|
||||
* property through @c get_property. Typically used as a base class.
|
||||
*/
|
||||
template<typename Property>
|
||||
struct maybe_store_property
|
||||
{
|
||||
maybe_store_property() {}
|
||||
maybe_store_property(const Property& p) : p(p) {}
|
||||
|
||||
Property& get_property() { return p; }
|
||||
const Property& get_property() const { return p; }
|
||||
|
||||
private:
|
||||
Property p;
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archiver>
|
||||
void serialize(Archiver& ar, const unsigned int /*version*/)
|
||||
{
|
||||
ar & p;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct maybe_store_property<no_property>
|
||||
{
|
||||
maybe_store_property() {}
|
||||
maybe_store_property(no_property) {}
|
||||
|
||||
no_property get_property() const { return no_property(); }
|
||||
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archiver>
|
||||
void serialize(Archiver&, const unsigned int /*version*/) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure is a simple pair that also contains a property.
|
||||
*/
|
||||
template<typename T, typename U, typename Property>
|
||||
class pair_with_property
|
||||
: public boost::parallel::detail::untracked_pair<T, U>
|
||||
, public maybe_store_property<Property>
|
||||
{
|
||||
public:
|
||||
typedef boost::parallel::detail::untracked_pair<T, U> pair_base;
|
||||
typedef maybe_store_property<Property> property_base;
|
||||
|
||||
pair_with_property() { }
|
||||
|
||||
pair_with_property(const T& t, const U& u, const Property& property)
|
||||
: pair_base(t, u), property_base(property) { }
|
||||
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archiver>
|
||||
void serialize(Archiver& ar, const unsigned int /*version*/)
|
||||
{
|
||||
ar & boost::serialization::base_object<pair_base>(*this)
|
||||
& boost::serialization::base_object<property_base>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename U, typename Property>
|
||||
inline pair_with_property<T, U, Property>
|
||||
make_pair_with_property(const T& t, const U& u, const Property& property)
|
||||
{
|
||||
return pair_with_property<T, U, Property>(t, u, property);
|
||||
}
|
||||
|
||||
} } } // end namespace boost::parallel::detail
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
template<>
|
||||
struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<no_property> > : mpl::true_ { };
|
||||
|
||||
template<typename Property>
|
||||
struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<Property> >
|
||||
: is_mpi_datatype<Property> { };
|
||||
|
||||
template<typename T, typename U, typename Property>
|
||||
struct is_mpi_datatype<boost::detail::parallel::pair_with_property<T, U, Property> >
|
||||
: boost::mpl::and_<is_mpi_datatype<boost::parallel::detail::untracked_pair<T, U> >,
|
||||
is_mpi_datatype<Property> > { };
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
BOOST_IS_BITWISE_SERIALIZABLE(boost::detail::parallel::maybe_store_property<no_property>)
|
||||
|
||||
namespace boost { namespace serialization {
|
||||
|
||||
template<typename Property>
|
||||
struct is_bitwise_serializable<boost::detail::parallel::maybe_store_property<Property> >
|
||||
: is_bitwise_serializable<Property> { };
|
||||
|
||||
template<typename Property>
|
||||
struct implementation_level<boost::detail::parallel::maybe_store_property<Property> >
|
||||
: mpl::int_<object_serializable> {} ;
|
||||
|
||||
template<typename Property>
|
||||
struct tracking_level<boost::detail::parallel::maybe_store_property<Property> >
|
||||
: mpl::int_<track_never> {} ;
|
||||
|
||||
template<typename T, typename U, typename Property>
|
||||
struct is_bitwise_serializable<
|
||||
boost::detail::parallel::pair_with_property<T, U, Property> >
|
||||
: boost::mpl::and_<is_bitwise_serializable<boost::parallel::detail::untracked_pair<T, U> >,
|
||||
is_bitwise_serializable<Property> > { };
|
||||
|
||||
template<typename T, typename U, typename Property>
|
||||
struct implementation_level<
|
||||
boost::detail::parallel::pair_with_property<T, U, Property> >
|
||||
: mpl::int_<object_serializable> {} ;
|
||||
|
||||
template<typename T, typename U, typename Property>
|
||||
struct tracking_level<
|
||||
boost::detail::parallel::pair_with_property<T, U, Property> >
|
||||
: mpl::int_<track_never> {} ;
|
||||
|
||||
} } // end namespace boost::serialization
|
||||
|
||||
#endif // BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
|
||||
85
test/external/boost/graph/parallel/detail/untracked_pair.hpp
vendored
Normal file
85
test/external/boost/graph/parallel/detail/untracked_pair.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright (C) 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
|
||||
//
|
||||
// This file contains helper data structures for use in transmitting
|
||||
// properties. The basic idea is to optimize away any storage for the
|
||||
// properties when no properties are specified.
|
||||
#ifndef BOOST_PARALLEL_DETAIL_UNTRACKED_PAIR_HPP
|
||||
#define BOOST_PARALLEL_DETAIL_UNTRACKED_PAIR_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <utility> // for std::pair
|
||||
#include <boost/serialization/utility.hpp>
|
||||
|
||||
namespace boost { namespace parallel { namespace detail {
|
||||
|
||||
/**
|
||||
* This structure is like std::pair, with the only difference
|
||||
* that tracking in the serialization library is turned off.
|
||||
*/
|
||||
|
||||
template<typename T, typename U>
|
||||
struct untracked_pair : public std::pair<T,U>
|
||||
{
|
||||
untracked_pair() {}
|
||||
|
||||
untracked_pair(const T& t, const U& u)
|
||||
: std::pair<T,U>(t,u) {}
|
||||
|
||||
template<class T1, class U1>
|
||||
untracked_pair(std::pair<T1,U1> const& p)
|
||||
: std::pair<T,U>(p) {}
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
inline untracked_pair<T, U>
|
||||
make_untracked_pair(const T& t, const U& u)
|
||||
{
|
||||
return untracked_pair<T,U>(t,u);
|
||||
}
|
||||
|
||||
} } } // end namespace boost::parallel::detail
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_mpi_datatype<boost::parallel::detail::untracked_pair<T, U> >
|
||||
: is_mpi_datatype<std::pair<T,U> > {};
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
|
||||
namespace boost { namespace serialization {
|
||||
|
||||
// pair
|
||||
template<class Archive, class F, class S>
|
||||
inline void serialize(
|
||||
Archive & ar,
|
||||
boost::parallel::detail::untracked_pair<F, S> & p,
|
||||
const unsigned int /* file_version */
|
||||
){
|
||||
ar & boost::serialization::make_nvp("first", p.first);
|
||||
ar & boost::serialization::make_nvp("second", p.second);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_bitwise_serializable<
|
||||
boost::parallel::detail::untracked_pair<T, U> >
|
||||
: is_bitwise_serializable<std::pair<T, U> > {};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct implementation_level<boost::parallel::detail::untracked_pair<T, U> >
|
||||
: mpl::int_<object_serializable> {} ;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct tracking_level<boost::parallel::detail::untracked_pair<T, U> >
|
||||
: mpl::int_<track_never> {} ;
|
||||
|
||||
} } // end namespace boost::serialization
|
||||
|
||||
#endif // BOOST_PARALLEL_DETAIL_UNTRACKED_PAIR_HPP
|
||||
615
test/external/boost/graph/parallel/distribution.hpp
vendored
Normal file
615
test/external/boost/graph/parallel/distribution.hpp
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Peter Gottschling
|
||||
// Andrew Lumsdaine
|
||||
#ifndef BOOST_PARALLEL_DISTRIBUTION_HPP
|
||||
#define BOOST_PARALLEL_DISTRIBUTION_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <boost/random/uniform_int.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost { namespace parallel {
|
||||
|
||||
template<typename ProcessGroup, typename SizeType = std::size_t>
|
||||
class variant_distribution
|
||||
{
|
||||
public:
|
||||
typedef typename ProcessGroup::process_id_type process_id_type;
|
||||
typedef typename ProcessGroup::process_size_type process_size_type;
|
||||
typedef SizeType size_type;
|
||||
|
||||
private:
|
||||
struct basic_distribution
|
||||
{
|
||||
virtual ~basic_distribution() {}
|
||||
virtual size_type block_size(process_id_type, size_type) const = 0;
|
||||
virtual process_id_type in_process(size_type) const = 0;
|
||||
virtual size_type local(size_type) const = 0;
|
||||
virtual size_type global(size_type) const = 0;
|
||||
virtual size_type global(process_id_type, size_type) const = 0;
|
||||
virtual void* address() = 0;
|
||||
virtual const void* address() const = 0;
|
||||
virtual const std::type_info& type() const = 0;
|
||||
};
|
||||
|
||||
template<typename Distribution>
|
||||
struct poly_distribution : public basic_distribution
|
||||
{
|
||||
explicit poly_distribution(const Distribution& distribution)
|
||||
: distribution_(distribution) { }
|
||||
|
||||
virtual size_type block_size(process_id_type id, size_type n) const
|
||||
{ return distribution_.block_size(id, n); }
|
||||
|
||||
virtual process_id_type in_process(size_type i) const
|
||||
{ return distribution_(i); }
|
||||
|
||||
virtual size_type local(size_type i) const
|
||||
{ return distribution_.local(i); }
|
||||
|
||||
virtual size_type global(size_type n) const
|
||||
{ return distribution_.global(n); }
|
||||
|
||||
virtual size_type global(process_id_type id, size_type n) const
|
||||
{ return distribution_.global(id, n); }
|
||||
|
||||
virtual void* address() { return &distribution_; }
|
||||
virtual const void* address() const { return &distribution_; }
|
||||
virtual const std::type_info& type() const { return typeid(Distribution); }
|
||||
|
||||
private:
|
||||
Distribution distribution_;
|
||||
};
|
||||
|
||||
public:
|
||||
variant_distribution() { }
|
||||
|
||||
template<typename Distribution>
|
||||
variant_distribution(const Distribution& distribution)
|
||||
: distribution_(new poly_distribution<Distribution>(distribution)) { }
|
||||
|
||||
size_type block_size(process_id_type id, size_type n) const
|
||||
{ return distribution_->block_size(id, n); }
|
||||
|
||||
process_id_type operator()(size_type i) const
|
||||
{ return distribution_->in_process(i); }
|
||||
|
||||
size_type local(size_type i) const
|
||||
{ return distribution_->local(i); }
|
||||
|
||||
size_type global(size_type n) const
|
||||
{ return distribution_->global(n); }
|
||||
|
||||
size_type global(process_id_type id, size_type n) const
|
||||
{ return distribution_->global(id, n); }
|
||||
|
||||
operator bool() const { return distribution_; }
|
||||
|
||||
void clear() { distribution_.reset(); }
|
||||
|
||||
template<typename T>
|
||||
T* as()
|
||||
{
|
||||
if (distribution_->type() == typeid(T))
|
||||
return static_cast<T*>(distribution_->address());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* as() const
|
||||
{
|
||||
if (distribution_->type() == typeid(T))
|
||||
return static_cast<T*>(distribution_->address());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr<basic_distribution> distribution_;
|
||||
};
|
||||
|
||||
struct block
|
||||
{
|
||||
template<typename LinearProcessGroup>
|
||||
explicit block(const LinearProcessGroup& pg, std::size_t n)
|
||||
: id(process_id(pg)), p(num_processes(pg)), n(n) { }
|
||||
|
||||
// If there are n elements in the distributed data structure, returns the number of elements stored locally.
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType n) const
|
||||
{ return (n / p) + ((std::size_t)(n % p) > id? 1 : 0); }
|
||||
|
||||
// If there are n elements in the distributed data structure, returns the number of elements stored on processor ID
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType n) const
|
||||
{ return (n / p) + ((ProcessID)(n % p) > id? 1 : 0); }
|
||||
|
||||
// Returns the processor on which element with global index i is stored
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
SizeType cutoff_processor = n % p;
|
||||
SizeType cutoff = cutoff_processor * (n / p + 1);
|
||||
|
||||
if (i < cutoff) return i / (n / p + 1);
|
||||
else return cutoff_processor + (i - cutoff) / (n / p);
|
||||
}
|
||||
|
||||
// Find the starting index for processor with the given id
|
||||
template<typename ID>
|
||||
std::size_t start(ID id) const
|
||||
{
|
||||
std::size_t estimate = id * (n / p + 1);
|
||||
ID cutoff_processor = n % p;
|
||||
if (id < cutoff_processor) return estimate;
|
||||
else return estimate - (id - cutoff_processor);
|
||||
}
|
||||
|
||||
// Find the local index for the ith global element
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
SizeType owner = (*this)(i);
|
||||
return i - start(owner);
|
||||
}
|
||||
|
||||
// Returns the global index of local element i
|
||||
template<typename SizeType>
|
||||
SizeType global(SizeType i) const
|
||||
{ return global(id, i); }
|
||||
|
||||
// Returns the global index of the ith local element on processor id
|
||||
template<typename ProcessID, typename SizeType>
|
||||
SizeType global(ProcessID id, SizeType i) const
|
||||
{ return i + start(id); }
|
||||
|
||||
private:
|
||||
std::size_t id; //< The ID number of this processor
|
||||
std::size_t p; //< The number of processors
|
||||
std::size_t n; //< The size of the problem space
|
||||
};
|
||||
|
||||
// Block distribution with arbitrary block sizes
|
||||
struct uneven_block
|
||||
{
|
||||
typedef std::vector<std::size_t> size_vector;
|
||||
|
||||
template<typename LinearProcessGroup>
|
||||
explicit uneven_block(const LinearProcessGroup& pg, const std::vector<std::size_t>& local_sizes)
|
||||
: id(process_id(pg)), p(num_processes(pg)), local_sizes(local_sizes)
|
||||
{
|
||||
BOOST_ASSERT(local_sizes.size() == p);
|
||||
local_starts.resize(p + 1);
|
||||
local_starts[0] = 0;
|
||||
std::partial_sum(local_sizes.begin(), local_sizes.end(), &local_starts[1]);
|
||||
n = local_starts[p];
|
||||
}
|
||||
|
||||
// To do maybe: enter local size in each process and gather in constructor (much handier)
|
||||
// template<typename LinearProcessGroup>
|
||||
// explicit uneven_block(const LinearProcessGroup& pg, std::size_t my_local_size)
|
||||
|
||||
// If there are n elements in the distributed data structure, returns the number of elements stored locally.
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType) const
|
||||
{ return local_sizes[id]; }
|
||||
|
||||
// If there are n elements in the distributed data structure, returns the number of elements stored on processor ID
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType) const
|
||||
{ return local_sizes[id]; }
|
||||
|
||||
// Returns the processor on which element with global index i is stored
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
BOOST_ASSERT (i >= (SizeType) 0 && i < (SizeType) n); // check for valid range
|
||||
size_vector::const_iterator lb = std::lower_bound(local_starts.begin(), local_starts.end(), (std::size_t) i);
|
||||
return ((SizeType)(*lb) == i ? lb : --lb) - local_starts.begin();
|
||||
}
|
||||
|
||||
// Find the starting index for processor with the given id
|
||||
template<typename ID>
|
||||
std::size_t start(ID id) const
|
||||
{
|
||||
return local_starts[id];
|
||||
}
|
||||
|
||||
// Find the local index for the ith global element
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
SizeType owner = (*this)(i);
|
||||
return i - start(owner);
|
||||
}
|
||||
|
||||
// Returns the global index of local element i
|
||||
template<typename SizeType>
|
||||
SizeType global(SizeType i) const
|
||||
{ return global(id, i); }
|
||||
|
||||
// Returns the global index of the ith local element on processor id
|
||||
template<typename ProcessID, typename SizeType>
|
||||
SizeType global(ProcessID id, SizeType i) const
|
||||
{ return i + start(id); }
|
||||
|
||||
private:
|
||||
std::size_t id; //< The ID number of this processor
|
||||
std::size_t p; //< The number of processors
|
||||
std::size_t n; //< The size of the problem space
|
||||
std::vector<std::size_t> local_sizes; //< The sizes of all blocks
|
||||
std::vector<std::size_t> local_starts; //< Lowest global index of each block
|
||||
};
|
||||
|
||||
|
||||
struct oned_block_cyclic
|
||||
{
|
||||
template<typename LinearProcessGroup>
|
||||
explicit oned_block_cyclic(const LinearProcessGroup& pg, std::size_t size)
|
||||
: id(process_id(pg)), p(num_processes(pg)), size(size) { }
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType n) const
|
||||
{
|
||||
return block_size(id, n);
|
||||
}
|
||||
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType n) const
|
||||
{
|
||||
SizeType all_blocks = n / size;
|
||||
SizeType extra_elements = n % size;
|
||||
SizeType everyone_gets = all_blocks / p;
|
||||
SizeType extra_blocks = all_blocks % p;
|
||||
SizeType my_blocks = everyone_gets + (p < extra_blocks? 1 : 0);
|
||||
SizeType my_elements = my_blocks * size
|
||||
+ (p == extra_blocks? extra_elements : 0);
|
||||
return my_elements;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
return (i / size) % p;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
return ((i / size) / p) * size + i % size;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType global(SizeType i) const
|
||||
{ return global(id, i); }
|
||||
|
||||
template<typename ProcessID, typename SizeType>
|
||||
SizeType global(ProcessID id, SizeType i) const
|
||||
{
|
||||
return ((i / size) * p + id) * size + i % size;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t id; //< The ID number of this processor
|
||||
std::size_t p; //< The number of processors
|
||||
std::size_t size; //< Block size
|
||||
};
|
||||
|
||||
struct twod_block_cyclic
|
||||
{
|
||||
template<typename LinearProcessGroup>
|
||||
explicit twod_block_cyclic(const LinearProcessGroup& pg,
|
||||
std::size_t block_rows, std::size_t block_columns,
|
||||
std::size_t data_columns_per_row)
|
||||
: id(process_id(pg)), p(num_processes(pg)),
|
||||
block_rows(block_rows), block_columns(block_columns),
|
||||
data_columns_per_row(data_columns_per_row)
|
||||
{ }
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType n) const
|
||||
{
|
||||
return block_size(id, n);
|
||||
}
|
||||
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType n) const
|
||||
{
|
||||
// TBD: This is really lame :)
|
||||
int result = -1;
|
||||
while (n > 0) {
|
||||
--n;
|
||||
if ((*this)(n) == id && (int)local(n) > result) result = local(n);
|
||||
}
|
||||
++result;
|
||||
|
||||
// std::cerr << "Block size of id " << id << " is " << result << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
SizeType result = get_block_num(i) % p;
|
||||
// std::cerr << "Item " << i << " goes on processor " << result << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
// Compute the start of the block
|
||||
std::size_t block_num = get_block_num(i);
|
||||
// std::cerr << "Item " << i << " is in block #" << block_num << std::endl;
|
||||
|
||||
std::size_t local_block_num = block_num / p;
|
||||
std::size_t block_start = local_block_num * block_rows * block_columns;
|
||||
|
||||
// Compute the offset into the block
|
||||
std::size_t data_row = i / data_columns_per_row;
|
||||
std::size_t data_col = i % data_columns_per_row;
|
||||
std::size_t block_offset = (data_row % block_rows) * block_columns
|
||||
+ (data_col % block_columns);
|
||||
|
||||
// std::cerr << "Item " << i << " maps to local index " << block_start+block_offset << std::endl;
|
||||
return block_start + block_offset;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType global(SizeType i) const
|
||||
{
|
||||
// Compute the (global) block in which this element resides
|
||||
SizeType local_block_num = i / (block_rows * block_columns);
|
||||
SizeType block_offset = i % (block_rows * block_columns);
|
||||
SizeType block_num = local_block_num * p + id;
|
||||
|
||||
// Compute the position of the start of the block (globally)
|
||||
SizeType block_start = block_num * block_rows * block_columns;
|
||||
|
||||
std::cerr << "Block " << block_num << " starts at index " << block_start
|
||||
<< std::endl;
|
||||
|
||||
// Compute the row and column of this block
|
||||
SizeType block_row = block_num / (data_columns_per_row / block_columns);
|
||||
SizeType block_col = block_num % (data_columns_per_row / block_columns);
|
||||
|
||||
SizeType row_in_block = block_offset / block_columns;
|
||||
SizeType col_in_block = block_offset % block_columns;
|
||||
|
||||
std::cerr << "Local index " << i << " is in block at row " << block_row
|
||||
<< ", column " << block_col << ", in-block row " << row_in_block
|
||||
<< ", in-block col " << col_in_block << std::endl;
|
||||
|
||||
SizeType result = block_row * block_rows + block_col * block_columns
|
||||
+ row_in_block * block_rows + col_in_block;
|
||||
|
||||
|
||||
std::cerr << "global(" << i << "@" << id << ") = " << result
|
||||
<< " =? " << local(result) << std::endl;
|
||||
BOOST_ASSERT(i == local(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename SizeType>
|
||||
std::size_t get_block_num(SizeType i) const
|
||||
{
|
||||
std::size_t data_row = i / data_columns_per_row;
|
||||
std::size_t data_col = i % data_columns_per_row;
|
||||
std::size_t block_row = data_row / block_rows;
|
||||
std::size_t block_col = data_col / block_columns;
|
||||
std::size_t blocks_in_row = data_columns_per_row / block_columns;
|
||||
std::size_t block_num = block_col * blocks_in_row + block_row;
|
||||
return block_num;
|
||||
}
|
||||
|
||||
std::size_t id; //< The ID number of this processor
|
||||
std::size_t p; //< The number of processors
|
||||
std::size_t block_rows; //< The # of rows in each block
|
||||
std::size_t block_columns; //< The # of columns in each block
|
||||
std::size_t data_columns_per_row; //< The # of columns per row of data
|
||||
};
|
||||
|
||||
class twod_random
|
||||
{
|
||||
template<typename RandomNumberGen>
|
||||
struct random_int
|
||||
{
|
||||
explicit random_int(RandomNumberGen& gen) : gen(gen) { }
|
||||
|
||||
template<typename T>
|
||||
T operator()(T n) const
|
||||
{
|
||||
uniform_int<T> distrib(0, n-1);
|
||||
return distrib(gen);
|
||||
}
|
||||
|
||||
private:
|
||||
RandomNumberGen& gen;
|
||||
};
|
||||
|
||||
public:
|
||||
template<typename LinearProcessGroup, typename RandomNumberGen>
|
||||
explicit twod_random(const LinearProcessGroup& pg,
|
||||
std::size_t block_rows, std::size_t block_columns,
|
||||
std::size_t data_columns_per_row,
|
||||
std::size_t n,
|
||||
RandomNumberGen& gen)
|
||||
: id(process_id(pg)), p(num_processes(pg)),
|
||||
block_rows(block_rows), block_columns(block_columns),
|
||||
data_columns_per_row(data_columns_per_row),
|
||||
global_to_local(n / (block_rows * block_columns))
|
||||
{
|
||||
std::copy(make_counting_iterator(std::size_t(0)),
|
||||
make_counting_iterator(global_to_local.size()),
|
||||
global_to_local.begin());
|
||||
|
||||
random_int<RandomNumberGen> rand(gen);
|
||||
std::random_shuffle(global_to_local.begin(), global_to_local.end(), rand);
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType n) const
|
||||
{
|
||||
return block_size(id, n);
|
||||
}
|
||||
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType n) const
|
||||
{
|
||||
// TBD: This is really lame :)
|
||||
int result = -1;
|
||||
while (n > 0) {
|
||||
--n;
|
||||
if ((*this)(n) == id && (int)local(n) > result) result = local(n);
|
||||
}
|
||||
++result;
|
||||
|
||||
// std::cerr << "Block size of id " << id << " is " << result << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
SizeType result = get_block_num(i) % p;
|
||||
// std::cerr << "Item " << i << " goes on processor " << result << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
// Compute the start of the block
|
||||
std::size_t block_num = get_block_num(i);
|
||||
// std::cerr << "Item " << i << " is in block #" << block_num << std::endl;
|
||||
|
||||
std::size_t local_block_num = block_num / p;
|
||||
std::size_t block_start = local_block_num * block_rows * block_columns;
|
||||
|
||||
// Compute the offset into the block
|
||||
std::size_t data_row = i / data_columns_per_row;
|
||||
std::size_t data_col = i % data_columns_per_row;
|
||||
std::size_t block_offset = (data_row % block_rows) * block_columns
|
||||
+ (data_col % block_columns);
|
||||
|
||||
// std::cerr << "Item " << i << " maps to local index " << block_start+block_offset << std::endl;
|
||||
return block_start + block_offset;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename SizeType>
|
||||
std::size_t get_block_num(SizeType i) const
|
||||
{
|
||||
std::size_t data_row = i / data_columns_per_row;
|
||||
std::size_t data_col = i % data_columns_per_row;
|
||||
std::size_t block_row = data_row / block_rows;
|
||||
std::size_t block_col = data_col / block_columns;
|
||||
std::size_t blocks_in_row = data_columns_per_row / block_columns;
|
||||
std::size_t block_num = block_col * blocks_in_row + block_row;
|
||||
return global_to_local[block_num];
|
||||
}
|
||||
|
||||
std::size_t id; //< The ID number of this processor
|
||||
std::size_t p; //< The number of processors
|
||||
std::size_t block_rows; //< The # of rows in each block
|
||||
std::size_t block_columns; //< The # of columns in each block
|
||||
std::size_t data_columns_per_row; //< The # of columns per row of data
|
||||
std::vector<std::size_t> global_to_local;
|
||||
};
|
||||
|
||||
class random_distribution
|
||||
{
|
||||
template<typename RandomNumberGen>
|
||||
struct random_int
|
||||
{
|
||||
explicit random_int(RandomNumberGen& gen) : gen(gen) { }
|
||||
|
||||
template<typename T>
|
||||
T operator()(T n) const
|
||||
{
|
||||
uniform_int<T> distrib(0, n-1);
|
||||
return distrib(gen);
|
||||
}
|
||||
|
||||
private:
|
||||
RandomNumberGen& gen;
|
||||
};
|
||||
|
||||
public:
|
||||
template<typename LinearProcessGroup, typename RandomNumberGen>
|
||||
random_distribution(const LinearProcessGroup& pg, RandomNumberGen& gen,
|
||||
std::size_t n)
|
||||
: base(pg, n), local_to_global(n), global_to_local(n)
|
||||
{
|
||||
std::copy(make_counting_iterator(std::size_t(0)),
|
||||
make_counting_iterator(n),
|
||||
local_to_global.begin());
|
||||
|
||||
random_int<RandomNumberGen> rand(gen);
|
||||
std::random_shuffle(local_to_global.begin(), local_to_global.end(), rand);
|
||||
|
||||
|
||||
for (std::vector<std::size_t>::size_type i = 0; i < n; ++i)
|
||||
global_to_local[local_to_global[i]] = i;
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType block_size(SizeType n) const
|
||||
{ return base.block_size(n); }
|
||||
|
||||
template<typename SizeType, typename ProcessID>
|
||||
SizeType block_size(ProcessID id, SizeType n) const
|
||||
{ return base.block_size(id, n); }
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType operator()(SizeType i) const
|
||||
{
|
||||
return base(global_to_local[i]);
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType local(SizeType i) const
|
||||
{
|
||||
return base.local(global_to_local[i]);
|
||||
}
|
||||
|
||||
template<typename ProcessID, typename SizeType>
|
||||
SizeType global(ProcessID p, SizeType i) const
|
||||
{
|
||||
return local_to_global[base.global(p, i)];
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
SizeType global(SizeType i) const
|
||||
{
|
||||
return local_to_global[base.global(i)];
|
||||
}
|
||||
|
||||
private:
|
||||
block base;
|
||||
std::vector<std::size_t> local_to_global;
|
||||
std::vector<std::size_t> global_to_local;
|
||||
};
|
||||
|
||||
} } // end namespace boost::parallel
|
||||
|
||||
#endif // BOOST_PARALLEL_DISTRIBUTION_HPP
|
||||
|
||||
101
test/external/boost/graph/parallel/process_group.hpp
vendored
Normal file
101
test/external/boost/graph/parallel/process_group.hpp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
#ifndef BOOST_GRAPH_PARALLEL_PROCESS_GROUP_HPP
|
||||
#define BOOST_GRAPH_PARALLEL_PROCESS_GROUP_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace graph { namespace parallel {
|
||||
|
||||
/**
|
||||
* A special type used as a flag to a process group constructor that
|
||||
* indicates that the copy of a process group will represent a new
|
||||
* distributed data structure.
|
||||
*/
|
||||
struct attach_distributed_object { };
|
||||
|
||||
/**
|
||||
* Describes the context in which a trigger is being invoked to
|
||||
* receive a message.
|
||||
*/
|
||||
enum trigger_receive_context {
|
||||
/// No trigger is active at this time.
|
||||
trc_none,
|
||||
/// The trigger is being invoked during synchronization, at the end
|
||||
/// of a superstep.
|
||||
trc_in_synchronization,
|
||||
/// The trigger is being invoked as an "early" receive of a message
|
||||
/// that was sent through the normal "send" operations to be
|
||||
/// received by the end of the superstep, but the process group sent
|
||||
/// the message earlier to clear its buffers.
|
||||
trc_early_receive,
|
||||
/// The trigger is being invoked for an out-of-band message, which
|
||||
/// must be handled immediately.
|
||||
trc_out_of_band,
|
||||
/// The trigger is being invoked for an out-of-band message, which
|
||||
/// must be handled immediately and has alredy been received by
|
||||
/// an MPI_IRecv call.
|
||||
trc_irecv_out_of_band
|
||||
};
|
||||
|
||||
// Process group tags
|
||||
struct process_group_tag {};
|
||||
struct linear_process_group_tag : virtual process_group_tag {};
|
||||
struct messaging_process_group_tag : virtual process_group_tag {};
|
||||
struct immediate_process_group_tag : virtual messaging_process_group_tag {};
|
||||
struct bsp_process_group_tag : virtual messaging_process_group_tag {};
|
||||
struct batch_process_group_tag : virtual messaging_process_group_tag {};
|
||||
struct locking_process_group_tag : virtual process_group_tag {};
|
||||
struct spawning_process_group_tag : virtual process_group_tag {};
|
||||
|
||||
struct process_group_archetype
|
||||
{
|
||||
typedef int process_id_type;
|
||||
};
|
||||
|
||||
void wait(process_group_archetype&);
|
||||
void synchronize(process_group_archetype&);
|
||||
int process_id(const process_group_archetype&);
|
||||
int num_processes(const process_group_archetype&);
|
||||
|
||||
template<typename T> void send(process_group_archetype&, int, int, const T&);
|
||||
|
||||
template<typename T>
|
||||
process_group_archetype::process_id_type
|
||||
receive(const process_group_archetype& pg,
|
||||
process_group_archetype::process_id_type source, int tag, T& value);
|
||||
|
||||
template<typename T>
|
||||
std::pair<process_group_archetype::process_id_type, std::size_t>
|
||||
receive(const process_group_archetype& pg, int tag, T values[], std::size_t n);
|
||||
|
||||
template<typename T>
|
||||
std::pair<process_group_archetype::process_id_type, std::size_t>
|
||||
receive(const process_group_archetype& pg,
|
||||
process_group_archetype::process_id_type source, int tag, T values[],
|
||||
std::size_t n);
|
||||
|
||||
} } } // end namespace boost::graph::parallel
|
||||
|
||||
namespace boost { namespace graph { namespace distributed {
|
||||
using parallel::trigger_receive_context;
|
||||
using parallel::trc_early_receive;
|
||||
using parallel::trc_out_of_band;
|
||||
using parallel::trc_irecv_out_of_band;
|
||||
using parallel::trc_in_synchronization;
|
||||
using parallel::trc_none;
|
||||
using parallel::attach_distributed_object;
|
||||
} } } // end namespace boost::graph::distributed
|
||||
|
||||
#endif // BOOST_GRAPH_PARALLEL_PROCESS_GROUP_HPP
|
||||
111
test/external/boost/graph/parallel/properties.hpp
vendored
Normal file
111
test/external/boost/graph/parallel/properties.hpp
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright 2004 The Trustees of Indiana University.
|
||||
|
||||
// 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: Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
#ifndef BOOST_GRAPH_PARALLEL_PROPERTIES_HPP
|
||||
#define BOOST_GRAPH_PARALLEL_PROPERTIES_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/property_map/parallel/distributed_property_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
/***************************************************************************
|
||||
* Property map reduction operations
|
||||
***************************************************************************/
|
||||
/**
|
||||
* Metafunction that produces a reduction operation for the given
|
||||
* property. The default behavior merely forwards to @ref
|
||||
* basic_reduce, but it is expected that this class template will be
|
||||
* specified for important properties.
|
||||
*/
|
||||
template<typename Property>
|
||||
struct property_reduce
|
||||
{
|
||||
template<typename Value>
|
||||
class apply : public parallel::basic_reduce<Value> {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Reduction of vertex colors can only darken, not lighten, the
|
||||
* color. Black cannot turn black, grey can only turn black, and
|
||||
* white can be changed to either color. The default color is white.
|
||||
*/
|
||||
template<>
|
||||
struct property_reduce<vertex_color_t>
|
||||
{
|
||||
template<typename Color>
|
||||
class apply
|
||||
{
|
||||
typedef color_traits<Color> traits;
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, non_default_resolver = true);
|
||||
|
||||
template<typename Key>
|
||||
Color operator()(const Key&) const { return traits::white(); }
|
||||
|
||||
template<typename Key>
|
||||
Color operator()(const Key&, Color local, Color remote) const {
|
||||
if (local == traits::white()) return remote;
|
||||
else if (remote == traits::black()) return remote;
|
||||
else return local;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Reduction of a distance always takes the shorter distance. The
|
||||
* default distance value is the maximum value for the data type.
|
||||
*/
|
||||
template<>
|
||||
struct property_reduce<vertex_distance_t>
|
||||
{
|
||||
template<typename T>
|
||||
class apply
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, non_default_resolver = true);
|
||||
|
||||
template<typename Key>
|
||||
T operator()(const Key&) const { return (std::numeric_limits<T>::max)(); }
|
||||
|
||||
template<typename Key>
|
||||
T operator()(const Key&, T x, T y) const { return x < y? x : y; }
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct property_reduce<vertex_predecessor_t>
|
||||
{
|
||||
template<typename T>
|
||||
class apply
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, non_default_resolver = true);
|
||||
|
||||
T operator()(T key) const { return key; }
|
||||
T operator()(T key, T, T y) const { return y; }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Property, typename PropertyMap>
|
||||
inline void set_property_map_role(Property p, PropertyMap pm)
|
||||
{
|
||||
typedef typename property_traits<PropertyMap>::value_type value_type;
|
||||
typedef property_reduce<Property> property_red;
|
||||
typedef typename property_red::template apply<value_type> reduce;
|
||||
|
||||
pm.set_reduce(reduce());
|
||||
}
|
||||
|
||||
} // end namespace boost
|
||||
#endif // BOOST_GRAPH_PARALLEL_PROPERTIES_HPP
|
||||
108
test/external/boost/graph/parallel/simple_trigger.hpp
vendored
Normal file
108
test/external/boost/graph/parallel/simple_trigger.hpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright (C) 2007 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)
|
||||
|
||||
// This file contains a simplification of the "trigger" method for
|
||||
// process groups. The simple trigger handles the common case where
|
||||
// the handler associated with a trigger is a member function bound to
|
||||
// a particular pointer.
|
||||
|
||||
#ifndef BOOST_GRAPH_PARALLEL_SIMPLE_TRIGGER_HPP
|
||||
#define BOOST_GRAPH_PARALLEL_SIMPLE_TRIGGER_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_USE_MPI
|
||||
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
||||
#endif
|
||||
|
||||
#include <boost/graph/parallel/process_group.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace parallel {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* INTERNAL ONLY
|
||||
*
|
||||
* The actual function object that bridges from the normal trigger
|
||||
* interface to the simplified interface. This is the equivalent of
|
||||
* bind(pmf, self, _1, _2, _3, _4), but without the compile-time
|
||||
* overhead of bind.
|
||||
*/
|
||||
template<typename Class, typename T, typename Result>
|
||||
class simple_trigger_t
|
||||
{
|
||||
public:
|
||||
simple_trigger_t(Class* self,
|
||||
Result (Class::*pmf)(int, int, const T&,
|
||||
trigger_receive_context))
|
||||
: self(self), pmf(pmf) { }
|
||||
|
||||
Result
|
||||
operator()(int source, int tag, const T& data,
|
||||
trigger_receive_context context) const
|
||||
{
|
||||
return (self->*pmf)(source, tag, data, context);
|
||||
}
|
||||
|
||||
private:
|
||||
Class* self;
|
||||
Result (Class::*pmf)(int, int, const T&, trigger_receive_context);
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
/**
|
||||
* Simplified trigger interface that reduces the amount of code
|
||||
* required to connect a process group trigger to a handler that is
|
||||
* just a bound member function.
|
||||
*
|
||||
* INTERNAL ONLY
|
||||
*/
|
||||
template<typename ProcessGroup, typename Class, typename T>
|
||||
inline void
|
||||
simple_trigger(ProcessGroup& pg, int tag, Class* self,
|
||||
void (Class::*pmf)(int source, int tag, const T& data,
|
||||
trigger_receive_context context), int)
|
||||
{
|
||||
pg.template trigger<T>(tag,
|
||||
detail::simple_trigger_t<Class, T, void>(self, pmf));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified trigger interface that reduces the amount of code
|
||||
* required to connect a process group trigger with a reply to a
|
||||
* handler that is just a bound member function.
|
||||
*
|
||||
* INTERNAL ONLY
|
||||
*/
|
||||
template<typename ProcessGroup, typename Class, typename T, typename Result>
|
||||
inline void
|
||||
simple_trigger(ProcessGroup& pg, int tag, Class* self,
|
||||
Result (Class::*pmf)(int source, int tag, const T& data,
|
||||
trigger_receive_context context), long)
|
||||
{
|
||||
pg.template trigger_with_reply<T>
|
||||
(tag, detail::simple_trigger_t<Class, T, Result>(self, pmf));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified trigger interface that reduces the amount of code
|
||||
* required to connect a process group trigger to a handler that is
|
||||
* just a bound member function.
|
||||
*/
|
||||
template<typename ProcessGroup, typename Class, typename T, typename Result>
|
||||
inline void
|
||||
simple_trigger(ProcessGroup& pg, int tag, Class* self,
|
||||
Result (Class::*pmf)(int source, int tag, const T& data,
|
||||
trigger_receive_context context))
|
||||
{
|
||||
// We pass 0 (an int) to help VC++ disambiguate calls to simple_trigger
|
||||
// with Result=void.
|
||||
simple_trigger(pg, tag, self, pmf, 0);
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::parallel
|
||||
|
||||
#endif // BOOST_GRAPH_PARALLEL_SIMPLE_TRIGGER_HPP
|
||||
Reference in New Issue
Block a user