diff --git a/src/parallel_coarsening.cpp b/src/parallel_coarsening.cpp index 8219217..31d2d53 100644 --- a/src/parallel_coarsening.cpp +++ b/src/parallel_coarsening.cpp @@ -1,8 +1,8 @@ #include "Graph.h" -#include #include -#include #include +#include +#include /** * Compares two nodes based on their random value. @@ -12,7 +12,7 @@ * @param randVal * @return true if n1 is bigger than n2, false otherwise */ -bool compare_nodes(const NodePtr & n1, const NodePtr & n2, std::vector&randVal){ +bool compare_nodes(const NodePtr &n1, const NodePtr &n2, std::vector &randVal) { return (randVal[n2->id] < randVal[n1->id] || (randVal[n2->id] == randVal[n1->id] && n2->id < n1->id)); } @@ -26,17 +26,15 @@ bool compare_nodes(const NodePtr & n1, const NodePtr & n2, std::vector&randVal, int start,int num_threads, - std::barrier<> &b, std::mutex&color_mtx, - int&colored, int&last_color, int&iterations){ +void colourGraphThread(GraphPtr &g, std::vector &randVal, int start, int num_threads, std::barrier<> &b, std::mutex &color_mtx, int &colored, int &last_color, + int &iterations) { + std::unique_lock thread_lock { color_mtx, std::defer_lock }; - std::unique_lock thread_lock{color_mtx, std::defer_lock}; - - for(int i = start; iV(); i+=num_threads){ - randVal[i] = (unsigned int)random(); + for (int i = start; i < g->V(); i += num_threads) { + randVal[i] = (unsigned int) random(); } - while(true){ + while (true) { b.arrive_and_wait(); std::vector buffer; @@ -45,34 +43,34 @@ void colourGraphThread(GraphPtr &g, std::vector&randVal, int start break; thread_lock.unlock(); - for(int i = start; iV(); i+=num_threads){ - if(g->colours[i] != -1) + for (int i = start; i < g->V(); i += num_threads) { + if (g->colours[i] != -1) continue; - bool isMin = true; + bool isMin = true; auto this_node = g->nodes[i]; - for (auto &other_node: this_node->get_neighbors()) { + for (auto &other_node : this_node->get_neighbors()) { if (compare_nodes(this_node, other_node, randVal)) { isMin = false; break; } } - if (isMin) buffer.emplace_back(i); - + if (isMin) + buffer.emplace_back(i); } b.arrive_and_wait(); thread_lock.lock(); - for (auto& minNode: buffer) { - randVal[minNode] = UINT_MAX ; + for (auto &minNode : buffer) { + randVal[minNode] = UINT_MAX; g->colours[minNode] = last_color; colored++; } iterations++; - if(iterations == num_threads){ + if (iterations == num_threads) { iterations = 0; last_color++; } @@ -87,46 +85,46 @@ void colourGraphThread(GraphPtr &g, std::vector&randVal, int start * @param num_threads the number of threads to use * @return the number of colours used */ -unsigned int colourGraph(GraphPtr&g, int num_threads){ - - int colored = 0; - int last_color = 0; - int iterations = 0; +unsigned int colourGraph(GraphPtr &g, int num_threads) { + int colored = 0; + int last_color = 0; + int iterations = 0; std::mutex color_mtx; std::barrier b(num_threads); std::vector randVal(g->V(), 0); std::vector threads(num_threads); - for(int i = 0; i& matched_nodes, EdgePtr& retVal){ + */ +bool get_max_edge(const EdgePtrArr &edges, std::vector &matched_nodes, EdgePtr &retVal) { unsigned int max_edge_weight = 0; EdgePtr max_edge = nullptr; - for(const auto&e: edges){ - if(matched_nodes[e->node1.lock()->id] || matched_nodes[e->node2.lock()->id]) continue; - if(e->weight > max_edge_weight){ + for (const auto &e : edges) { + if (matched_nodes[e->node1.lock()->id] || matched_nodes[e->node2.lock()->id]) + continue; + if (e->weight > max_edge_weight) { max_edge_weight = e->weight; - max_edge = e; + max_edge = e; } } - if(max_edge == nullptr) { + if (max_edge == nullptr) { return false; } @@ -148,29 +146,28 @@ bool get_max_edge(const EdgePtrArr& edges, std::vector& matched_nodes, Edg * @param matched_index * @param n_index */ -void coarse_step(const GraphPtr& original_graph, const GraphPtr& coarse_graph, int start, int num_threads, - std::mutex&mtx, std::barrier<>&b, int max_colour, std::vector&matched_nodes, - std::vector&matched_index, int&n_index){ +void coarse_step(const GraphPtr &original_graph, const GraphPtr &coarse_graph, int start, int num_threads, std::mutex &mtx, std::barrier<> &b, int max_colour, + std::vector &matched_nodes, std::vector &matched_index, int &n_index) { int colour = 0; - while (colour < max_colour){ - for(int i = start; iV(); i+=num_threads){ - + while (colour < max_colour) { + for (int i = start; i < original_graph->V(); i += num_threads) { std::unique_lock lock(mtx); - if(matched_nodes[i]) continue; + if (matched_nodes[i]) + continue; lock.unlock(); - if(original_graph->colours[i] == colour){ + if (original_graph->colours[i] == colour) { const auto n = original_graph->nodes[i]; EdgePtr e; - bool result = get_max_edge(n->edges, matched_nodes,e); - if(result){ + bool result = get_max_edge(n->edges, matched_nodes, e); + if (result) { matched_index[e->node1.lock()->id] = e->node2.lock()->id; matched_index[e->node2.lock()->id] = e->node1.lock()->id; - }else{ + } else { std::unique_lock lock2(mtx); matched_nodes[i] = true; - n->child = coarse_graph->add_node(n_index++, n->weight); + n->child = coarse_graph->add_node(n_index++, n->weight); lock2.unlock(); } } @@ -178,20 +175,20 @@ void coarse_step(const GraphPtr& original_graph, const GraphPtr& coarse_graph, i b.arrive_and_wait(); - for(int i = start; iV(); i+=num_threads){ + for (int i = start; i < original_graph->V(); i += num_threads) { std::unique_lock lock3(mtx); - if(matched_nodes[i]) continue; + if (matched_nodes[i]) + continue; lock3.unlock(); - if(original_graph->colours[i] == colour){ - + if (original_graph->colours[i] == colour) { const auto n1 = original_graph->nodes[i]; const auto n2 = original_graph->nodes[matched_index[i]]; - if(matched_index[n2->id] == n1->id){ + if (matched_index[n2->id] == n1->id) { std::unique_lock lock4(mtx); matched_nodes[n1->id] = matched_nodes[n2->id] = true; - n1->child = n2->child = coarse_graph->add_node(n_index++, n1->weight + n2->weight ); + n1->child = n2->child = coarse_graph->add_node(n_index++, n1->weight + n2->weight); lock4.unlock(); } } @@ -202,19 +199,18 @@ void coarse_step(const GraphPtr& original_graph, const GraphPtr& coarse_graph, i b.arrive_and_wait(); NodePtrArr buffer; - for(int i = start; iV(); i+=num_threads){ - if(matched_nodes[i]) continue; + for (int i = start; i < original_graph->V(); i += num_threads) { + if (matched_nodes[i]) + continue; const auto n = original_graph->nodes[i]; buffer.emplace_back(n); } - for(const auto& n: buffer){ + for (const auto &n : buffer) { std::unique_lock lock5(mtx); n->child = coarse_graph->add_node(n_index++, n->weight); lock5.unlock(); } - - } /** @@ -223,12 +219,11 @@ void coarse_step(const GraphPtr& original_graph, const GraphPtr& coarse_graph, i * @param num_threads The number of threads to use * @return The computed graph */ -GraphPtr coarseGraph_p(GraphPtr&g, int num_threads){ - +GraphPtr coarseGraph_p(GraphPtr &g, int num_threads) { g->colours = std::vector(g->V(), -1); -//first we color the graph through a modified version of Luby's algorithm -g->num_colours = colourGraph(g, num_threads); + // first we color the graph through a modified version of Luby's algorithm + g->num_colours = colourGraph(g, num_threads); auto coarse_graph = std::make_shared(); std::mutex mtx; @@ -239,17 +234,17 @@ g->num_colours = colourGraph(g, num_threads); int n_index = 0; std::vector threads; -//a number of threads are instantiated to perform color-based partitioning for(int i = 0; inum_colours, - std::ref(matched_nodes), std::ref(matched_index), std::ref(n_index)); + // a number of threads are instantiated to perform color-based partitioning + for (int i = 0; i < num_threads; i++) + threads.emplace_back(coarse_step, std::ref(g), std::ref(coarse_graph), i, num_threads, std::ref(mtx), std::ref(b), g->num_colours, std::ref(matched_nodes), + std::ref(matched_index), std::ref(n_index)); - for(auto&t: threads) + for (auto &t : threads) t.join(); -//the distances between nodes in the new graph are calculated - for(const auto& e : g->edges){ - if(e->node1.lock()->child->id != e->node2.lock()->child->id) + // the distances between nodes in the new graph are calculated + for (const auto &e : g->edges) { + if (e->node1.lock()->child->id != e->node2.lock()->child->id) coarse_graph->add_or_sum_edge(e->node1.lock()->child, e->node2.lock()->child, e->weight); }