Commit e75cf856 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Fix segfault bug in motifs()

This fixes a bug in the motifs() code which generates a segfault for
certain subgraph signatures. This also fixes a potential problem for
multithreaded execution.
parent 0d8112a0
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
#ifndef GRAPH_MOTIFS_HH #ifndef GRAPH_MOTIFS_HH
#define GRAPH_MOTIFS_HH #define GRAPH_MOTIFS_HH
#ifdef USING_OPENMP
#include <omp.h>
#endif
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <boost/graph/copy.hpp> #include <boost/graph/copy.hpp>
#include <boost/graph/isomorphism.hpp> #include <boost/graph/isomorphism.hpp>
...@@ -272,21 +268,22 @@ struct wrap_undirected ...@@ -272,21 +268,22 @@ struct wrap_undirected
}; };
}; };
// get the signature of the graph: concatenated out + in degree histograms // get the signature of the graph: sorted degree sequence
template <class Graph> template <class Graph>
void get_sig(Graph& g, vector<size_t>& sig) void get_sig(Graph& g, vector<size_t>& sig)
{ {
size_t N = num_vertices(g) + 1; sig.clear();
sig.resize(is_directed::apply<Graph>::type::value ? 2*N : N); size_t N = num_vertices(g);
for (size_t i = 0; i < sig.size(); ++i) if (N > 0)
sig[i] = 0; sig.resize(is_directed::apply<Graph>::type::value ? 2 * N : N);
typename graph_traits<Graph>::vertex_iterator v, v_end; for (size_t i = 0; i < N; ++i)
for (tie(v, v_end) = vertices(g); v != v_end; ++v)
{ {
sig[out_degree(*v,g)]++; typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
sig[i] = out_degree(v, g);
if(is_directed::apply<Graph>::type::value) if(is_directed::apply<Graph>::type::value)
sig[in_degreeS()(*v,g)+N]++; sig[i + N] = in_degreeS()(v, g);
} }
sort(sig.begin(), sig.end());
} }
// gets (or samples) all the subgraphs in graph g // gets (or samples) all the subgraphs in graph g
...@@ -349,11 +346,6 @@ struct get_all_motifs ...@@ -349,11 +346,6 @@ struct get_all_motifs
V.resize(n); V.resize(n);
} }
#ifdef USING_OPENMP
omp_lock_t lock;
omp_init_lock(&lock);
#endif
int i, N = (p < 1) ? V.size() : num_vertices(g); int i, N = (p < 1) ? V.size() : num_vertices(g);
#pragma omp parallel for default(shared) private(i, sig) \ #pragma omp parallel for default(shared) private(i, sig) \
schedule(dynamic) schedule(dynamic)
...@@ -369,64 +361,56 @@ struct get_all_motifs ...@@ -369,64 +361,56 @@ struct get_all_motifs
typename wrap_undirected::apply<Graph>::type ug(g); typename wrap_undirected::apply<Graph>::type ug(g);
get_subgraphs(ug, v, k, subgraphs, sampler); get_subgraphs(ug, v, k, subgraphs, sampler);
#pragma omp critical
for (size_t j = 0; j < subgraphs.size(); ++j) for (size_t j = 0; j < subgraphs.size(); ++j)
{ {
graph_sg_t sub; graph_sg_t sub;
make_subgraph(subgraphs[j], g, sub); make_subgraph(subgraphs[j], g, sub);
get_sig(sub, sig); get_sig(sub, sig);
#ifdef USING_OPENMP
if (fill_list)
omp_set_lock(&lock);
#endif
typeof(sub_list.begin()) iter = sub_list.find(sig); typeof(sub_list.begin()) iter = sub_list.find(sig);
if(iter == sub_list.end()) if(iter == sub_list.end())
{ {
if (!fill_list) if (!fill_list)
continue; // avoid inserting an element in sub_list continue; // avoid inserting an element in sub_list
sub_list[sig] = vector<pair<size_t,graph_sg_t> >(); sub_list[sig].clear();
} }
bool found = false; bool found = false;
vector<pair<size_t, graph_sg_t> >& sl = sub_list[sig]; typeof(sub_list.begin()) sl = sub_list.find(sig);
for (size_t l = 0; l < sl.size(); ++l) if (sl != sub_list.end())
{ {
graph_sg_t& motif = sl[l].second; for (size_t l = 0; l < sl->second.size(); ++l)
if (comp_iso)
{ {
if (isomorphism(motif, sub)) graph_sg_t& motif = sl->second[l].second;
found = true; if (comp_iso)
} {
else if (isomorphism(motif, sub))
{ found = true;
if (graph_cmp(motif, sub)) }
found = true; else
} {
if (found) if (graph_cmp(motif, sub))
{ found = true;
#pragma omp critical }
hist[sl[l].first]++; if (found)
break; {
hist[sl->second[l].first]++;
break;
}
} }
} }
if (found == false && fill_list) if (found == false && fill_list)
{ {
subgraph_list.push_back(sub); subgraph_list.push_back(sub);
sl.push_back(make_pair(subgraph_list.size()-1,sub)); sub_list[sig].push_back(make_pair(subgraph_list.size() - 1,
hist.push_back(1); sub));
hist.push_back(1);
} }
#ifdef USING_OPENMP
if (fill_list)
omp_unset_lock(&lock);
#endif
} }
} }
#ifdef USING_OPENMP
omp_destroy_lock(&lock);
#endif
} }
}; };
......
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