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

Replace some explicit parallel loops by implicit ones

parent 8a608cb9
......@@ -67,48 +67,47 @@ struct get_closeness
get_vertex_dists_t get_vertex_dists;
size_t HN = HardNumVertices()(g);
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
vertex_t v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
unchecked_vector_property_map<val_type,VertexIndex>
dist_map(vertex_index, num_vertices(g));
for (auto u : vertices_range(g))
dist_map[u] = numeric_limits<val_type>::max();
dist_map[v] = 0;
size_t comp_size = 0;
get_vertex_dists(g, v, vertex_index, dist_map, weights, comp_size);
closeness[v] = 0;
for (auto v2 : vertices_range(g))
{
if (v2 != v && dist_map[v2] != numeric_limits<val_type>::max())
{
if (!harmonic)
closeness[v] += dist_map[v2];
else
closeness[v] += 1. / dist_map[v2];
}
}
if (!harmonic)
closeness[v] = 1 / closeness[v];
if (norm)
{
if (harmonic)
closeness[v] /= HN - 1;
else
closeness[v] *= comp_size - 1;
}
}
parallel_vertex_loop
(g,
[&](auto v)
{
unchecked_vector_property_map<val_type,VertexIndex>
dist_map(vertex_index, num_vertices(g));
for (auto u : vertices_range(g))
dist_map[u] = numeric_limits<val_type>::max();
dist_map[v] = 0;
size_t comp_size = 0;
get_vertex_dists(g, v, vertex_index, dist_map, weights, comp_size);
closeness[v] = 0;
for (auto v2 : vertices_range(g))
{
if (v2 != v && dist_map[v2] != numeric_limits<val_type>::max())
{
if (!harmonic)
closeness[v] += dist_map[v2];
else
closeness[v] += 1. / dist_map[v2];
}
}
if (!harmonic)
closeness[v] = 1 / closeness[v];
if (norm)
{
if (harmonic)
closeness[v] /= HN - 1;
else
closeness[v] *= comp_size - 1;
}
});
}
class component_djk_visitor: public boost::dijkstra_visitor<>
{
public:
......
......@@ -46,63 +46,44 @@ struct get_eigentrust
if (is_directed::apply<Graph>::type::value)
{
TrustMap c_temp(edge_index, c.get_storage().size());
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c_type sum = 0;
for (const auto& e : out_edges_range(v, g))
sum += get(c, e);
if (sum > 0)
{
for (const auto& e : out_edges_range(v, g))
put(c_temp, e, get(c, e) / sum);
}
}
parallel_vertex_loop
(g,
[&](auto v)
{
c_type sum = 0;
for (const auto& e : out_edges_range(v, g))
sum += get(c, e);
if (sum > 0)
{
for (const auto& e : out_edges_range(v, g))
put(c_temp, e, get(c, e) / sum);
}
});
c = c_temp;
}
else
{
c_sum.reserve(num_vertices(g));
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c_sum[v] = 0;
for (const auto& e : out_edges_range(v, g))
c_sum[v] += c[e];
}
parallel_vertex_loop
(g,
[&](auto v)
{
c_sum[v] = 0;
for (const auto& e : out_edges_range(v, g))
c_sum[v] += c[e];
});
}
// init inferred trust t
int i, N = num_vertices(g), V = HardNumVertices()(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
t[v] = 1.0/V;
}
auto V = HardNumVertices()(g);
parallel_vertex_loop(g, [&](auto v) { t[v] = 1.0/V; });
t_type delta = epslon + 1;
iter = 0;
while (delta >= epslon)
{
delta = 0;
size_t i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:delta)
for (i = 0; i < N; ++i)
......@@ -134,17 +115,7 @@ struct get_eigentrust
}
if (iter % 2 != 0)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
t[v] = t_temp[v];
}
}
parallel_vertex_loop(g, [&](auto v) {t[v] = t_temp[v];});
}
};
......
......@@ -54,11 +54,11 @@ struct get_eigenvector
t_type delta = epsilon + 1;
t_type prev_delta = delta + 1;
size_t iter = 0;
int i, N = num_vertices(g);
while (delta >= epsilon)
{
prev_delta = delta;
norm = 0;
size_t i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:norm)
for (i = 0; i < N; ++i)
......@@ -82,16 +82,14 @@ struct get_eigenvector
norm = sqrt(norm);
delta = 0;
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:delta)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c_temp[v] /= norm;
delta += abs(c_temp[v] - c[v]);
}
parallel_vertex_loop
(g,
[&](auto v)
{
c_temp[v] /= norm;
delta += abs(c_temp[v] - c[v]);
});
swap(c_temp, c);
++iter;
......@@ -102,17 +100,7 @@ struct get_eigenvector
}
if (iter % 2 != 0)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c[v] = c_temp[v];
}
}
parallel_vertex_loop(g, [&](auto v) { c[v] = c_temp[v]; });
eig = norm;
}
......
......@@ -52,17 +52,14 @@ struct get_hits
CentralityMap y_temp(vertex_index, num_vertices(g));
// init centrality
int i, N = num_vertices(g), V = HardNumVertices()(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
x[v] = 1.0 / V;
y[v] = 1.0 / V;
}
auto V = HardNumVertices()(g);
parallel_vertex_loop
(g,
[&](auto v)
{
x[v] = 1.0 / V;
y[v] = 1.0 / V;
});
t_type x_norm = 0, y_norm = 0;
......@@ -71,6 +68,7 @@ struct get_hits
while (delta >= epsilon)
{
x_norm = 0, y_norm=0;
size_t i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:x_norm, y_norm)
for (i = 0; i < N; ++i)
......@@ -126,16 +124,13 @@ struct get_hits
if (iter % 2 != 0)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
x[v] = x_temp[v];
y[v] = y_temp[v];
}
parallel_vertex_loop
(g,
[&](auto v)
{
x[v] = x_temp[v];
y[v] = y_temp[v];
});
}
eig = x_norm;
......
......@@ -52,30 +52,26 @@ struct get_katz
t_type delta = epsilon + 1;
size_t iter = 0;
int i, N = num_vertices(g);
while (delta >= epsilon)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c_temp[v] = get(beta, v);
for (const auto& e : in_or_out_edges_range(v, g))
{
typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value)
s = source(e, g);
else
s = target(e, g);
c_temp[v] += alpha * get(w, e) * c[s];
}
}
parallel_vertex_loop
(g,
[&](auto v)
{
c_temp[v] = get(beta, v);
for (const auto& e : in_or_out_edges_range(v, g))
{
typename graph_traits<Graph>::vertex_descriptor s;
if (is_directed::apply<Graph>::type::value)
s = source(e, g);
else
s = target(e, g);
c_temp[v] += alpha * get(w, e) * c[s];
}
});
delta = 0;
size_t i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:delta)
for (i = 0; i < N; ++i)
......@@ -94,15 +90,7 @@ struct get_katz
if (iter % 2 != 0)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
c_temp[v] = c[v];
}
parallel_vertex_loop(g, [&](auto v) {c_temp[v] = c[v];});
}
}
};
......
......@@ -41,18 +41,14 @@ struct get_pagerank
RankMap deg(vertex_index, num_vertices(g));
// init degs
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
put(deg, v, 0);
for (const auto& e : out_edges_range(v, g))
put(deg, v, get(deg, v) + get(weight, e));
}
parallel_vertex_loop
(g,
[&](auto v)
{
put(deg, v, 0);
for (e : out_edges_range(v, g))
put(deg, v, get(deg, v) + get(weight, e));
});
rank_type delta = epsilon + 1;
rank_type d = damping;
......@@ -60,7 +56,8 @@ struct get_pagerank
while (delta >= epsilon)
{
delta = 0;
#pragma omp parallel for default(shared) private(i) \
size_t i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100) reduction(+:delta)
for (i = 0; i < N; ++i)
{
......@@ -90,15 +87,12 @@ struct get_pagerank
if (iter % 2 != 0)
{
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
put(rank, v, get(r_temp, v));
}
parallel_vertex_loop
(g,
[&](auto v)
{
put(rank, v, get(r_temp, v));
});
}
}
};
......
......@@ -103,17 +103,15 @@ struct get_trust_transitivity
typedef typename
property_traits<InferredTrustMap>::value_type::value_type t_type;
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
vertex_t v = vertex(i, g);
if (!is_valid_vertex(v, g))
continue;
t[v].resize((source == -1 && target == -1) ? N : 1);
}
size_t i, N = (target == -1) ? num_vertices(g) : target + 1;
parallel_vertex_loop
(g,
[&](auto v)
{
t[v].resize((source == -1 && target == -1) ? N : 1);
});
N = (target == -1) ? num_vertices(g) : target + 1;
#pragma omp parallel for default(shared) private(i) schedule(runtime) if (N > 100)
for (i = (target == -1) ? 0 : target; i < N; ++i)
{
......@@ -170,13 +168,11 @@ struct get_trust_transitivity
// compute the target's trust
t_type sum_w = 0, avg = 0;
for (tie(e, e_end) =
in_edge_iteratorS<Graph>::get_edges(tgt, g);
e != e_end; ++e)
for (auto e : in_edges_range(tgt, g))
{
t_type weight = dist_map[boost::source(*e,g)];
t_type weight = dist_map[boost::source(e, g)];
sum_w += weight;
avg += c[*e]*weight*weight;
avg += c[e]*weight*weight;
}
if (sum_w > 0)
t[tgt][0] = avg/sum_w;
......@@ -191,14 +187,11 @@ struct get_trust_transitivity
fg_t>::type rg_t;
rg_t rg(fg);
dist_map_t sum_w(vertex_index, num_vertices(g));
int j, N2 = num_vertices(g);
for (tie(e, e_end) =
in_edge_iteratorS<Graph>::get_edges(tgt, g);
e != e_end; ++e)
for (auto e : in_edges_range(tgt, g))
{
// compute the weights to all sources
dijkstra_shortest_paths
(rg, boost::source(*e, g), weight_map(c).
(rg, boost::source(e, g), weight_map(c).
vertex_index_map(vertex_index).
color_map(color_map).
distance_map(dist_map).
......@@ -207,33 +200,27 @@ struct get_trust_transitivity
distance_inf(t_type(0)).
distance_zero(t_type(1)));
#pragma omp parallel for default(shared) private(j) \
schedule(runtime) if (N > 100)
for (j = 0; j < N2; ++j)
{
vertex_t src = vertex(j, g);
if (!is_valid_vertex(src, g))
continue;
t_type weight = dist_map[src];
sum_w[src] += weight;
size_t tidx = (target == -1) ? vertex_index[tgt] : 0;
t[src][tidx] += c[*e]*weight*weight;
}
parallel_vertex_loop
(g,
[&](auto src)
{
t_type weight = dist_map[src];
sum_w[src] += weight;
size_t tidx = (target == -1) ? vertex_index[tgt] : 0;
t[src][tidx] += c[e]*weight*weight;
});
}
#pragma omp parallel for default(shared) private(j) \
schedule(runtime) if (N > 100)
for (j = 0; j < N2; ++j)
{
vertex_t src = vertex(j, g);
if (!is_valid_vertex(src, g))
continue;
size_t tidx = (target == -1) ? vertex_index[tgt] : 0;
if (sum_w[src] > 0)
t[src][tidx] /= sum_w[src];
if (src == tgt)
t[src][tidx] = 1.0;
}
parallel_vertex_loop
(g,
[&](auto src)
{
size_t tidx = (target == -1) ? vertex_index[tgt] : 0;
if (sum_w[src] > 0)
t[src][tidx] /= sum_w[src];
if (src == tgt)
t[src][tidx] = 1.0;
});
}
}
}
......
......@@ -141,25 +141,21 @@ struct copy_edge_property_dispatch
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 (!is_valid_vertex(v, src))
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];
}
}
parallel_vertex_loop
(src,
[&](auto v)
{
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];
}
});
}
};
......
......@@ -36,53 +36,48 @@ struct label_parallel_edges
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
typename property_map<Graph, edge_index_t>::type eidx = get(edge_index, g);
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) schedule(runtime) \
if (N > 100)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if