Commit 4d212c1b authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Switch from boost::adjacency_list<> to custom made and lightweight adj_list<>

Dumping boost::adjacency_list<> improves memory usage by a factor of
two, and also slightly improves performance in some cases.
parent 5b67db19
......@@ -30,23 +30,6 @@ namespace graph_tool
using namespace std;
using namespace boost;
// this is to avoid using GraphWrap as the underlying graph type
struct get_graph_t
{
template <class Graph>
struct apply
{
typedef Graph type;
};
template <class Graph>
struct apply<GraphWrap<Graph> >
{
typedef Graph type;
};
};
class AStarVisitorWrapper
{
public:
......@@ -54,54 +37,54 @@ public:
: _gi(gi), _vis(vis) {}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
void initialize_vertex(Vertex u, const Graph&)
{
_vis.attr("initialize_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g)
void discover_vertex(Vertex u, const Graph&)
{
_vis.attr("discover_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g)
void examine_vertex(Vertex u, const Graph&)
{
_vis.attr("examine_vertex")(PythonVertex(_gi, u));
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
void examine_edge(Edge e, const Graph&)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g)
void edge_relaxed(Edge e, const Graph&)
{
_vis.attr("edge_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g)
void edge_not_relaxed(Edge e, const Graph& g)
{
_vis.attr("edge_not_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void black_target(Edge e, Graph& g)
void black_target(Edge e, const Graph&)
{
_vis.attr("black_target")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g)
void finish_vertex(Vertex u, const Graph&)
{
_vis.attr("finish_vertex")(PythonVertex(_gi, u));
}
......
......@@ -48,7 +48,7 @@ struct do_astar_search
checked_vector_property_map<default_color_type,
typeof(get(vertex_index, g))>
color(get(vertex_index, g._g));
color(get(vertex_index, g));
typedef typename property_map_type::
apply<int32_t, typeof(get(vertex_index, g))>::type pred_t;
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
......
......@@ -37,38 +37,38 @@ public:
: _gi(gi), _vis(vis) {}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
void examine_edge(Edge e, const Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g)
void edge_relaxed(Edge e, const Graph& g)
{
_vis.attr("edge_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g)
void edge_not_relaxed(Edge e, const Graph& g)
{
_vis.attr("edge_not_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_minimized(Edge e, Graph& g)
void edge_minimized(Edge e, const Graph& g)
{
_vis.attr("edge_minimized")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_minimized(Edge e, Graph& g)
void edge_not_minimized(Edge e, const Graph& g)
{
_vis.attr("edge_not_minimized")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
private:
......
......@@ -37,60 +37,60 @@ public:
: _gi(gi), _vis(vis) {}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
void initialize_vertex(Vertex u, const Graph& g)
{
_vis.attr("initialize_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g)
void discover_vertex(Vertex u, const Graph& g)
{
_vis.attr("discover_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g)
void examine_vertex(Vertex u, const Graph& g)
{
_vis.attr("examine_vertex")(PythonVertex(_gi, u));
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
void examine_edge(Edge e, const Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g)
void tree_edge(Edge e, const Graph& g)
{
_vis.attr("tree_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void non_tree_edge(Edge e, Graph& g)
void non_tree_edge(Edge e, const Graph& g)
{
_vis.attr("non_tree_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g)
void gray_target(Edge e, const Graph& g)
{
_vis.attr("gray_target")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void black_target(Edge e, Graph& g)
void black_target(Edge e, const Graph& g)
{
_vis.attr("black_target")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g)
void finish_vertex(Vertex u, const Graph& g)
{
_vis.attr("finish_vertex")(PythonVertex(_gi, u));
}
......
......@@ -48,28 +48,28 @@ public:
void examine_edge(Edge e, const Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void tree_edge(Edge e, const Graph& g)
{
_vis.attr("tree_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void back_edge(Edge e, const Graph& g)
{
_vis.attr("back_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void forward_or_cross_edge(Edge e, const Graph& g)
{
_vis.attr("forward_or_cross_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Vertex, class Graph>
......
......@@ -37,46 +37,46 @@ public:
: _gi(gi), _vis(vis) {}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
void initialize_vertex(Vertex u, const Graph& g)
{
_vis.attr("initialize_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g)
void discover_vertex(Vertex u, const Graph& g)
{
_vis.attr("discover_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g)
void examine_vertex(Vertex u, const Graph& g)
{
_vis.attr("examine_vertex")(PythonVertex(_gi, u));
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
void examine_edge(Edge e, const Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g)
void edge_relaxed(Edge e, const Graph& g)
{
_vis.attr("edge_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g)
void edge_not_relaxed(Edge e, const Graph& g)
{
_vis.attr("edge_not_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
(PythonEdge<Graph>(_gi, e));
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g)
void finish_vertex(Vertex u, const Graph& g)
{
_vis.attr("finish_vertex")(PythonVertex(_gi, u));
}
......
......@@ -94,10 +94,11 @@ struct get_sampled_distance_histogram
vertex_t v;
tr1::uniform_int<size_t> randint(0, sources.size()-1);
{
size_t j;
#pragma omp critical
size_t i = randint(rng);
v = sources[i];
swap(sources[i], sources.back());
j = randint(rng);
v = sources[j];
swap(sources[j], sources.back());
sources.pop_back();
}
......
......@@ -25,17 +25,25 @@ using namespace std;
using namespace boost;
using namespace graph_tool;
struct deg_check : public boost::static_visitor<>
{
void operator()(boost::any a) const
{
if (!belongs<vertex_scalar_properties>()(a))
throw ValueException("Vertex property must be of scalar type.");
}
template<class T>
void operator()(const T&) const {}
};
// this will return the vertex histogram of degrees or scalar properties
python::object
get_vertex_histogram(GraphInterface& gi, GraphInterface::deg_t deg,
const vector<long double>& bins)
{
try
{
if (!belongs<vertex_scalar_properties>()(get<boost::any>(deg)))
throw ValueException("Vertex property must be of scalar type.");
}
catch (boost::bad_get&){}
boost::apply_visitor(deg_check(), deg);
python::object hist;
python::object ret_bins;
......
......@@ -30,21 +30,15 @@ using namespace graph_tool;
void do_label_parallel_edges(GraphInterface& gi, boost::any property,
bool mark_only, bool count_all)
{
GraphInterface::edge_index_map_t edge_index =
any_cast<GraphInterface::edge_index_map_t>(gi.GetEdgeIndex());
run_action<>()(gi, bind<void>(label_parallel_edges(), _1,
edge_index, _2, mark_only, count_all),
edge_scalar_properties())(property);
run_action<>()(gi, bind<void>(label_parallel_edges(), _1, _2, mark_only, count_all),
writable_edge_scalar_properties())(property);
}
void do_label_self_loops(GraphInterface& gi, boost::any property,
bool mark_only)
{
GraphInterface::edge_index_map_t edge_index =
any_cast<GraphInterface::edge_index_map_t>(gi.GetEdgeIndex());
run_action<>()(gi, bind<void>(label_self_loops(), _1,
edge_index, _2, mark_only),
edge_scalar_properties())(property);
run_action<>()(gi, bind<void>(label_self_loops(), _1, _2, mark_only),
writable_edge_scalar_properties())(property);
}
void do_remove_labeled_edges(GraphInterface& gi, boost::any property)
......
......@@ -29,9 +29,9 @@ using namespace boost;
// label parallel edges in the order they are found, starting from 1
struct label_parallel_edges
{
template <class Graph, class EdgeIndexMap, class ParallelMap>
void operator()(const Graph& g, EdgeIndexMap edge_index,
ParallelMap parallel, bool mark_only, bool count_all) const
template <class Graph, class ParallelMap>
void operator()(const Graph& g, ParallelMap parallel, bool mark_only,
bool count_all) const
{
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
......@@ -68,9 +68,8 @@ struct label_parallel_edges
// label self loops edges in the order they are found, starting from 1
struct label_self_loops
{
template <class Graph, class EdgeIndexMap, class SelfMap>
void operator()(const Graph& g, EdgeIndexMap edge_index,
SelfMap self, bool mark_only) const
template <class Graph, class SelfMap>
void operator()(const Graph& g, SelfMap self, bool mark_only) const
{
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
......
......@@ -29,7 +29,7 @@ class HistogramPropertyMap;
namespace boost
{
template <class PropertyMap>
struct property_traits<HistogramPropertyMap<PropertyMap> >:
struct property_traits<graph_tool::HistogramPropertyMap<PropertyMap> >:
public property_traits<PropertyMap> {};
}
......@@ -100,7 +100,7 @@ void put(HistogramPropertyMap<PropertyMap> pmap,
struct label_components
{
template <class Graph, class CompMap>
void operator()(const Graph& g, CompMap comp_map, vector<size_t>& hist)
void operator()(Graph& g, CompMap comp_map, vector<size_t>& hist)
const
{
typedef typename graph_traits<Graph>::directed_category
......@@ -112,17 +112,17 @@ struct label_components
}
template <class Graph, class CompMap>
void get_components(const Graph& g, CompMap comp_map,
void get_components(Graph& g, CompMap comp_map,
boost::true_type is_directed) const
{
strong_components(g, comp_map);
boost::strong_components(g, comp_map);
}
template <class Graph, class CompMap>
void get_components(const Graph& g, CompMap comp_map,
void get_components(Graph& g, CompMap comp_map,
boost::false_type is_directed) const
{
connected_components(g, comp_map);
boost::connected_components(g, comp_map);
}
};
......@@ -150,7 +150,7 @@ struct label_biconnected_components
};
template <class Graph, class CompMap, class ArtMap>
void operator()(const Graph& g, CompMap comp_map, ArtMap art_map,
void operator()(Graph& g, CompMap comp_map, ArtMap art_map,
vector<size_t>& hist) const
{
HistogramPropertyMap<CompMap> cm(comp_map, num_edges(g), hist);
......@@ -170,7 +170,7 @@ struct label_out_component
marker_visitor(CompMap comp) : _comp(comp) { }
template <class Vertex, class Graph>
void discover_vertex(Vertex u, const Graph& g)
void discover_vertex(Vertex u, const Graph&)
{
_comp[u] = true;
}
......@@ -179,7 +179,7 @@ struct label_out_component
};
template <class Graph, class CompMap>
void operator()(const Graph& g, CompMap comp_map, size_t root) const
void operator()(Graph& g, CompMap comp_map, size_t root) const
{
marker_visitor<CompMap> marker(comp_map);
breadth_first_search(g, vertex(root, g), visitor(marker));
......
......@@ -46,7 +46,7 @@ public:
template <class Graph>
void discover_vertex(typename graph_traits<Graph>::vertex_descriptor v,
Graph& g)
Graph&)
{
if (size_t(_pred[v]) == v)
return;
......@@ -74,7 +74,7 @@ public:
template <class Graph>
void examine_vertex(typename graph_traits<Graph>::vertex_descriptor u,
Graph& g)
Graph&)
{
if (_dist_map[u] > _max_dist)
{
......
......@@ -45,4 +45,3 @@ void dominator_tree(GraphInterface& gi, size_t entry, boost::any pred_map)
(gi, bind<void>(get_dominator_tree(), _1, entry, _2),
pred_properties())(pred_map);
}
......@@ -121,13 +121,13 @@ void get_kruskal_spanning_tree(GraphInterface& gi, boost::any weight_map,
if (weight_map.empty())
weight_map = cweight_t(1);
typedef mpl::push_back<edge_scalar_properties, cweight_t>::type
typedef mpl::push_back<writable_edge_scalar_properties, cweight_t>::type
weight_maps;
run_action<graph_tool::detail::never_directed>()
(gi, bind<void>(get_kruskal_min_span_tree(), _1, gi.GetVertexIndex(),
_2, _3),
weight_maps(), edge_scalar_properties())(weight_map, tree_map);
weight_maps(), writable_edge_scalar_properties())(weight_map, tree_map);
}
void get_prim_spanning_tree(GraphInterface& gi, size_t root,
......
......@@ -77,8 +77,8 @@ struct get_planar_embedding
}
template <class Graph, class VertexIndex, class EdgeIndex, class KurMap>
void operator()(Graph& g, VertexIndex vertex_index, EdgeIndex edge_index,
dummy_property_map embed_map, KurMap kur_map,
void operator()(Graph& g, VertexIndex, EdgeIndex edge_index,
dummy_property_map, KurMap kur_map,
bool& is_planar) const
{
edge_inserter<KurMap> kur_insert(kur_map);
......@@ -99,7 +99,7 @@ bool is_planar(GraphInterface& gi, boost::any embed_map, boost::any kur_map)
if (kur_map.empty())
kur_map = dummy_property_map();
typedef mpl::push_back<edge_scalar_properties,
typedef mpl::push_back<writable_edge_scalar_properties,
dummy_property_map>::type edge_map_types;
typedef mpl::push_back<vertex_scalar_vector_properties,
dummy_property_map>::type vertex_map_types;
......
......@@ -101,7 +101,7 @@ void random_matching(GraphInterface& gi, boost::any weight, boost::any match,
run_action<>()
(gi, bind<void>(do_random_matching(), _1, gi.GetVertexIndex(),
_2, _3, minimize, ref(rng)),
edge_props_t(), edge_scalar_properties())(weight, match);
edge_props_t(), writable_edge_scalar_properties())(weight, match);
}
void export_random_matching()
......
......@@ -42,5 +42,4 @@ void transitive_closure(GraphInterface& gi, GraphInterface& tcgi)
run_action<graph_tool::detail::always_directed>()
(gi, bind<void>(get_transitive_closure(), _1,
ref(tcgi.GetGraph())))();
tcgi.ReIndexEdges();
}
......@@ -494,7 +494,7 @@ class PropertyMap(object):
if self.__key_type == 'v':
n = g.num_vertices()
elif self.__key_type == 'e':
n = g._Graph__graph.GetMaxEdgeIndex() + 1
n = max(g.max_edge_index, 1)
else:
n = 1
g.pop_filter(edge=True, vertex=True)
......@@ -833,29 +833,27 @@ def edge_difference(g, prop, ediff=None):
Examples
--------
>>> from numpy.random import seed
>>> seed(42)
>>> gt.seed_rng(42)
>>> g = gt.random_graph(100, lambda: (3, 3))
>>> ediff = gt.edge_difference(g, g.vertex_index)
>>> print(ediff.a)
[ 89 67 83 -67 -75 -38 -7 -17 -78 -59 -1 6 -30 -4 -67 -9 -12 -17
-55 -42 -68 14 25 -7 -49 -1 -20 -58 10 24 -9 -40 17 3 -29 -47
-12 41 -34 24 -36 -12 38 -34 50 41 -34 -31 63 48 -14 21 3 12
52 -6 -26 16 63 54 -14 12 -16 52 27 -5 19 70 51 40 17 88
15 42 35 -26 -48 -10 89 18 19 54 5 85 12 77 70 18 54 11
73 51 62 63 10 81 49 57 89 52 4 67 14 28 33 51 62 77
66 44 -24 -8 19 62 -11 62 -18 -30 34 -23 -37 -31 -36 -18 8 -46
-1 -12 -49 -22 34 -26 -17 -63 -33 -53 19 -20 -23 -27 -12 -36 7 -83</