Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
// 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
#ifndef BOOST_GRAPH_PARALLEL_DIJKSTRA_DETAIL_HPP
#define BOOST_GRAPH_PARALLEL_DIJKSTRA_DETAIL_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/property_map/property_map.hpp>
namespace boost { namespace graph { namespace distributed { namespace detail {
/**********************************************************************
* Dijkstra queue message data *
**********************************************************************/
template<typename DistanceMap, typename PredecessorMap>
class dijkstra_msg_value
{
typedef typename property_traits<DistanceMap>::value_type distance_type;
typedef typename property_traits<PredecessorMap>::value_type
predecessor_type;
public:
typedef std::pair<distance_type, predecessor_type> type;
static type create(distance_type dist, predecessor_type pred)
{ return std::make_pair(dist, pred); }
};
template<typename DistanceMap>
class dijkstra_msg_value<DistanceMap, dummy_property_map>
{
typedef typename property_traits<DistanceMap>::key_type vertex_descriptor;
public:
typedef typename property_traits<DistanceMap>::value_type type;
static type create(type dist, vertex_descriptor) { return dist; }
};
/**********************************************************************/
} } } } // end namespace boost::graph::distributed::detail
#endif // BOOST_GRAPH_PARALLEL_DIJKSTRA_DETAIL_HPP

View File

