Commit 92d0c0b5 authored by Tiago Peixoto's avatar Tiago Peixoto

Fix memory usage issue in graph_blockmodel.cc

parent 0fdb192b
...@@ -94,7 +94,12 @@ inline double safelog(Type x) ...@@ -94,7 +94,12 @@ inline double safelog(Type x)
__attribute__((always_inline)) __attribute__((always_inline))
inline double safelog(size_t x) inline double safelog(size_t x)
{ {
assert(x < __safelog_cache.size()); if (x >= __safelog_cache.size())
{
if (x == 0)
return 0;
return log(x);
}
return __safelog_cache[x]; return __safelog_cache[x];
} }
...@@ -102,8 +107,7 @@ __attribute__((always_inline)) ...@@ -102,8 +107,7 @@ __attribute__((always_inline))
inline double xlogx(size_t x) inline double xlogx(size_t x)
{ {
if (x >= __xlogx_cache.size()) if (x >= __xlogx_cache.size())
cout << x << " " << __xlogx_cache.size() << endl; return x * safelog(x);
assert(x < __xlogx_cache.size());
return __xlogx_cache[x]; return __xlogx_cache[x];
} }
...@@ -1654,7 +1658,8 @@ struct egroups_manage ...@@ -1654,7 +1658,8 @@ struct egroups_manage
template <class Eprop, class Vprop, class VEprop, class Graph, class VertexIndex> template <class Eprop, class Vprop, class VEprop, class Graph, class VertexIndex>
static void build(Vprop b, boost::any& oegroups, VEprop esrcpos, static void build(Vprop b, boost::any& oegroups, VEprop esrcpos,
VEprop etgtpos, Eprop eweight, Graph& g, VEprop etgtpos, Eprop eweight, Graph& g,
VertexIndex vertex_index, size_t B, bool weighted, bool empty) VertexIndex vertex_index, size_t B, bool weighted,
bool empty)
{ {
if (weighted) if (weighted)
{ {
...@@ -1666,8 +1671,7 @@ struct egroups_manage ...@@ -1666,8 +1671,7 @@ struct egroups_manage
if (empty) if (empty)
return; return;
build_dispatch(b, egroups_checked.get_unchecked(B), build_dispatch(b, egroups_checked.get_unchecked(B),
esrcpos, etgtpos, eweight, g, vertex_index, B, esrcpos, etgtpos, eweight, g, vertex_index, B);
mpl::true_());
} }
else else
{ {
...@@ -1679,27 +1683,29 @@ struct egroups_manage ...@@ -1679,27 +1683,29 @@ struct egroups_manage
if (empty) if (empty)
return; return;
build_dispatch(b, egroups_checked.get_unchecked(B), build_dispatch(b, egroups_checked.get_unchecked(B),
esrcpos, etgtpos, eweight, g, vertex_index, B, esrcpos, etgtpos, eweight, g, vertex_index, B);
mpl::true_());
} }
} }
template <class Eprop, class Vprop, class VEprop, class Graph, class VertexIndex, class Egroups> template <class Eprop, class Vprop, class VEprop, class Graph,
class VertexIndex, class Egroups>
static void build_dispatch(Vprop b, Egroups egroups, VEprop esrcpos, static void build_dispatch(Vprop b, Egroups egroups, VEprop esrcpos,
VEprop etgtpos, Eprop eweight, Graph& g, VEprop etgtpos, Eprop eweight, Graph& g,
VertexIndex, size_t, mpl::true_) VertexIndex, size_t)
{ {
for (auto e : edges_range(g)) for (auto e : edges_range(g))
{ {
size_t r = b[get_source(e, g)]; size_t r = b[get_source(e, g)];
assert (r < B); assert (r < B);
auto& r_elist = egroups[r]; auto& r_elist = egroups[r];
esrcpos[e] = insert_edge(std::make_tuple(e, true), r_elist, eweight[e]); esrcpos[e] = insert_edge(std::make_tuple(e, true), r_elist,
eweight[e]);
size_t s = b[get_target(e, g)]; size_t s = b[get_target(e, g)];
assert (s < B); assert (s < B);
auto& s_elist = egroups[s]; auto& s_elist = egroups[s];
etgtpos[e] = insert_edge(std::make_tuple(e, false), s_elist, eweight[e]); etgtpos[e] = insert_edge(std::make_tuple(e, false), s_elist,
eweight[e]);
} }
} }
...@@ -1720,31 +1726,31 @@ struct egroups_manage ...@@ -1720,31 +1726,31 @@ struct egroups_manage
template <class Edge, class Epos> template <class Edge, class Epos>
static void remove_edge(size_t pos, Epos& esrcpos, Epos& etgtpos, static void remove_edge(size_t pos, Epos& esrcpos, Epos& etgtpos,
DynamicSampler<Edge>& elist) vector<Edge>& elist)
{ {
typedef typename property_traits<Epos>::value_type val_t; typedef typename property_traits<Epos>::value_type val_t;
if (get<1>(elist.back()))
esrcpos[get<0>(elist.back())] = pos;
else
etgtpos[get<0>(elist.back())] = pos;
if (get<1>(elist[pos])) if (get<1>(elist[pos]))
esrcpos[get<0>(elist[pos])] = numeric_limits<val_t>::max(); esrcpos[get<0>(elist[pos])] = numeric_limits<val_t>::max();
else else
etgtpos[get<0>(elist[pos])] = numeric_limits<val_t>::max(); etgtpos[get<0>(elist[pos])] = numeric_limits<val_t>::max();
elist.remove(pos); elist[pos] = elist.back();
elist.pop_back();
} }
template <class Edge, class Epos> template <class Edge, class Epos>
static void remove_edge(size_t pos, Epos& esrcpos, Epos& etgtpos, static void remove_edge(size_t pos, Epos& esrcpos, Epos& etgtpos,
vector<Edge>& elist) DynamicSampler<Edge>& elist)
{ {
typedef typename property_traits<Epos>::value_type val_t; typedef typename property_traits<Epos>::value_type val_t;
if (get<1>(elist.back()))
esrcpos[get<0>(elist.back())] = pos;
else
etgtpos[get<0>(elist.back())] = pos;
if (get<1>(elist[pos])) if (get<1>(elist[pos]))
esrcpos[get<0>(elist[pos])] = numeric_limits<val_t>::max(); esrcpos[get<0>(elist[pos])] = numeric_limits<val_t>::max();
else else
etgtpos[get<0>(elist[pos])] = numeric_limits<val_t>::max(); etgtpos[get<0>(elist[pos])] = numeric_limits<val_t>::max();
elist[pos] = elist.back(); elist.remove(pos);
elist.pop_back();
} }
template <class Vertex, class Graph, class EVprop, class Eprop, class VEprop> template <class Vertex, class Graph, class EVprop, class Eprop, class VEprop>
......
...@@ -97,7 +97,6 @@ class BlockState(object): ...@@ -97,7 +97,6 @@ class BlockState(object):
def __init__(self, g, eweight=None, vweight=None, b=None, def __init__(self, g, eweight=None, vweight=None, b=None,
B=None, clabel=None, deg_corr=True, B=None, clabel=None, deg_corr=True,
max_BE=1000, **kwargs): max_BE=1000, **kwargs):
BlockState._state_ref_count += 1 BlockState._state_ref_count += 1
# initialize weights to unity, if necessary # initialize weights to unity, if necessary
...@@ -205,9 +204,11 @@ class BlockState(object): ...@@ -205,9 +204,11 @@ class BlockState(object):
self.edges_dl = False self.edges_dl = False
# computation cache # computation cache
libcommunity.init_safelog(int(5 * max(self.E, self.N))) E = g.num_edges()
libcommunity.init_xlogx(int(5 * max(self.E, self.N))) N = g.num_vertices()
libcommunity.init_lgamma(int(3 * max(self.E, self.N))) libcommunity.init_safelog(int(5 * max(E, N)))
libcommunity.init_xlogx(int(5 * max(E, N)))
libcommunity.init_lgamma(int(3 * max(E, N)))
def __del__(self): def __del__(self):
try: try:
......
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