You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
2153 lines
88 KiB
2153 lines
88 KiB
// Copyright (C) 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 |
|
// Jeremiah Willcock |
|
// Andrew Lumsdaine |
|
|
|
// Distributed compressed sparse row graph type |
|
|
|
#ifndef BOOST_GRAPH_DISTRIBUTED_CSR_HPP |
|
#define BOOST_GRAPH_DISTRIBUTED_CSR_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/assert.hpp> |
|
#include <boost/graph/compressed_sparse_row_graph.hpp> |
|
#include <boost/graph/distributed/selector.hpp> |
|
#include <boost/mpl/if.hpp> |
|
#include <boost/type_traits/is_same.hpp> |
|
#include <boost/graph/distributed/concepts.hpp> |
|
#include <boost/graph/parallel/properties.hpp> |
|
#include <boost/graph/parallel/distribution.hpp> |
|
#include <boost/property_map/parallel/local_property_map.hpp> |
|
#include <boost/property_map/parallel/distributed_property_map.hpp> |
|
|
|
namespace boost { |
|
|
|
// Distributed and sequential inplace ctors have the same signature so |
|
// we need a separate tag for distributed inplace ctors |
|
enum distributed_construct_inplace_from_sources_and_targets_t |
|
{distributed_construct_inplace_from_sources_and_targets}; |
|
|
|
// The number of bits we reserve for the processor ID. |
|
// DPG TBD: This is a hack. It will eventually be a run-time quantity. |
|
static const int processor_bits = 8; |
|
|
|
// Tag class for a distributed CSR graph |
|
struct distributed_csr_tag |
|
: public virtual distributed_graph_tag, |
|
public virtual distributed_vertex_list_graph_tag, |
|
public virtual distributed_edge_list_graph_tag, |
|
public virtual incidence_graph_tag, |
|
public virtual adjacency_graph_tag {}; |
|
|
|
template<typename VertexProperty, typename EdgeProperty, |
|
typename GraphProperty, typename ProcessGroup, typename InVertex, |
|
typename InDistribution, typename InEdgeIndex> |
|
class compressed_sparse_row_graph< |
|
directedS, VertexProperty, EdgeProperty, GraphProperty, |
|
distributedS<ProcessGroup, InVertex, InDistribution>, |
|
InEdgeIndex> |
|
{ |
|
typedef compressed_sparse_row_graph self_type; |
|
|
|
private: |
|
/** |
|
* Determine the type used to represent vertices in the graph. If |
|
* the user has overridden the default, use the user's |
|
* parameter. Otherwise, fall back to std::size_t. |
|
*/ |
|
typedef typename mpl::if_<is_same<InVertex, defaultS>, |
|
std::size_t, |
|
InVertex>::type Vertex; |
|
|
|
/** |
|
* Determine the type used to represent edges in the graph. If |
|
* the user has overridden the default (which is to be the same as |
|
* the distributed vertex selector type), use the user's |
|
* parameter. Otherwise, fall back to the value of @c Vertex. |
|
*/ |
|
typedef typename mpl::if_<is_same<InEdgeIndex, |
|
distributedS<ProcessGroup, InVertex, |
|
InDistribution> >, |
|
Vertex, |
|
InEdgeIndex>::type EdgeIndex; |
|
|
|
public: |
|
/** |
|
* The type of the CSR graph that will be stored locally. |
|
*/ |
|
typedef compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty, |
|
GraphProperty, Vertex, EdgeIndex> |
|
base_type; |
|
|
|
// ----------------------------------------------------------------- |
|
// Graph concept requirements |
|
typedef Vertex vertex_descriptor; |
|
typedef typename graph_traits<base_type>::edge_descriptor edge_descriptor; |
|
typedef directed_tag directed_category; |
|
typedef allow_parallel_edge_tag edge_parallel_category; |
|
typedef distributed_csr_tag traversal_category; |
|
static vertex_descriptor null_vertex(); |
|
|
|
// ----------------------------------------------------------------- |
|
// Distributed Vertex List Graph concept requirements |
|
typedef Vertex vertices_size_type; |
|
class vertex_iterator; |
|
|
|
// ----------------------------------------------------------------- |
|
// Distributed Edge List Graph concept requirements |
|
typedef EdgeIndex edges_size_type; |
|
class edge_iterator; |
|
|
|
// ----------------------------------------------------------------- |
|
// Incidence Graph concept requirements |
|
typedef typename graph_traits<base_type>::out_edge_iterator |
|
out_edge_iterator; |
|
typedef typename graph_traits<base_type>::degree_size_type |
|
degree_size_type; |
|
|
|
// ----------------------------------------------------------------- |
|
// Adjacency Graph concept requirements |
|
typedef typename graph_traits<base_type>::adjacency_iterator |
|
adjacency_iterator; |
|
|
|
// Note: This graph type does not model Bidirectional Graph. |
|
// However, this typedef is required to satisfy graph_traits. |
|
typedef void in_edge_iterator; |
|
|
|
// ----------------------------------------------------------------- |
|
// Distributed Container concept requirements |
|
typedef ProcessGroup process_group_type; |
|
typedef boost::parallel::variant_distribution<process_group_type, Vertex> |
|
distribution_type; |
|
|
|
// ----------------------------------------------------------------- |
|
// Workarounds |
|
// NOTE: This graph type does not have old-style graph properties. It only |
|
// accepts bundles. |
|
typedef no_property vertex_property_type; |
|
typedef no_property edge_property_type; |
|
typedef no_property graph_property_type; |
|
typedef typename mpl::if_<is_void<VertexProperty>, |
|
void****, |
|
VertexProperty>::type vertex_bundled; |
|
typedef typename mpl::if_<is_void<EdgeProperty>, |
|
void****, |
|
EdgeProperty>::type edge_bundled; |
|
typedef typename mpl::if_<is_void<GraphProperty>, |
|
void****, |
|
GraphProperty>::type graph_bundled; |
|
|
|
// ----------------------------------------------------------------- |
|
// Useful types |
|
typedef typename ProcessGroup::process_id_type process_id_type; |
|
|
|
// ----------------------------------------------------------------- |
|
// Graph constructors |
|
compressed_sparse_row_graph(const ProcessGroup& pg = ProcessGroup()) |
|
: m_process_group(pg), m_distribution(parallel::block(pg, 0)) {} |
|
|
|
compressed_sparse_row_graph(const GraphProperty& prop, |
|
const ProcessGroup& pg = ProcessGroup()) |
|
: m_process_group(pg), m_distribution(parallel::block(pg, 0)) {} |
|
|
|
compressed_sparse_row_graph(vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup()) |
|
: m_process_group(pg), m_distribution(parallel::block(pg, 0)), |
|
m_base(numverts) |
|
{} |
|
|
|
compressed_sparse_row_graph(vertices_size_type numverts, |
|
const GraphProperty& prop, |
|
const ProcessGroup& pg = ProcessGroup()) |
|
: m_process_group(pg), m_distribution(parallel::block(pg, 0)), |
|
m_base(numverts) |
|
{} |
|
|
|
template <typename Distribution> |
|
compressed_sparse_row_graph(vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist) |
|
: m_process_group(pg), m_distribution(dist), m_base(numverts) {} |
|
|
|
template <typename Distribution> |
|
compressed_sparse_row_graph(vertices_size_type numverts, |
|
const GraphProperty& prop, |
|
const ProcessGroup& pg, |
|
const Distribution& dist) |
|
: m_process_group(pg), m_distribution(dist), m_base(numverts) {} |
|
|
|
template <typename InputIterator> |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename Distribution> |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator> |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator> |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
edges_size_type numedges = 0, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename Distribution> |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator> |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
edges_size_type numedges = 0, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename MultiPassInputIterator> |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename MultiPassInputIterator, typename Distribution> |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename MultiPassInputIterator, typename EdgePropertyIterator> |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename MultiPassInputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename Source> |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename Distribution, typename Source> |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename Source> |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
std::vector<edge_bundled>& edge_props, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template <typename Distribution, typename Source> |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
std::vector<edge_bundled>& edge_props, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template<typename InputIterator> |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template<typename InputIterator, typename EdgePropertyIterator> |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg = ProcessGroup(), |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template<typename InputIterator, typename Distribution> |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
template<typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop = GraphProperty()); |
|
|
|
base_type& base() { return m_base; } |
|
const base_type& base() const { return m_base; } |
|
|
|
process_group_type process_group() const { return m_process_group.base(); } |
|
|
|
distribution_type& distribution() { return m_distribution; } |
|
const distribution_type& distribution() const { return m_distribution; } |
|
|
|
// Directly access a vertex or edge bundle |
|
vertex_bundled& operator[](vertex_descriptor v) |
|
{ |
|
std::pair<process_id_type, vertex_descriptor> locator |
|
= get(vertex_global, *this, v); |
|
BOOST_ASSERT(locator.first == process_id(m_process_group)); |
|
return base().m_vertex_properties[locator.second]; |
|
} |
|
|
|
const vertex_bundled& operator[](vertex_descriptor v) const |
|
{ |
|
std::pair<process_id_type, vertex_descriptor> locator |
|
= get(vertex_global, *this, v); |
|
BOOST_ASSERT(locator.first == process_id(m_process_group)); |
|
return base().m_process_group[locator.second]; |
|
} |
|
|
|
edge_bundled& operator[](edge_descriptor e) |
|
{ |
|
BOOST_ASSERT(get(vertex_owner, *this, e.src) == process_id(m_process_group)); |
|
return base().m_edge_properties[e.idx]; |
|
} |
|
|
|
const edge_bundled& operator[](edge_descriptor e) const |
|
{ |
|
BOOST_ASSERT(get(vertex_owner, *this, e.src) == process_id(m_process_group)); |
|
return base().m_edge_properties[e.idx]; |
|
} |
|
|
|
// Create a vertex descriptor from a process ID and a local index. |
|
vertex_descriptor |
|
make_vertex_descriptor(process_id_type p, vertex_descriptor v) const |
|
{ |
|
vertex_descriptor vertex_local_index_bits = |
|
sizeof(vertex_descriptor) * CHAR_BIT - processor_bits; |
|
return v | ((vertex_descriptor)p << vertex_local_index_bits); |
|
} |
|
|
|
// Convert a local vertex descriptor into a global vertex descriptor |
|
vertex_descriptor local_to_global_vertex(vertex_descriptor v) const |
|
{ |
|
return make_vertex_descriptor(process_id(m_process_group), v); |
|
} |
|
|
|
// Structural modification |
|
vertex_descriptor add_vertex() |
|
{ |
|
typename graph_traits<base_type>::vertex_descriptor v |
|
= boost::add_vertex(m_base); |
|
|
|
return make_vertex_descriptor(process_id(m_process_group), v); |
|
} |
|
|
|
vertex_descriptor add_vertex(const vertex_bundled& p) |
|
{ |
|
typename graph_traits<base_type>::vertex_descriptor v |
|
= boost::add_vertex(m_base, p); |
|
|
|
return make_vertex_descriptor(process_id(m_process_group), v); |
|
} |
|
|
|
vertex_descriptor add_vertices(vertices_size_type count) |
|
{ |
|
typename graph_traits<base_type>::vertex_descriptor v |
|
= boost::add_vertices(count, m_base); |
|
|
|
return make_vertex_descriptor(process_id(m_process_group), v); |
|
} |
|
|
|
template <typename InputIterator> |
|
void |
|
add_edges(InputIterator first, InputIterator last) |
|
{ boost::add_edges_global(first, last, get(vertex_local, *this), m_base); } |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator> |
|
void |
|
add_edges(InputIterator first, InputIterator last, |
|
EdgePropertyIterator ep_iter, |
|
EdgePropertyIterator ep_iter_end) |
|
{ boost::add_edges_global(first, last, ep_iter, ep_iter_end, |
|
get(vertex_local, *this), m_base); } |
|
|
|
template <typename InputIterator> |
|
void |
|
add_edges_sorted(InputIterator first, InputIterator last) |
|
{ boost::add_edges_sorted_global(first, last, |
|
get(vertex_local, *this), m_base); } |
|
|
|
template <typename InputIterator, typename EdgePropertyIterator> |
|
void |
|
add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted, |
|
EdgePropertyIterator ep_iter_sorted) |
|
{ boost::add_edges_sorted_global(first_sorted, last_sorted, ep_iter_sorted, |
|
get(vertex_local, *this), m_base); } |
|
|
|
protected: |
|
ProcessGroup m_process_group; |
|
distribution_type m_distribution; |
|
base_type m_base; |
|
}; |
|
|
|
/** @brief Helper macro containing the template parameters for the |
|
* distributed CSR graph. |
|
* |
|
* This macro contains all of the template parameters needed for the |
|
* distributed compressed_sparse_row graph type. It is used to reduce |
|
* the amount of typing required to declare free functions for this |
|
* graph type. |
|
*/ |
|
#define BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS \ |
|
typename VertexProperty, typename EdgeProperty, \ |
|
typename GraphProperty, typename ProcessGroup, typename InVertex, \ |
|
typename InDistribution, typename InEdgeIndex |
|
|
|
/** @brief Helper macro containing the typical instantiation of the |
|
* distributed CSR graph. |
|
* |
|
* This macro contains an instantiation of the distributed CSR graph |
|
* type using the typical template parameters names (e.g., those |
|
* provided by the macro @c |
|
* BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS). It is used to reduce |
|
* the amount of typing required to declare free functions for this |
|
* graph type. |
|
*/ |
|
#define BOOST_DISTRIB_CSR_GRAPH_TYPE \ |
|
compressed_sparse_row_graph< \ |
|
directedS, VertexProperty, EdgeProperty, GraphProperty, \ |
|
distributedS<ProcessGroup, InVertex, InDistribution>, \ |
|
InEdgeIndex> |
|
|
|
// ----------------------------------------------------------------- |
|
// Graph concept operations |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE::null_vertex() |
|
{ |
|
return graph_traits<base_type>::null_vertex(); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Incidence Graph concept operations |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
source(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE&) |
|
{ return e.src; } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
target(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return target(e, g.base()); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator> |
|
out_edges(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type |
|
edges_size_type; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor ed; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator it; |
|
edges_size_type u_local = get(vertex_local, g, u); |
|
edges_size_type u_row_start = g.base().m_forward.m_rowstart[u_local]; |
|
edges_size_type next_row_start = g.base().m_forward.m_rowstart[u_local + 1]; |
|
return std::make_pair(it(ed(u, u_row_start)), |
|
it(ed(u, (std::max)(u_row_start, next_row_start)))); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type |
|
out_degree(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return out_degree(get(vertex_local, g, u), g.base()); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// DistributedGraph concept requirements |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
void synchronize(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE graph_type; |
|
synchronize(g.process_group()); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
ProcessGroup |
|
process_group(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.process_group(); } |
|
|
|
|
|
// ----------------------------------------------------------------- |
|
// Adjacency Graph concept requirements |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator> |
|
adjacent_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return adjacent_vertices(get(vertex_local, g, u), g.base()); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Distributed Vertex List Graph concept operations |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator |
|
: public iterator_adaptor<vertex_iterator, |
|
counting_iterator<Vertex>, |
|
Vertex, |
|
random_access_traversal_tag, |
|
Vertex> |
|
{ |
|
typedef iterator_adaptor<vertex_iterator, |
|
counting_iterator<Vertex>, |
|
Vertex, |
|
random_access_traversal_tag, |
|
Vertex> inherited; |
|
public: |
|
vertex_iterator() {} |
|
|
|
explicit vertex_iterator(Vertex v, const self_type* graph) |
|
: inherited(counting_iterator<Vertex>(v)), graph(graph) { } |
|
|
|
Vertex dereference() const |
|
{ |
|
return graph->local_to_global_vertex(*(this->base_reference())); |
|
} |
|
|
|
friend class iterator_core_access; |
|
|
|
private: |
|
const self_type* graph; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type |
|
num_vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return num_vertices(g.base()); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator> |
|
vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator |
|
vertex_iterator; |
|
return std::make_pair(vertex_iterator(0, &g), |
|
vertex_iterator(num_vertices(g), &g)); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Distributed Edge List Graph concept operations |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator |
|
{ |
|
public: |
|
typedef std::forward_iterator_tag iterator_category; |
|
typedef edge_descriptor value_type; |
|
|
|
typedef const edge_descriptor* pointer; |
|
|
|
typedef edge_descriptor reference; |
|
typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type; |
|
|
|
edge_iterator() : graph(0), current_edge(), end_of_this_vertex(0) {} |
|
|
|
edge_iterator(const compressed_sparse_row_graph& graph, |
|
edge_descriptor current_edge, |
|
EdgeIndex end_of_this_vertex) |
|
: graph(&graph), local_src(current_edge.src), current_edge(current_edge), |
|
end_of_this_vertex(end_of_this_vertex) |
|
{ |
|
// The edge that comes in has a local source vertex. Make it global. |
|
current_edge.src = graph.local_to_global_vertex(current_edge.src); |
|
} |
|
|
|
// From InputIterator |
|
reference operator*() const { return current_edge; } |
|
pointer operator->() const { return ¤t_edge; } |
|
|
|
bool operator==(const edge_iterator& o) const { |
|
return current_edge == o.current_edge; |
|
} |
|
bool operator!=(const edge_iterator& o) const { |
|
return current_edge != o.current_edge; |
|
} |
|
|
|
edge_iterator& operator++() |
|
{ |
|
++current_edge.idx; |
|
while (current_edge.idx == end_of_this_vertex && local_src < num_vertices(*graph)-1) { |
|
++local_src; |
|
current_edge.src = graph->local_to_global_vertex(local_src); |
|
end_of_this_vertex = graph->base().m_forward.m_rowstart[local_src + 1]; |
|
} |
|
return *this; |
|
} |
|
|
|
edge_iterator operator++(int) { |
|
edge_iterator temp = *this; |
|
++*this; |
|
return temp; |
|
} |
|
|
|
private: |
|
const compressed_sparse_row_graph* graph; |
|
EdgeIndex local_src; |
|
edge_descriptor current_edge; |
|
EdgeIndex end_of_this_vertex; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type |
|
num_edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return g.base().m_forward.m_column.size(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator> |
|
edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator ei; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edgedesc; |
|
if (g.base().m_forward.m_rowstart.size() == 1 || |
|
g.base().m_forward.m_column.empty()) { |
|
return std::make_pair(ei(), ei()); |
|
} else { |
|
// Find the first vertex that has outgoing edges |
|
Vertex src = 0; |
|
while (g.base().m_forward.m_rowstart[src + 1] == 0) ++src; |
|
return std::make_pair(ei(g, edgedesc(src, 0), g.base().m_forward.m_rowstart[src + 1]), |
|
ei(g, edgedesc(num_vertices(g), g.base().m_forward.m_column.size()), 0)); |
|
} |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Graph constructors |
|
|
|
// Returns true if a vertex belongs to a process according to a distribution |
|
template <typename OwnerMap, typename ProcessId> |
|
struct local_vertex { |
|
|
|
local_vertex(OwnerMap owner, ProcessId id) |
|
: owner(owner), id(id) {} |
|
|
|
template <typename Vertex> |
|
bool operator()(Vertex x) |
|
{ return get(owner, x) == id; } |
|
|
|
template <typename Vertex> |
|
bool operator()(Vertex x) const |
|
{ return get(owner, x) == id; } |
|
|
|
private: |
|
OwnerMap owner; |
|
ProcessId id; |
|
}; |
|
|
|
// Returns true if a vertex belongs to a process according to a distribution |
|
template <typename OwnerMap, typename ProcessId> |
|
struct local_edge { |
|
|
|
local_edge(OwnerMap owner, ProcessId id) |
|
: owner(owner), id(id) {} |
|
|
|
template <typename Vertex> |
|
bool operator()(std::pair<Vertex, Vertex>& x) |
|
{ return get(owner, x.first) == id; } |
|
|
|
template <typename Vertex> |
|
bool operator()(const std::pair<Vertex, Vertex>& x) const |
|
{ return get(owner, x.first) == id; } |
|
|
|
private: |
|
OwnerMap owner; |
|
ProcessId id; |
|
}; |
|
|
|
// Turns an index iterator into a vertex iterator |
|
template<typename IndexIterator, typename Graph> |
|
class index_to_vertex_iterator { |
|
|
|
public: |
|
typedef std::input_iterator_tag iterator_category; |
|
typedef typename graph_traits<Graph>::vertex_descriptor Vertex; |
|
typedef std::pair<Vertex, Vertex> value_type; |
|
typedef const value_type& reference; |
|
typedef const value_type* pointer; |
|
typedef void difference_type; |
|
|
|
index_to_vertex_iterator(IndexIterator index, |
|
const Graph& g) |
|
: index(index), g(g), current(to_edge(*index)) {} |
|
|
|
reference operator*() { current = to_edge(*index); return current; } |
|
pointer operator->() { current = to_edge(*index); return ¤t; } |
|
|
|
index_to_vertex_iterator& operator++() |
|
{ |
|
++index; |
|
return *this; |
|
} |
|
|
|
index_to_vertex_iterator operator++(int) |
|
{ |
|
index_to_vertex_iterator temp(*this); |
|
++(*this); |
|
return temp; |
|
} |
|
|
|
bool operator==(const index_to_vertex_iterator& other) const |
|
{ return index == other.index; } |
|
|
|
bool operator!=(const index_to_vertex_iterator& other) const |
|
{ return !(*this == other); } |
|
|
|
private: |
|
value_type to_edge(const typename std::iterator_traits<IndexIterator>::value_type& x) |
|
{ return std::make_pair(vertex(x.first, g), vertex(x.second, g)); } |
|
|
|
IndexIterator index; |
|
const Graph& g; |
|
value_type current; |
|
}; |
|
|
|
template <typename Distribution, typename Graph> |
|
struct index_to_vertex_func { |
|
|
|
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; |
|
typedef typename boost::graph_traits<Graph>::vertices_size_type vertices_size_type; |
|
typedef std::pair<vertex_descriptor, vertex_descriptor> result_type; |
|
typedef std::pair<vertices_size_type, vertices_size_type> base_iterator_type; |
|
|
|
index_to_vertex_func(const Distribution& dist, const Graph& g) |
|
: dist(dist), g(g) {} |
|
|
|
|
|
result_type operator()(const base_iterator_type& p) const |
|
{ |
|
return std::make_pair(vertex(p.first, g), vertex(p.second, g)); |
|
} |
|
|
|
private: |
|
const Distribution& dist; |
|
const Graph& g; |
|
}; |
|
|
|
// NGE: This method only works with iterators that have a difference_type, |
|
// the index_to_vertex_iterator class above is retained for compatibility |
|
// with BGL generators which have no difference_type |
|
template <typename IndexIterator, typename Distribution, typename Graph> |
|
boost::transform_iterator<index_to_vertex_func<Distribution, Graph>, IndexIterator> |
|
make_index_to_vertex_iterator(IndexIterator it, const Distribution& dist, |
|
const Graph& g) { |
|
return boost::make_transform_iterator( |
|
it, index_to_vertex_func<Distribution, Graph>(dist, g)); |
|
} |
|
|
|
// Forward declaration of csr_vertex_owner_map |
|
template<typename ProcessID, typename Key> class csr_vertex_owner_map; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename InputIterator, typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename EdgePropertyIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
ep_iter, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
ep_iter, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
edges_size_type numedges, // This is not used as there is no appropriate BGL ctor |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_sorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename InputIterator, typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_sorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename EdgePropertyIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
edges_size_type numedges, // This is not used as there is no appropriate BGL ctor |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_sorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
ep_iter, |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_sorted_t, |
|
InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_sorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
ep_iter, |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename MultiPassInputIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_multi_pass_global, |
|
make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this), |
|
make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename MultiPassInputIterator, typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_multi_pass_global, |
|
make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this), |
|
make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename MultiPassInputIterator, typename EdgePropertyIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_multi_pass_global, |
|
make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this), |
|
make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this), |
|
ep_iter, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename MultiPassInputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t, |
|
MultiPassInputIterator edge_begin, |
|
MultiPassInputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_multi_pass_global, |
|
make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this), |
|
make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this), |
|
ep_iter, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename Source> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(m_distribution.block_size(process_id(m_process_group), numverts)) |
|
{ |
|
// Convert linear indices to global indices |
|
for (edges_size_type i = 0; i < sources.size(); ++i) { |
|
sources[i] = m_distribution.local(sources[i]); |
|
targets[i] = make_vertex_descriptor(m_distribution(targets[i]), |
|
m_distribution.local(targets[i])); |
|
} |
|
|
|
m_base.assign_sources_and_targets_global( |
|
sources, targets, m_distribution.block_size(process_id(m_process_group), numverts), |
|
identity_property_map()); |
|
|
|
// TODO: set property on m_base? |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename Distribution, typename Source> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(m_distribution.block_size(process_id(m_process_group), numverts)) |
|
{ |
|
// Convert linear indices to global indices |
|
for (edges_size_type i = 0; i < sources.size(); ++i) { |
|
sources[i] = m_distribution.local(sources[i]); |
|
targets[i] = make_vertex_descriptor(m_distribution(targets[i]), |
|
m_distribution.local(targets[i])); |
|
} |
|
|
|
m_base.assign_sources_and_targets_global( |
|
sources, targets, m_distribution.block_size(process_id(m_process_group), numverts), |
|
identity_property_map()); |
|
|
|
// TODO: set property on m_base? |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename Source> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
std::vector<edge_bundled>& edge_props, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(m_distribution.block_size(process_id(m_process_group), numverts)) |
|
{ |
|
// Convert linear indices to global indices |
|
for (edges_size_type i = 0; i < sources.size(); ++i) { |
|
sources[i] = m_distribution.local(sources[i]); |
|
targets[i] = make_vertex_descriptor(m_distribution(targets[i]), |
|
m_distribution.local(targets[i])); |
|
} |
|
|
|
m_base.assign_sources_and_targets_global( |
|
sources, targets, edge_props, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
identity_property_map()); |
|
|
|
// TODO: set property on m_base? |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template <typename Distribution, typename Source> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t, |
|
std::vector<Source>& sources, |
|
std::vector<vertex_descriptor>& targets, |
|
std::vector<edge_bundled>& edge_props, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(m_distribution.block_size(process_id(m_process_group), numverts)) |
|
{ |
|
// Convert linear indices to global indices |
|
for (edges_size_type i = 0; i < sources.size(); ++i) { |
|
sources[i] = m_distribution.local(sources[i]); |
|
targets[i] = make_vertex_descriptor(m_distribution(targets[i]), |
|
m_distribution.local(targets[i])); |
|
} |
|
|
|
m_base.assign_sources_and_targets_global( |
|
sources, targets, edge_props, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
identity_property_map()); |
|
|
|
// TODO: set property on m_base? |
|
} |
|
|
|
// |
|
// Old (untagged) ctors, these default to the unsorted sequential ctors |
|
// |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
|
|
{ |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename EdgePropertyIterator> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
|
|
m_distribution(parallel::block(m_process_group, numverts)), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
ep_iter, |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
template<typename InputIterator, typename EdgePropertyIterator, |
|
typename Distribution> |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE:: |
|
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, |
|
EdgePropertyIterator ep_iter, |
|
vertices_size_type numverts, |
|
const ProcessGroup& pg, |
|
const Distribution& dist, |
|
const GraphProperty& prop) |
|
: m_process_group(pg), |
|
m_distribution(dist), |
|
m_base(edges_are_unsorted_global, |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this), |
|
index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this), |
|
m_distribution.block_size(process_id(m_process_group), numverts), |
|
get(vertex_local, *this), |
|
local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>, |
|
process_id_type> (get(vertex_owner, *this), process_id(pg)), |
|
prop) |
|
{ |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Vertex Global Property Map |
|
template<typename ProcessID, typename Key> |
|
class csr_vertex_global_map |
|
{ |
|
public: |
|
// ----------------------------------------------------------------- |
|
// Readable Property Map concept requirements |
|
typedef std::pair<ProcessID, Key> value_type; |
|
typedef value_type reference; |
|
typedef Key key_type; |
|
typedef readable_property_map_tag category; |
|
}; |
|
|
|
template<typename ProcessID, typename Key> |
|
inline std::pair<ProcessID, Key> |
|
get(csr_vertex_global_map<ProcessID, Key>, |
|
typename csr_vertex_global_map<ProcessID, Key>::key_type k) |
|
{ |
|
const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits; |
|
const Key local_index_mask = Key(-1) >> processor_bits; |
|
|
|
return std::pair<ProcessID, Key>(k >> local_index_bits, |
|
k & local_index_mask); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t> |
|
{ |
|
public: |
|
typedef csr_vertex_global_map< |
|
typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type; |
|
typedef type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::type |
|
get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t> |
|
::type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
std::pair<typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> |
|
get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_global, |
|
const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g), |
|
k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::const_type |
|
get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t> |
|
::const_type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
std::pair<typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> |
|
get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
vertex_descriptor; |
|
typedef std::pair<typename ProcessGroup::process_id_type, vertex_descriptor> |
|
result_type; |
|
const int local_index_bits = |
|
sizeof(vertex_descriptor) * CHAR_BIT - processor_bits; |
|
const vertex_descriptor local_index_mask = |
|
vertex_descriptor(-1) >> processor_bits; |
|
|
|
return result_type(k >> local_index_bits, k & local_index_mask); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Extra, common functions |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
vertex(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type i, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return g.make_vertex_descriptor(g.distribution()(i), |
|
g.distribution().local(i)); |
|
} |
|
|
|
// Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i)) |
|
// time |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator> |
|
edge_range(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type EdgeIndex; |
|
typedef typename std::vector<Vertex>::const_iterator adj_iter; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edge_desc; |
|
std::pair<adj_iter, adj_iter> raw_adjacencies = adjacent_vertices(i, g); |
|
std::pair<adj_iter, adj_iter> adjacencies = |
|
std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j); |
|
EdgeIndex idx_begin = adjacencies.first - g.base().m_forward.m_column.begin(); |
|
EdgeIndex idx_end = adjacencies.second - g.base().m_forward.m_column.begin(); |
|
return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)), |
|
out_edge_iter(edge_desc(i, idx_end))); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor, bool> |
|
edge(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j, |
|
const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; |
|
std::pair<out_edge_iter, out_edge_iter> range = edge_range(i, j, g); |
|
if (range.first == range.second) |
|
return std::make_pair(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor(), |
|
false); |
|
else |
|
return std::make_pair(*range.first, true); |
|
} |
|
|
|
// A helper that turns requests for property maps for const graphs |
|
// into property maps for non-const graphs. |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Property> |
|
class property_map<const BOOST_DISTRIB_CSR_GRAPH_TYPE, Property> |
|
{ |
|
public: |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Property> |
|
::const_type type; |
|
typedef type const_type; |
|
}; |
|
|
|
// ----------------------------------------------------------------- |
|
// Structural modifiers |
|
|
|
#if 0 |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
add_vertex(BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.add_vertex(); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
add_vertex(const typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_bundled& p, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.add_vertex(p); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
add_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type count, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.add_vertices(count); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator> |
|
void |
|
add_edges(InputIterator first, InputIterator last, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ g.add_edges(first, last); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator, |
|
typename EdgePropertyIterator> |
|
void |
|
add_edges(InputIterator first, InputIterator last, |
|
EdgePropertyIterator ep_iter, |
|
EdgePropertyIterator ep_iter_end, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.add_edges(first, last, ep_iter, ep_iter_end); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator> |
|
void |
|
add_edges_sorted(InputIterator first, InputIterator last, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ return g.add_edges_sorted(first, last); } |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator, |
|
typename EdgePropertyIterator> |
|
void |
|
add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted, |
|
EdgePropertyIterator ep_iter_sorted, |
|
BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ g.add_edges_sorted(first_sorted, last_sorted, ep_iter_sorted); } |
|
#endif |
|
|
|
// ----------------------------------------------------------------- |
|
// Vertex Owner Property Map |
|
template<typename ProcessID, typename Key> |
|
class csr_vertex_owner_map |
|
{ |
|
public: |
|
// ----------------------------------------------------------------- |
|
// Readable Property Map concept requirements |
|
typedef ProcessID value_type; |
|
typedef value_type reference; |
|
typedef Key key_type; |
|
typedef readable_property_map_tag category; |
|
}; |
|
|
|
template<typename ProcessID, typename Key> |
|
inline ProcessID |
|
get(csr_vertex_owner_map<ProcessID, Key> pm, |
|
typename csr_vertex_owner_map<ProcessID, Key>::key_type k) |
|
{ |
|
const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits; |
|
return k >> local_index_bits; |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t> |
|
{ |
|
public: |
|
typedef csr_vertex_owner_map< |
|
typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type; |
|
typedef type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::type |
|
get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t> |
|
::type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename ProcessGroup::process_id_type |
|
get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_owner, |
|
const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g), |
|
k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::const_type |
|
get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t> |
|
::const_type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename ProcessGroup::process_id_type |
|
get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
vertex_descriptor; |
|
const int local_index_bits = |
|
sizeof(vertex_descriptor) * CHAR_BIT - processor_bits; |
|
return k >> local_index_bits; |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Vertex Local Property Map |
|
template<typename Key> |
|
class csr_vertex_local_map |
|
{ |
|
public: |
|
// ----------------------------------------------------------------- |
|
// Readable Property Map concept requirements |
|
typedef Key value_type; |
|
typedef value_type reference; |
|
typedef Key key_type; |
|
typedef readable_property_map_tag category; |
|
}; |
|
|
|
template<typename Key> |
|
inline Key |
|
get(csr_vertex_local_map<Key> pm, |
|
typename csr_vertex_local_map<Key>::key_type k) |
|
{ |
|
const Key local_index_mask = Key(-1) >> processor_bits; |
|
return k & local_index_mask; |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> |
|
{ |
|
public: |
|
typedef csr_vertex_local_map< |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type; |
|
typedef type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::type |
|
get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> |
|
::type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_local, |
|
const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g), |
|
k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::const_type |
|
get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> |
|
::const_type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
vertex_descriptor; |
|
const vertex_descriptor local_index_mask = |
|
vertex_descriptor(-1) >> processor_bits; |
|
return k & local_index_mask; |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Vertex Index Property Map |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t> |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, |
|
vertex_global_t>::const_type |
|
global_map; |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type |
|
process_group_type; |
|
|
|
typedef property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> local; |
|
|
|
public: |
|
typedef local_property_map<process_group_type, |
|
global_map, |
|
typename local::type> type; |
|
typedef local_property_map<process_group_type, |
|
global_map, |
|
typename local::const_type> const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::type |
|
get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t> |
|
::type result_type; |
|
|
|
return result_type(g.process_group(), get(vertex_global, g), |
|
get(vertex_local, g)); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type |
|
get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_local, g, k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::const_type |
|
get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t> |
|
::const_type result_type; |
|
return result_type(g.process_group(), get(vertex_global, g), |
|
get(vertex_local, g)); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type |
|
get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_local, g, k); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Vertex Local Index Property Map |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t> |
|
: public property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> { }; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::type |
|
get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return get(vertex_local, g); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type |
|
get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_local, g, k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::const_type |
|
get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
return get(vertex_local, g); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type |
|
get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k) |
|
{ |
|
return get(vertex_local, g, k); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Edge Global Property Map |
|
template<typename ProcessID, typename Vertex, typename EdgeIndex> |
|
class csr_edge_global_map |
|
{ |
|
public: |
|
// ----------------------------------------------------------------- |
|
// Readable Property Map concept requirements |
|
typedef std::pair<ProcessID, EdgeIndex> value_type; |
|
typedef value_type reference; |
|
typedef detail::csr_edge_descriptor<Vertex, EdgeIndex> key_type; |
|
typedef readable_property_map_tag category; |
|
}; |
|
|
|
template<typename ProcessID, typename Vertex, typename EdgeIndex> |
|
inline std::pair<ProcessID, EdgeIndex> |
|
get(csr_edge_global_map<ProcessID, Vertex, EdgeIndex> pm, |
|
typename csr_edge_global_map<ProcessID, Vertex, EdgeIndex>::key_type k) |
|
{ |
|
const int local_index_bits = sizeof(Vertex) * CHAR_BIT - processor_bits; |
|
return std::pair<ProcessID, EdgeIndex>(k.src >> local_index_bits, k.idx); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t> |
|
{ |
|
public: |
|
typedef csr_edge_global_map< |
|
typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> type; |
|
typedef type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::type |
|
get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t> |
|
::type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
std::pair<typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> |
|
get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k) |
|
{ |
|
return get(edge_global, |
|
const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g), |
|
k); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::const_type |
|
get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t> |
|
::const_type result_type; |
|
return result_type(); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
std::pair<typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> |
|
get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k) |
|
{ |
|
typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor |
|
vertex_descriptor; |
|
|
|
const int local_index_bits = |
|
sizeof(vertex_descriptor) * CHAR_BIT - processor_bits; |
|
|
|
typedef std::pair<typename ProcessGroup::process_id_type, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> |
|
result_type; |
|
|
|
return result_type(k.src >> local_index_bits, k.idx); |
|
} |
|
|
|
// ----------------------------------------------------------------- |
|
// Edge Index Property Map |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t> |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t> |
|
::type global_map; |
|
|
|
public: |
|
typedef local_property_map< |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type, |
|
global_map, |
|
identity_property_map> type; |
|
typedef type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::type |
|
get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t> |
|
::type result_type; |
|
return result_type(g.process_group(), get(edge_global, g), |
|
identity_property_map()); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type |
|
get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k) |
|
{ |
|
return k.idx; |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::const_type |
|
get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t> |
|
::const_type result_type; |
|
return result_type(g.process_group(), get(edge_global, g), |
|
identity_property_map()); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type |
|
get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g, |
|
typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k) |
|
{ |
|
return k.idx; |
|
} |
|
|
|
/* Common traits for getting vertex_bundle and edge_bundle maps */ |
|
|
|
namespace detail { |
|
template <typename Graph, typename T> struct get_bundles; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename T> |
|
class get_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE, T> { |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph; |
|
typedef typename Graph::process_group_type process_group_type; |
|
|
|
// Extract the global property map for our key type. |
|
typedef typename property_map<Graph, vertex_global_t>::const_type vertex_global_map; |
|
typedef typename property_traits<vertex_global_map>::value_type vertex_locator; |
|
typedef typename property_map<Graph, edge_global_t>::const_type edge_global_map; |
|
typedef typename property_traits<edge_global_map>::value_type edge_locator; |
|
|
|
// Build the local property map |
|
typedef bundle_property_map<std::vector<VertexProperty>, |
|
typename vertex_locator::second_type, |
|
VertexProperty, |
|
T> vertex_local_pmap; |
|
|
|
// Build the local const property map |
|
typedef bundle_property_map<const std::vector<VertexProperty>, |
|
typename vertex_locator::second_type, |
|
VertexProperty, |
|
const T> vertex_local_const_pmap; |
|
|
|
// Build the local property map |
|
typedef bundle_property_map<std::vector<EdgeProperty>, |
|
typename edge_locator::second_type, |
|
EdgeProperty, |
|
T> edge_local_pmap; |
|
|
|
// Build the local const property map |
|
typedef bundle_property_map<const std::vector<EdgeProperty>, |
|
typename edge_locator::second_type, |
|
EdgeProperty, |
|
const T> edge_local_const_pmap; |
|
|
|
public: |
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, vertex_global_map, vertex_local_pmap> vertex_map_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, vertex_global_map, vertex_local_const_pmap> vertex_map_const_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, edge_global_map, edge_local_pmap> edge_map_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, edge_global_map, edge_local_const_pmap> edge_map_const_type; |
|
|
|
}; |
|
|
|
template <typename Graph> struct get_full_bundles; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
class get_full_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE> { // For vertex_bundle_t and edge_bundle_t |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph; |
|
typedef typename Graph::process_group_type process_group_type; |
|
|
|
// Extract the global property map for our key type. |
|
typedef typename property_map<Graph, vertex_global_t>::const_type vertex_global_map; |
|
typedef typename property_traits<vertex_global_map>::value_type vertex_locator; |
|
typedef typename property_map<Graph, edge_global_t>::const_type edge_global_map; |
|
typedef typename property_traits<edge_global_map>::value_type edge_locator; |
|
|
|
// Build the local property maps |
|
typedef typename property_map<typename Graph::base_type, vertex_bundle_t>::type vertex_local_pmap; |
|
typedef typename property_map<typename Graph::base_type, vertex_bundle_t>::const_type vertex_local_const_pmap; |
|
typedef typename property_map<typename Graph::base_type, edge_bundle_t>::type edge_local_pmap; |
|
typedef typename property_map<typename Graph::base_type, edge_bundle_t>::const_type edge_local_const_pmap; |
|
|
|
public: |
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, vertex_global_map, vertex_local_pmap> vertex_map_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, vertex_global_map, vertex_local_const_pmap> vertex_map_const_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, edge_global_map, edge_local_pmap> edge_map_type; |
|
|
|
typedef ::boost::parallel::distributed_property_map< |
|
process_group_type, edge_global_map, edge_local_const_pmap> edge_map_const_type; |
|
|
|
}; |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
struct property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_bundle_t> |
|
{ |
|
typedef typename detail::get_full_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE>::vertex_map_type type; |
|
typedef typename detail::get_full_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE>::vertex_map_const_type const_type; |
|
}; |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS> |
|
struct property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_bundle_t> |
|
{ |
|
typedef typename detail::get_full_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE>::edge_map_type type; |
|
typedef typename detail::get_full_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE>::edge_map_const_type const_type; |
|
}; |
|
|
|
// ----------------------------------------------------------------- |
|
// Bundled Properties |
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle> |
|
class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, T Bundle::*> |
|
{ |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph; |
|
typedef typename Graph::process_group_type process_group_type; |
|
|
|
public: |
|
typedef typename mpl::if_<detail::is_vertex_bundle<VertexProperty, |
|
EdgeProperty, |
|
Bundle>, |
|
typename detail::get_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE, T>::vertex_map_type, |
|
typename detail::get_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE, T>::edge_map_type> |
|
::type type; |
|
|
|
typedef typename mpl::if_<detail::is_vertex_bundle<VertexProperty, |
|
EdgeProperty, |
|
Bundle>, |
|
typename detail::get_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE, T>::vertex_map_const_type, |
|
typename detail::get_bundles<BOOST_DISTRIB_CSR_GRAPH_TYPE, T>::edge_map_const_type> |
|
::type const_type; |
|
}; |
|
|
|
namespace detail { |
|
// Retrieve the local bundle_property_map corresponding to a |
|
// non-const vertex property. |
|
template<typename Graph, typename T, typename Bundle> |
|
inline bundle_property_map<std::vector<typename Graph::vertex_bundled>, |
|
typename Graph::vertex_descriptor, |
|
typename Graph::vertex_bundled, T> |
|
get_distrib_csr_bundle(T Bundle::* p, Graph& g, mpl::true_) |
|
{ |
|
typedef bundle_property_map<std::vector<typename Graph::vertex_bundled>, |
|
typename Graph::vertex_descriptor, |
|
typename Graph::vertex_bundled, T> result_type; |
|
return result_type(&g.base().vertex_properties().m_vertex_properties, p); |
|
} |
|
|
|
// Retrieve the local bundle_property_map corresponding to a |
|
// const vertex property. |
|
template<typename Graph, typename T, typename Bundle> |
|
inline bundle_property_map<const std::vector<typename Graph::vertex_bundled>, |
|
typename Graph::vertex_descriptor, |
|
typename Graph::vertex_bundled, const T> |
|
get_distrib_csr_bundle(T Bundle::* p, const Graph& g, mpl::true_) |
|
{ |
|
typedef bundle_property_map< |
|
const std::vector<typename Graph::vertex_bundled>, |
|
typename Graph::vertex_descriptor, |
|
typename Graph::vertex_bundled, const T> result_type; |
|
return result_type(&g.base().vertex_properties().m_vertex_properties, p); |
|
} |
|
|
|
// Retrieve the local bundle_property_map corresponding to a |
|
// non-const edge property. |
|
template<typename Graph, typename T, typename Bundle> |
|
inline bundle_property_map<std::vector<typename Graph::edge_bundled>, |
|
typename Graph::edges_size_type, |
|
typename Graph::edge_bundled, T> |
|
get_distrib_csr_bundle(T Bundle::* p, Graph& g, mpl::false_) |
|
{ |
|
typedef bundle_property_map<std::vector<typename Graph::edge_bundled>, |
|
typename Graph::edges_size_type, |
|
typename Graph::edge_bundled, T> result_type; |
|
return result_type(&g.base().edge_properties().m_edge_properties, p); |
|
} |
|
|
|
// Retrieve the local bundle_property_map corresponding to a |
|
// const edge property. |
|
template<typename Graph, typename T, typename Bundle> |
|
inline bundle_property_map<const std::vector<typename Graph::edge_bundled>, |
|
typename Graph::edges_size_type, |
|
typename Graph::edge_bundled, const T> |
|
get_distrib_csr_bundle(T Bundle::* p, const Graph& g, mpl::false_) |
|
{ |
|
typedef bundle_property_map< |
|
const std::vector<typename Graph::edge_bundled>, |
|
typename Graph::edges_size_type, |
|
typename Graph::edge_bundled, const T> result_type; |
|
return result_type(&g.base().edge_properties().m_edge_properties, p); |
|
} |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle> |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, T Bundle::*>::type |
|
get(T Bundle::* p, BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph; |
|
typedef typename property_map<Graph, T Bundle::*>::type result_type; |
|
|
|
// Resolver |
|
typedef typename property_traits<result_type>::value_type value_type; |
|
typedef typename property_reduce<T Bundle::*>::template apply<value_type> |
|
reduce; |
|
|
|
typedef typename property_traits<result_type>::key_type descriptor; |
|
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; |
|
typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>, |
|
vertex_global_t, edge_global_t>::type |
|
global_map_t; |
|
|
|
return result_type(g.process_group(), get(global_map_t(), g), |
|
detail::get_distrib_csr_bundle |
|
(p, g, mpl::bool_<is_same<descriptor, |
|
vertex_descriptor>::value>()), |
|
reduce()); |
|
} |
|
|
|
template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle> |
|
typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, T Bundle::*>::const_type |
|
get(T Bundle::* p, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g) |
|
{ |
|
typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph; |
|
typedef typename property_map<Graph, T Bundle::*>::const_type result_type; |
|
|
|
// Resolver |
|
typedef typename property_traits<result_type>::value_type value_type; |
|
typedef typename property_reduce<T Bundle::*>::template apply<value_type> |
|
reduce; |
|
|
|
typedef typename property_traits<result_type>::key_type descriptor; |
|
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; |
|
typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>, |
|
vertex_global_t, edge_global_t>::type |
|
global_map_t; |
|
|
|
return result_type(g.process_group(), get(global_map_t(), g), |
|
detail::get_distrib_csr_bundle |
|
(p, g, mpl::bool_<is_same<descriptor, |
|
vertex_descriptor>::value>()), |
|
reduce()); |
|
} |
|
|
|
namespace mpi { |
|
template<typename Vertex, typename EdgeIndex> |
|
struct is_mpi_datatype<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> > |
|
: mpl::true_ { }; |
|
} |
|
|
|
namespace serialization { |
|
template<typename Vertex, typename EdgeIndex> |
|
struct is_bitwise_serializable<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> > |
|
: mpl::true_ { }; |
|
|
|
template<typename Vertex, typename EdgeIndex> |
|
struct implementation_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> > |
|
: mpl::int_<object_serializable> {} ; |
|
|
|
template<typename Vertex, typename EdgeIndex> |
|
struct tracking_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> > |
|
: mpl::int_<track_never> {} ; |
|
|
|
} |
|
|
|
} // end namespace boost |
|
|
|
#endif // BOOST_GRAPH_DISTRIBUTED_CSR_HPP
|
|
|