@@ -0,0 +1,108 @@
// 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
#ifndef BOOST_FILTERED_QUEUE_HPP
#define BOOST_FILTERED_QUEUE_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 <algorithm>
namespace boost {
/** Queue adaptor that filters elements pushed into the queue
* according to some predicate.
*/
template<typename Buffer, typename Predicate>
class filtered_queue
{
public:
typedef Buffer buffer_type;
typedef Predicate predicate_type;
typedef typename Buffer::value_type value_type;
typedef typename Buffer::size_type size_type;
/**
* Constructs a new filtered queue with an initial buffer and a
* predicate.
*
* @param buffer the initial buffer
* @param pred the predicate
*/
explicit
filtered_queue(const buffer_type& buffer = buffer_type(),
const predicate_type& pred = predicate_type())
: buffer(buffer), pred(pred) {}
/** Push a value into the queue.
*
* If the predicate returns @c true for @p x, pushes @p x into the
* buffer.
*/
void push(const value_type& x) { if (pred(x)) buffer.push(x); }
/** Pop the front element off the buffer.
*
* @pre @c !empty()
*/
void pop() { buffer.pop(); }
/** Retrieve the front (top) element in the buffer.
*
* @pre @c !empty()
*/
value_type& top() { return buffer.top(); }
/**
* \overload
*/
const value_type& top() const { return buffer.top(); }
/** Determine the number of elements in the buffer. */
size_type size() const { return buffer.size(); }
/** Determine if the buffer is empty. */
bool empty() const { return buffer.empty(); }
/** Get a reference to the underlying buffer. */
buffer_type& base() { return buffer; }
const buffer_type& base() const { return buffer; }
/** Swap the contents of this with @p other. */
void swap(filtered_queue& other)
{
using std::swap;
swap(buffer, other.buffer);
swap(pred, other.pred);
}
private:
buffer_type buffer;
predicate_type pred;
};
/** Create a filtered queue. */
template<typename Buffer, typename Predicate>
inline filtered_queue<Buffer, Predicate>
make_filtered_queue(const Buffer& buffer, const Predicate& pred)
{ return filtered_queue<Buffer, Predicate>(buffer, pred); }
/** Swap a filtered_queue. */
template<typename Buffer, typename Predicate>
inline void
swap(filtered_queue<Buffer, Predicate>& x,
filtered_queue<Buffer, Predicate>& y)
{
x.swap(y);
}
} // end namespace boost
#endif // BOOST_FILTERED_QUEUE_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
// 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
#include <boost/optional.hpp>
#include <cassert>
#include <boost/graph/parallel/algorithm.hpp>
#include <boost/graph/parallel/process_group.hpp>
#include <functional>
#include <algorithm>
#include <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
namespace boost { namespace graph { namespace distributed {
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
BOOST_DISTRIBUTED_QUEUE_TYPE::
distributed_queue(const ProcessGroup& process_group, const OwnerMap& owner,
const Buffer& buffer, bool polling)
: process_group(process_group, attach_distributed_object()),
owner(owner),
buffer(buffer),
polling(polling)
{
if (!polling)
outgoing_buffers.reset(
new outgoing_buffers_t(num_processes(process_group)));
setup_triggers();
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
BOOST_DISTRIBUTED_QUEUE_TYPE::
distributed_queue(const ProcessGroup& process_group, const OwnerMap& owner,
const Buffer& buffer, const UnaryPredicate& pred,
bool polling)
: process_group(process_group, attach_distributed_object()),
owner(owner),
buffer(buffer),
pred(pred),
polling(polling)
{
if (!polling)
outgoing_buffers.reset(
new outgoing_buffers_t(num_processes(process_group)));
setup_triggers();
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
BOOST_DISTRIBUTED_QUEUE_TYPE::
distributed_queue(const ProcessGroup& process_group, const OwnerMap& owner,
const UnaryPredicate& pred, bool polling)
: process_group(process_group, attach_distributed_object()),
owner(owner),
pred(pred),
polling(polling)
{
if (!polling)
outgoing_buffers.reset(
new outgoing_buffers_t(num_processes(process_group)));
setup_triggers();
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
void
BOOST_DISTRIBUTED_QUEUE_TYPE::push(const value_type& x)
{
typename ProcessGroup::process_id_type dest = get(owner, x);
if (outgoing_buffers)
outgoing_buffers->at(dest).push_back(x);
else if (dest == process_id(process_group))
buffer.push(x);
else
send(process_group, get(owner, x), msg_push, x);
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
bool
BOOST_DISTRIBUTED_QUEUE_TYPE::empty() const
{
/* Processes will stay here until the buffer is nonempty or
synchronization with the other processes indicates that all local
buffers are empty (and no messages are in transit).
*/
while (buffer.empty() && !do_synchronize()) ;
return buffer.empty();
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
typename BOOST_DISTRIBUTED_QUEUE_TYPE::size_type
BOOST_DISTRIBUTED_QUEUE_TYPE::size() const
{
empty();
return buffer.size();
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
void BOOST_DISTRIBUTED_QUEUE_TYPE::setup_triggers()
{
using boost::graph::parallel::simple_trigger;
simple_trigger(process_group, msg_push, this,
&distributed_queue::handle_push);
simple_trigger(process_group, msg_multipush, this,
&distributed_queue::handle_multipush);
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
void
BOOST_DISTRIBUTED_QUEUE_TYPE::
handle_push(int /*source*/, int /*tag*/, const value_type& value,
trigger_receive_context)
{
if (pred(value)) buffer.push(value);
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
void
BOOST_DISTRIBUTED_QUEUE_TYPE::
handle_multipush(int /*source*/, int /*tag*/,
const std::vector<value_type>& values,
trigger_receive_context)
{
for (std::size_t i = 0; i < values.size(); ++i)
if (pred(values[i])) buffer.push(values[i]);
}
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
bool
BOOST_DISTRIBUTED_QUEUE_TYPE::do_synchronize() const
{
#ifdef PBGL_ACCOUNTING
++num_synchronizations;
#endif
using boost::parallel::all_reduce;
using std::swap;
typedef typename ProcessGroup::process_id_type process_id_type;
if (outgoing_buffers) {
// Transfer all of the push requests
process_id_type id = process_id(process_group);
process_id_type np = num_processes(process_group);
for (process_id_type dest = 0; dest < np; ++dest) {
outgoing_buffer_t& outgoing = outgoing_buffers->at(dest);
std::size_t size = outgoing.size();
if (size != 0) {
if (dest != id) {
send(process_group, dest, msg_multipush, outgoing);
} else {
for (std::size_t i = 0; i < size; ++i)
buffer.push(outgoing[i]);
}
outgoing.clear();
}
}
}
synchronize(process_group);
unsigned local_size = buffer.size();
unsigned global_size =
all_reduce(process_group, local_size, std::plus<unsigned>());
return global_size == 0;
}
} } } // end namespace boost::graph::distributed

View File

@@ -0,0 +1,259 @@
// Copyright (C) 2005-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
#ifndef BOOST_GRAPH_DETAIL_REMOTE_UPDATE_SET_HPP
#define BOOST_GRAPH_DETAIL_REMOTE_UPDATE_SET_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>
#include <boost/type_traits/is_convertible.hpp>
#include <vector>
#include <boost/assert.hpp>
#include <boost/optional.hpp>
#include <queue>
namespace boost { namespace graph { namespace detail {
template<typename ProcessGroup>
void do_synchronize(ProcessGroup& pg)
{
using boost::parallel::synchronize;
synchronize(pg);
}
struct remote_set_queued {};
struct remote_set_immediate {};
template<typename ProcessGroup>
class remote_set_semantics
{
BOOST_STATIC_CONSTANT
(bool,
queued = (is_convertible<
typename ProcessGroup::communication_category,
parallel::bsp_process_group_tag>::value));
public:
typedef typename mpl::if_c<queued,
remote_set_queued,
remote_set_immediate>::type type;
};
template<typename Derived, typename ProcessGroup, typename Value,
typename OwnerMap,
typename Semantics = typename remote_set_semantics<ProcessGroup>::type>
class remote_update_set;
/**********************************************************************
* Remote updating set that queues messages until synchronization *
**********************************************************************/
template<typename Derived, typename ProcessGroup, typename Value,
typename OwnerMap>
class remote_update_set<Derived, ProcessGroup, Value, OwnerMap,
remote_set_queued>
{
typedef typename property_traits<OwnerMap>::key_type Key;
typedef std::vector<std::pair<Key, Value> > Updates;
typedef typename Updates::size_type updates_size_type;
typedef typename Updates::value_type updates_pair_type;
public:
private:
typedef typename ProcessGroup::process_id_type process_id_type;
enum message_kind {
/** Message containing the number of updates that will be sent in
* a msg_updates message that will immediately follow. This
* message will contain a single value of type
* updates_size_type.
*/
msg_num_updates,
/** Contains (key, value) pairs with all of the updates from a
* particular source. The number of updates is variable, but will
* be provided in a msg_num_updates message that immediately
* preceeds this message.
*
*/
msg_updates
};
struct handle_messages
{
explicit
handle_messages(remote_update_set* self, const ProcessGroup& pg)
: self(self), update_sizes(num_processes(pg), 0) { }
void operator()(process_id_type source, int tag)
{
switch(tag) {
case msg_num_updates:
{
// Receive the # of updates
updates_size_type num_updates;
receive(self->process_group, source, tag, num_updates);
update_sizes[source] = num_updates;
}
break;
case msg_updates:
{
updates_size_type num_updates = update_sizes[source];
BOOST_ASSERT(num_updates);
// Receive the actual updates
std::vector<updates_pair_type> updates(num_updates);
receive(self->process_group, source, msg_updates, &updates[0],
num_updates);
// Send updates to derived "receive_update" member
Derived* derived = static_cast<Derived*>(self);
for (updates_size_type u = 0; u < num_updates; ++u)
derived->receive_update(source, updates[u].first, updates[u].second);
update_sizes[source] = 0;
}
break;
};
}
private:
remote_update_set* self;
std::vector<updates_size_type> update_sizes;
};
friend struct handle_messages;
protected:
remote_update_set(const ProcessGroup& pg, const OwnerMap& owner)
: process_group(pg, handle_messages(this, pg)),
updates(num_processes(pg)), owner(owner) {
}
void update(const Key& key, const Value& value)
{
if (get(owner, key) == process_id(process_group)) {
Derived* derived = static_cast<Derived*>(this);
derived->receive_update(get(owner, key), key, value);
}
else {
updates[get(owner, key)].push_back(std::make_pair(key, value));
}
}
void collect() { }
void synchronize()
{
// Emit all updates and then remove them
process_id_type num_processes = updates.size();
for (process_id_type p = 0; p < num_processes; ++p) {
if (!updates[p].empty()) {
send(process_group, p, msg_num_updates, updates[p].size());
send(process_group, p, msg_updates,
&updates[p].front(), updates[p].size());
updates[p].clear();
}
}
do_synchronize(process_group);
}
ProcessGroup process_group;
private:
std::vector<Updates> updates;
OwnerMap owner;
};
/**********************************************************************
* Remote updating set that sends messages immediately *
**********************************************************************/
template<typename Derived, typename ProcessGroup, typename Value,
typename OwnerMap>
class remote_update_set<Derived, ProcessGroup, Value, OwnerMap,
remote_set_immediate>
{
typedef typename property_traits<OwnerMap>::key_type Key;
typedef std::pair<Key, Value> update_pair_type;
typedef typename std::vector<update_pair_type>::size_type updates_size_type;
public:
typedef typename ProcessGroup::process_id_type process_id_type;
private:
enum message_kind {
/** Contains a (key, value) pair that will be updated. */
msg_update
};
struct handle_messages
{
explicit handle_messages(remote_update_set* self, const ProcessGroup& pg)
: self(self)
{ update_sizes.resize(num_processes(pg), 0); }
void operator()(process_id_type source, int tag)
{
// Receive the # of updates
BOOST_ASSERT(tag == msg_update);
update_pair_type update;
receive(self->process_group, source, tag, update);
// Send update to derived "receive_update" member
Derived* derived = static_cast<Derived*>(self);
derived->receive_update(source, update.first, update.second);
}
private:
std::vector<updates_size_type> update_sizes;
remote_update_set* self;
};
friend struct handle_messages;
protected:
remote_update_set(const ProcessGroup& pg, const OwnerMap& owner)
: process_group(pg, handle_messages(this, pg)), owner(owner) { }
void update(const Key& key, const Value& value)
{
if (get(owner, key) == process_id(process_group)) {
Derived* derived = static_cast<Derived*>(this);
derived->receive_update(get(owner, key), key, value);
}
else
send(process_group, get(owner, key), msg_update,
update_pair_type(key, value));
}
void collect()
{
typedef std::pair<process_id_type, int> probe_type;
handle_messages handler(this, process_group);
while (optional<probe_type> stp = probe(process_group))
if (stp->second == msg_update) handler(stp->first, stp->second);
}
void synchronize()
{
do_synchronize(process_group);
}
ProcessGroup process_group;
OwnerMap owner;
};
} } } // end namespace boost::graph::detail
#endif // BOOST_GRAPH_DETAIL_REMOTE_UPDATE_SET_HPP

View File

@@ -0,0 +1,84 @@
// -*- C++ -*-
// Copyright (C) 2007 Douglas Gregor <doug.gregor@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)
#ifndef BOOST_GRAPH_DISTRIBUTED_TAG_ALLOCATOR_HPP
#define BOOST_GRAPH_DISTRIBUTED_TAG_ALLOCATOR_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 <vector>
namespace boost { namespace graph { namespace distributed { namespace detail {
/**
* \brief The tag allocator allows clients to request unique tags that
* can be used for one-time communications.
*
* The tag allocator hands out tag values from a predefined maximum
* (given in the constructor) moving downward. Tags are provided one
* at a time via a @c token. When the @c token goes out of scope, the
* tag is returned and may be reallocated. These tags should be used,
* for example, for one-time communication of values.
*/
class tag_allocator {
public:
class token;
friend class token;
/**
* Construct a new tag allocator that provides unique tags starting
* with the value @p top_tag and moving lower, as necessary.
*/
explicit tag_allocator(int top_tag) : bottom(top_tag) { }
/**
* Retrieve a new tag. The token itself holds onto the tag, which
* will be released when the token is destroyed.
*/
token get_tag();
private:
int bottom;
std::vector<int> freed;
};
/**
* A token used to represent an allocated tag.
*/
class tag_allocator::token {
public:
/// Transfer ownership of the tag from @p other.
token(const token& other);
/// De-allocate the tag, if this token still owns it.
~token();
/// Retrieve the tag allocated for this task.
operator int() const { return tag_; }
private:
/// Create a token with a specific tag from the given tag_allocator
token(tag_allocator* allocator, int tag)
: allocator(allocator), tag_(tag) { }
/// Undefined: tokens are not copy-assignable
token& operator=(const token&);
/// The allocator from which this tag was allocated.
tag_allocator* allocator;
/// The stored tag flag. If -1, this token does not own the tag.
mutable int tag_;
friend class tag_allocator;
};
} } } } // end namespace boost::graph::distributed::detail
#endif // BOOST_GRAPH_DISTRIBUTED_TAG_ALLOCATOR_HPP