Commit 5dbe3935 authored by Tiago Peixoto's avatar Tiago Peixoto

Re-organize compilation units to reduce compile-time memory usage

parent 322a4f4b
......@@ -23,19 +23,22 @@ libgraph_tool_core_la_SOURCES = \
graph_exceptions.cc \
graph_bind.cc \
graph_copy.cc \
graph_copy_imp1.cc \
graph_filtering.cc \
graph_io.cc \
graph_openmp.cc \
graph_properties.cc \
graph_properties_imp1.cc \
graph_properties_imp2.cc \
graph_properties_imp3.cc \
graph_properties_imp4.cc \
graph_properties_copy.cc \
graph_properties_copy_imp1.cc \
graph_properties_group.cc \
graph_properties_ungroup.cc \
graph_properties_map_values.cc \
graph_properties_map_values_imp1.cc \
graph_python_interface.cc \
graph_python_interface_imp1.cc \
graph_python_interface_export.cc \
graph_selectors.cc \
graphml.cpp \
......@@ -55,6 +58,7 @@ libgraph_tool_core_la_include_HEADERS = \
graph_filtering.hh \
graph_io_binary.hh \
graph_properties.hh \
graph_properties_copy.hh \
graph_properties_group.hh \
graph_properties_map_values.hh \
graph_python_interface.hh \
......
......@@ -70,7 +70,8 @@ struct copy_vertex_property_dispatch
auto p_tgt = ptgt->get_unchecked(num_vertices(tgt));
int i, N = num_vertices(src);
#pragma omp parallel for default(shared) private(i) schedule(runtime) if (N > 100)
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, src);
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2015 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_properties.hh"
#include "graph_selectors.hh"
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/python/extract.hpp>
using namespace std;
using namespace boost;
using namespace graph_tool;
template <class GraphSrc, class GraphTgt, class IndexMap, class SrcIndexMap>
struct copy_edge_property_dispatch
{
copy_edge_property_dispatch(const GraphSrc& src, const GraphTgt& tgt,
boost::any& prop_src, boost::any& prop_tgt,
IndexMap& index_map,
SrcIndexMap& src_edge_index,
size_t max_src_edge_index,
bool& found)
: src(src), tgt(tgt), prop_src(prop_src),
prop_tgt(prop_tgt), index_map(index_map),
src_edge_index(src_edge_index),
max_src_edge_index(max_src_edge_index), found(found) {}
const GraphSrc& src;
const GraphTgt& tgt;
boost::any& prop_src;
boost::any& prop_tgt;
IndexMap& index_map;
SrcIndexMap& src_edge_index;
size_t max_src_edge_index;
bool& found;
template <class PropertyMap>
void operator()(PropertyMap) const
{
PropertyMap* psrc = any_cast<PropertyMap>(&prop_src);
if (psrc == NULL)
return;
if (prop_tgt.empty())
prop_tgt = PropertyMap(get(edge_index_t(), tgt));
PropertyMap* ptgt = any_cast<PropertyMap>(&prop_tgt);
if (ptgt == NULL)
return;
found = true;
auto p_src = psrc->get_unchecked(max_src_edge_index + 1);
auto p_tgt = ptgt->get_unchecked(num_edges(tgt));
int i, N = num_vertices(src);
#pragma omp parallel for default(shared) private(i) schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, src);
if (v == graph_traits<GraphSrc>::null_vertex())
continue;
for (auto e : out_edges_range(v, src))
{
auto s = source(e, src);
auto t = target(e, src);
if (!is_directed::apply<GraphSrc>::type::value && s > t)
continue;
size_t ei = src_edge_index[e];
const auto& new_e = index_map[ei];
p_tgt[new_e] = p_src[e];
}
}
}
};
template <class PropertyMaps, class GraphSrc, class GraphTgt,
class IndexMap, class SrcIndexMap>
void copy_edge_property(boost::any& prop_src, boost::any& prop_tgt,
const GraphSrc& src, const GraphTgt& tgt,
IndexMap& index_map, SrcIndexMap& src_vertex_index,
size_t max_src_edge_index)
{
bool found = false;
boost::mpl::for_each<PropertyMaps>(copy_edge_property_dispatch<GraphSrc, GraphTgt,
IndexMap, SrcIndexMap>
(src, tgt, prop_src, prop_tgt, index_map, src_vertex_index,
max_src_edge_index, found));
if (!found)
throw ValueException("Cannot find property map type.");
}
......@@ -255,125 +255,3 @@ void mark_edges(GraphInterface& gi, boost::any prop)
(gi, bind<void>(do_mark_edges(), _1, _2),
writable_edge_scalar_properties())(prop);
}
struct do_perfect_vhash
{
template <class Graph, class VertexPropertyMap, class HashProp>
void operator()(Graph& g, VertexPropertyMap prop, HashProp hprop,
boost::any& adict) const
{
typedef typename property_traits<VertexPropertyMap>::value_type val_t;
typedef typename property_traits<HashProp>::value_type hash_t;
typedef unordered_map<val_t, hash_t> dict_t;
if (adict.empty())
adict = dict_t();
dict_t& dict = any_cast<dict_t&>(adict);
for (auto v : vertices_range(g))
{
auto val = prop[v];
auto iter = dict.find(val);
hash_t h;
if (iter == dict.end())
h = dict[val] = dict.size() - 1;
else
h = iter->second;
hprop[v] = h;
}
}
};
void perfect_vhash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict)
{
run_action<graph_tool::detail::always_directed>()
(gi, std::bind<void>(do_perfect_vhash(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::ref(dict)),
vertex_properties(), writable_vertex_scalar_properties())
(prop, hprop);
}
struct do_perfect_ehash
{
template <class Graph, class EdgePropertyMap, class HashProp>
void operator()(Graph& g, EdgePropertyMap prop, HashProp hprop,
boost::any& adict) const
{
typedef typename property_traits<EdgePropertyMap>::value_type val_t;
typedef typename property_traits<HashProp>::value_type hash_t;
typedef unordered_map<val_t, hash_t> dict_t;
if (adict.empty())
adict = dict_t();
dict_t& dict = any_cast<dict_t&>(adict);
for (auto e : edges_range(g))
{
auto val = prop[e];
auto iter = dict.find(val);
hash_t h;
if (iter == dict.end())
h = dict[val] = dict.size() - 1;
else
h = iter->second;
hprop[e] = h;
}
}
};
void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict)
{
run_action<graph_tool::detail::always_directed>()
(gi, std::bind<void>(do_perfect_ehash(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::ref(dict)),
edge_properties(), writable_edge_scalar_properties())
(prop, hprop);
}
struct do_set_vertex_property
{
template <class Graph, class PropertyMap>
void operator()(Graph& g, PropertyMap prop, boost::python::object oval) const
{
typedef typename property_traits<PropertyMap>::value_type val_t;
val_t val = boost::python::extract<val_t>(oval);
for (auto v : vertices_range(g))
prop[v] = val;
}
};
void set_vertex_property(GraphInterface& gi, boost::any prop,
boost::python::object val)
{
run_action<>()(gi, std::bind(do_set_vertex_property(), std::placeholders::_1,
std::placeholders::_2, val),
writable_vertex_properties())(prop);
}
struct do_set_edge_property
{
template <class Graph, class PropertyMap>
void operator()(Graph& g, PropertyMap prop, boost::python::object oval) const
{
typedef typename property_traits<PropertyMap>::value_type val_t;
val_t val = boost::python::extract<val_t>(oval);
for (auto e : edges_range(g))
prop[e] = val;
}
};
void set_edge_property(GraphInterface& gi, boost::any prop,
boost::python::object val)
{
run_action<>()(gi, std::bind(do_set_edge_property(), std::placeholders::_1,
std::placeholders::_2, val),
writable_edge_properties())(prop);
}
......@@ -22,106 +22,12 @@
#include <boost/mpl/contains.hpp>
#include <boost/python/extract.hpp>
#include "graph_properties_copy.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
//
// Property map copying
// ====================
template <class IteratorSel, class PropertyMaps>
struct copy_property
{
template <class GraphTgt, class GraphSrc, class PropertyTgt>
void operator()(const GraphTgt& tgt, const GraphSrc* src,
PropertyTgt dst_map, boost::any prop_src) const
{
try
{
auto src_map = boost::any_cast<typename PropertyTgt::checked_t>(prop_src);
dispatch(tgt, src, dst_map, src_map);
}
catch (bad_any_cast)
{
typedef typename property_traits<PropertyTgt>::value_type val_tgt;
typedef typename IteratorSel::template get_descriptor<GraphSrc>::type src_d;
DynamicPropertyMapWrap<val_tgt, src_d> src_map(prop_src, PropertyMaps());
dispatch(tgt, src, dst_map, src_map);
}
}
template <class GraphTgt, class GraphSrc, class PropertyTgt, class PropertySrc>
void dispatch(const GraphTgt& tgt, const GraphSrc* src,
PropertyTgt dst_map, PropertySrc src_map) const
{
try
{
typename IteratorSel::template apply<GraphSrc>::type vs, vs_end;
typename IteratorSel::template apply<GraphTgt>::type vt, vt_end;
tie(vt, vt_end) = IteratorSel::range(tgt);
for (tie(vs, vs_end) = IteratorSel::range(*src); vs != vs_end; ++vs)
{
dst_map[*vt] = get(src_map, *vs);
++vt;
}
}
catch (bad_lexical_cast&)
{
throw ValueException("property values are not convertible");
}
}
};
struct edge_selector
{
template <class Graph>
struct apply
{
typedef typename graph_traits<Graph>::edge_iterator type;
};
template <class Graph>
struct get_descriptor
{
typedef typename graph_traits<Graph>::edge_descriptor type;
};
template <class Graph>
static pair<typename apply<Graph>::type,
typename apply<Graph>::type>
range(Graph& g)
{
return edges(g);
}
};
struct vertex_selector
{
template <class Graph>
struct apply
{
typedef typename graph_traits<Graph>::vertex_iterator type;
};
template <class Graph>
struct get_descriptor
{
typedef typename graph_traits<Graph>::vertex_descriptor type;
};
template <class Graph>
static pair<typename apply<Graph>::type,
typename apply<Graph>::type>
range(Graph& g)
{
return vertices(g);
}
};
struct graph_views:
boost::mpl::transform<graph_tool::detail::all_graph_views,
boost::mpl::quote1<std::add_pointer> >::type {};
......@@ -137,15 +43,3 @@ void GraphInterface::copy_vertex_property(const GraphInterface& src,
graph_views(), writable_vertex_properties())
(src.get_graph_view(), prop_tgt);
}
void GraphInterface::copy_edge_property(const GraphInterface& src,
boost::any prop_src,
boost::any prop_tgt)
{
run_action<>()
(*this, std::bind(copy_property<edge_selector,edge_properties>(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, prop_src),
graph_views(), writable_edge_properties())
(src.get_graph_view(), prop_tgt);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2015 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GRAPH_PROPERTIES_COPY_HH
#define GRAPH_PROPERTIES_COPY_HH
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_properties.hh"
#include <boost/mpl/contains.hpp>
#include <boost/python/extract.hpp>
namespace graph_tool
{
//
// Property map copying
// ====================
template <class IteratorSel, class PropertyMaps>
struct copy_property
{
template <class GraphTgt, class GraphSrc, class PropertyTgt>
void operator()(const GraphTgt& tgt, const GraphSrc* src,
PropertyTgt dst_map, boost::any prop_src) const
{
try
{
auto src_map = boost::any_cast<typename PropertyTgt::checked_t>(prop_src);
dispatch(tgt, src, dst_map, src_map);
}
catch (boost::bad_any_cast)
{
typedef typename boost::property_traits<PropertyTgt>::value_type val_tgt;
typedef typename IteratorSel::template get_descriptor<GraphSrc>::type src_d;
DynamicPropertyMapWrap<val_tgt, src_d> src_map(prop_src, PropertyMaps());
dispatch(tgt, src, dst_map, src_map);
}
}
template <class GraphTgt, class GraphSrc, class PropertyTgt, class PropertySrc>
void dispatch(const GraphTgt& tgt, const GraphSrc* src,
PropertyTgt dst_map, PropertySrc src_map) const
{
try
{
typename IteratorSel::template apply<GraphSrc>::type vs, vs_end;
typename IteratorSel::template apply<GraphTgt>::type vt, vt_end;
tie(vt, vt_end) = IteratorSel::range(tgt);
tie(vs, vs_end) = IteratorSel::range(*src);
for (; vs != vs_end; ++vs)
{
put(dst_map, *vt++, get(src_map, *vs));
}
}
catch (boost::bad_lexical_cast&)
{
throw ValueException("property values are not convertible");
}
}
};
struct edge_selector
{
template <class Graph>
struct apply
{
typedef typename boost::graph_traits<Graph>::edge_iterator type;
};
template <class Graph>
struct get_descriptor
{
typedef typename boost::graph_traits<Graph>::edge_descriptor type;
};
template <class Graph>
static std::pair<typename apply<Graph>::type,
typename apply<Graph>::type>
range(Graph& g)
{
return edges(g);
}
};
struct vertex_selector
{
template <class Graph>
struct apply
{
typedef typename boost::graph_traits<Graph>::vertex_iterator type;
};
template <class Graph>
struct get_descriptor
{
typedef typename boost::graph_traits<Graph>::vertex_descriptor type;
};
template <class Graph>
static std::pair<typename apply<Graph>::type,
typename apply<Graph>::type>
range(Graph& g)
{
return vertices(g);
}
};
} // namespace graph_tool
#endif // GRAPH_PROPERTIES_COPY_HH
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2015 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_properties.hh"
#include <boost/mpl/contains.hpp>
#include <boost/python/extract.hpp>
#include "graph_properties_copy.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
struct graph_views:
boost::mpl::transform<graph_tool::detail::all_graph_views,
boost::mpl::quote1<std::add_pointer> >::type {};
void GraphInterface::copy_edge_property(const GraphInterface& src,
boost::any prop_src,
boost::any prop_tgt)
{
run_action<>()
(*this, std::bind(copy_property<edge_selector,edge_properties>(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, prop_src),
graph_views(), writable_edge_properties())
(src.get_graph_view(), prop_tgt);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2015 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_python_interface.hh"
#include "graph.hh"
#include "graph_properties.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
#include "hash_map_wrap.hh"
#include <boost/mpl/for_each.hpp>
#include <boost/python/extract.hpp>
using namespace std;