Commit 0eb27fe5 authored by Tiago Peixoto's avatar Tiago Peixoto

blockmodel: Improve performance by disabling group mapping for non-layered SBMs

parent 809432af
Pipeline #425 passed with stage
in 517 minutes and 25 seconds
......@@ -21,6 +21,7 @@ libgraph_tool_inference_la_SOURCES = \
blockmodel/graph_blockmodel_gibbs.cc \
blockmodel/graph_blockmodel_imp.cc \
blockmodel/graph_blockmodel_imp2.cc \
blockmodel/graph_blockmodel_imp3.cc \
blockmodel/graph_blockmodel_marginals.cc \
blockmodel/graph_blockmodel_mcmc.cc \
blockmodel/graph_blockmodel_merge.cc \
......
......@@ -135,6 +135,7 @@ simple_degs_t copy_simple_degs(simple_degs_t& degs)
}
void export_sbm_state();
void export_sbm_state_rmap();
double spence(double);
......@@ -143,6 +144,7 @@ void export_blockmodel_state()
using namespace boost::python;
export_sbm_state();
export_sbm_state_rmap();
class_<vcmap_t>("unity_vprop_t").def("_get_any", &get_any<vcmap_t>);
class_<ecmap_t>("unity_eprop_t").def("_get_any", &get_any<ecmap_t>);
......
......@@ -58,10 +58,21 @@ typedef mpl::vector2<std::true_type, std::false_type> bool_tr;
typedef mpl::vector2<vcmap_t, vmap_t> vweight_tr;
typedef mpl::vector2<ecmap_t, emap_t> eweight_tr;
#ifdef GRAPH_BLOCKMODEL_RMAP_ENABLE
# ifdef GRAPH_BLOCKMODEL_RMAP_ALL_ENABLE
typedef mpl::vector2<std::true_type, std::false_type> rmap_tr;
# else
typedef mpl::vector1<std::true_type> rmap_tr;
# endif
#else
typedef mpl::vector1<std::false_type> rmap_tr;
#endif
#define BLOCK_STATE_params \
((g, &, all_graph_views, 1)) \
((is_weighted,, bool_tr, 1)) \
((use_hash,, bool_tr, 1)) \
((use_rmap,, rmap_tr, 1)) \
((_abg, &, boost::any&, 0)) \
((_aeweight, &, boost::any&, 0)) \
((_avweight, &, boost::any&, 0)) \
......@@ -104,6 +115,8 @@ public:
GET_PARAMS_USING(BlockStateBase<Ts...>, BLOCK_STATE_params)
GET_PARAMS_TYPEDEF(Ts, BLOCK_STATE_params)
typedef partition_stats<use_rmap_t::value> partition_stats_t;
template <class RNG, class... ATs,
typename std::enable_if_t<sizeof...(ATs) == sizeof...(Ts)>* = nullptr>
BlockState(RNG& rng, ATs&&... args)
......
......@@ -20,6 +20,9 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#define GRAPH_BLOCKMODEL_RMAP_ALL_ENABLE
#include "graph_blockmodel_util.hh"
#include "graph_blockmodel.hh"
#include "../support/graph_state.hh"
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 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_tool.hh"
#include "random.hh"
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "graph_blockmodel_util.hh"
#include "graph_blockmodel.hh"
#include "../support/graph_state.hh"
using namespace boost;
using namespace graph_tool;
GEN_DISPATCH(block_state, BlockState, BLOCK_STATE_params)
using namespace boost::python;
void export_sbm_state_rmap()
{
block_state::dispatch
([&](auto* s)
{
typedef typename std::remove_reference<decltype(*s)>::type state_t;
// void (state_t::*remove_vertices)(python::object) =
// &state_t::remove_vertices;
// void (state_t::*add_vertices)(python::object, python::object) =
// &state_t::add_vertices;
// void (state_t::*move_vertex)(size_t, size_t) =
// &state_t::move_vertex;
// void (state_t::*move_vertices)(python::object, python::object) =
// &state_t::move_vertices;
// double (state_t::*virtual_move)(size_t, size_t, size_t,
// entropy_args_t) =
// &state_t::virtual_move;
// size_t (state_t::*sample_block)(size_t, double, double, rng_t&) =
// &state_t::sample_block;
// size_t (state_t::*random_neighbor)(size_t, rng_t&) =
// &state_t::random_neighbor;
// double (state_t::*get_move_prob)(size_t, size_t, size_t, double,
// double, bool) =
// &state_t::get_move_prob;
// void (state_t::*merge_vertices)(size_t, size_t) =
// &state_t::merge_vertices;
// void (state_t::*set_partition)(boost::any&) =
// &state_t::set_partition;
class_<state_t, bases<BlockStateVirtualBase>>
c(name_demangle(typeid(state_t).name()).c_str(),
no_init);
c.def("get_B_E",
&state_t::get_B_E)
.def("get_B_E_D",
&state_t::get_B_E_D);
// c.def("remove_vertices", remove_vertices)
// .def("add_vertices", add_vertices)
// .def("move_vertex", move_vertex)
// .def("move_vertices", move_vertices)
// .def("set_partition", set_partition)
// .def("virtual_move", virtual_move)
// .def("merge_vertices", merge_vertices)
// .def("sample_block", sample_block)
// .def("sample_neighbor", random_neighbor)
// .def("entropy", &state_t::entropy)
// .def("get_partition_dl", &state_t::get_partition_dl)
// .def("get_deg_dl", &state_t::get_deg_dl)
// .def("get_move_prob", get_move_prob)
// .def("enable_partition_stats",
// &state_t::enable_partition_stats)
// .def("disable_partition_stats",
// &state_t::disable_partition_stats)
// .def("is_partition_stats_enabled",
// &state_t::is_partition_stats_enabled)
// .def("couple_state",
// &state_t::couple_state)
// .def("decouple_state",
// &state_t::decouple_state)
// .def("get_B_E",
// &state_t::get_B_E)
// .def("get_B_E_D",
// &state_t::get_B_E_D)
// .def("clear_egroups",
// &state_t::clear_egroups)
// .def("rebuild_neighbor_sampler",
// &state_t::rebuild_neighbor_sampler)
// .def("sync_emat",
// &state_t::sync_emat);
});
}
......@@ -60,7 +60,8 @@ void degs_op(size_t v, Vprop& vweight, Eprop& eweight,
}
}
class partition_stats_t
template <bool use_rmap>
class partition_stats
{
public:
......@@ -68,12 +69,20 @@ public:
template <class Graph, class Vprop, class VWprop, class Eprop, class Degs,
class Mprop, class Vlist>
partition_stats_t(Graph& g, Vprop& b, Vlist& vlist, size_t E, size_t B,
VWprop& vweight, Eprop& eweight, Degs& degs,
const Mprop& ignore_degree, std::vector<size_t>& bmap,
bool allow_empty)
partition_stats(Graph& g, Vprop& b, Vlist& vlist, size_t E, size_t B,
VWprop& vweight, Eprop& eweight, Degs& degs,
const Mprop& ignore_degree, std::vector<size_t>& bmap,
bool allow_empty)
: _bmap(bmap), _N(0), _E(E), _total_B(B), _allow_empty(allow_empty)
{
if (!use_rmap)
{
_hist.resize(num_vertices(g));
_total.resize(num_vertices(g));
_ep.resize(num_vertices(g));
_em.resize(num_vertices(g));
}
for (auto v : vlist)
{
if (vweight[v] == 0)
......@@ -108,23 +117,28 @@ public:
}
}
template <bool resize=false>
size_t get_r(size_t r)
{
constexpr size_t null =
std::numeric_limits<size_t>::max();
if (r >= _bmap.size())
_bmap.resize(r + 1, null);
size_t nr = _bmap[r];
if (nr == null)
nr = _bmap[r] = _hist.size();
if (nr >= _hist.size())
if (use_rmap)
{
constexpr size_t null =
std::numeric_limits<size_t>::max();
if (r >= _bmap.size())
_bmap.resize(r + 1, null);
size_t nr = _bmap[r];
if (nr == null)
nr = _bmap[r] = _hist.size();
r = nr;
}
if ((resize || use_rmap) && r >= _hist.size())
{
_hist.resize(nr + 1);
_total.resize(nr + 1);
_ep.resize(nr + 1);
_em.resize(nr + 1);
_hist.resize(r + 1);
_total.resize(r + 1);
_ep.resize(r + 1);
_em.resize(r + 1);
}
return nr;
return r;
}
double get_partition_dl()
......@@ -260,7 +274,7 @@ public:
r = get_r(r);
if (nr != null_group)
nr = get_r(nr);
nr = get_r<true>(nr);
int n = vweight[v];
if (n == 0)
......@@ -325,7 +339,7 @@ public:
if (r != null_group)
r = get_r(r);
if (nr != null_group)
nr = get_r(nr);
nr = get_r<true>(nr);
double S_b = 0, S_a = 0;
......@@ -363,7 +377,7 @@ public:
if (r != null_group)
r = get_r(r);
if (nr != null_group)
nr = get_r(nr);
nr = get_r<true>(nr);
auto dop =
[&](auto&& f)
......@@ -577,7 +591,7 @@ public:
{
if (nr == null_group || vweight[v] == 0)
return;
nr = get_r(nr);
nr = get_r<true>(nr);
change_vertex(v, nr, deg_corr, g, vweight, eweight, degs, 1);
}
......
......@@ -21,6 +21,7 @@
#include "graph_tool.hh"
#include "random.hh"
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel.hh"
#include "graph_blockmodel_layers_util.hh"
#define BASE_STATE_params BLOCK_STATE_params
......@@ -43,7 +44,7 @@ python::object make_layered_block_state(boost::python::object oblock_state,
auto dispatch = [&](auto& block_state)
{
typedef typename std::remove_reference<decltype(block_state)>::type
state_t;
state_t;
layered_block_state<state_t>::make_dispatch
(olayered_state,
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -21,6 +21,7 @@
#include "graph_tool.hh"
#include "random.hh"
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#include "graph_blockmodel_layers_util.hh"
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -20,6 +20,7 @@
#include <boost/python.hpp>
#define GRAPH_BLOCKMODEL_RMAP_ENABLE
#include "../blockmodel/graph_blockmodel_util.hh"
#include "../blockmodel/graph_blockmodel.hh"
#define BASE_STATE_params BLOCK_STATE_params
......
......@@ -426,6 +426,7 @@ class BlockState(object):
self.max_BE = max_BE
self.use_hash = self.B > self.max_BE
self.use_rmap = kwargs.pop("use_rmap", False)
self.ignore_degrees = kwargs.pop("ignore_degrees", None)
if self.ignore_degrees is None:
......
......@@ -156,6 +156,7 @@ class LayeredBlockState(OverlapBlockState, BlockState):
deg_corr=deg_corr, allow_empty=allow_empty,
max_BE=max_BE, degs=tdegs,
Lrecdx=self.Lrecdx[0],
use_rmap=True,
**dmask(kwargs, ["degs", "lweights", "gs"]))
else:
kwargs = dmask(kwargs, ["degs"])
......@@ -318,6 +319,7 @@ class LayeredBlockState(OverlapBlockState, BlockState):
kwargs.pop("rec_params", None)
kwargs.pop("Lrecdx", None)
kwargs.pop("epsilon", None)
kwargs.pop("bfield", None)
if len(kwargs) > 0:
warnings.warn("unrecognized keyword arguments: " +
......@@ -375,7 +377,8 @@ class LayeredBlockState(OverlapBlockState, BlockState):
deg_corr=self.deg_corr,
degs=degs,
allow_empty=self.allow_empty,
max_BE=self.max_BE)
max_BE=self.max_BE,
use_rmap=True)
else:
base_u, node_index = self.__get_base_u(u)
state = OverlapBlockState(u, b=u.vp["b"].fa,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment