Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce WeightBalancedLibra algorithm(vertex-cut graph partition) #249

Merged
merged 1 commit into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/Graph/Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2486,10 +2486,10 @@ namespace CXXGRAPH
}

template <typename T>
PartitionMap<T> Graph<T>::partitionGraph(PARTITIONING::PartitionAlgorithm algorithm, unsigned int numberOfPartitions, double param1, double param2, double param3, unsigned int numberOfthreads) const
PartitionMap<T> Graph<T>::partitionGraph(PARTITIONING::PartitionAlgorithm algorithm, unsigned int numberOfPartitions, double param1, double param2, double param3, unsigned int numberOfThreads) const
{
PartitionMap<T> partitionMap;
PARTITIONING::Globals globals(numberOfPartitions, algorithm, param1, param2, param3, numberOfthreads);
PARTITIONING::Globals globals(numberOfPartitions, algorithm, param1, param2, param3, numberOfThreads);
const T_EdgeSet<T> & edgeSet = getEdgeSet();
globals.edgeCardinality = edgeSet.size();
globals.vertexCardinality = this->getNodeSet().size();
Expand Down
80 changes: 79 additions & 1 deletion include/Partitioning/CoordinatedPartitionState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ namespace CXXGRAPH
private:
std::map<int, std::shared_ptr<CoordinatedRecord<T>>> record_map;
std::vector<int> machines_load_edges;
std::vector<double> machines_weight_edges;
std::vector<int> machines_load_vertices;
PartitionMap<T> partition_map;
Globals GLOBALS;
int MAX_LOAD;
std::shared_ptr<std::mutex> machines_load_edges_mutex = nullptr;
std::shared_ptr<std::mutex> machines_load_vertices_mutex = nullptr;
std::shared_ptr<std::mutex> machines_weight_edges_mutex = nullptr;
std::shared_ptr<std::mutex> record_map_mutex = nullptr;
//DatWriter out; //to print the final partition of each edge
public:
Expand All @@ -56,10 +58,14 @@ namespace CXXGRAPH

std::shared_ptr<Record<T>> getRecord(int x);
int getMachineLoad(int m);
int getMachineWeight(int m);
int getMachineLoadVertices(int m);
void incrementMachineLoad(int m, const Edge<T> *e);
void incrementMachineWeight(int m, const Edge<T> *e);
int getMinLoad();
int getMaxLoad();
int getMachineWithMinWeight();
int getMachineWithMinWeight(const std::set<int> &partitions);
std::vector<int> getMachines_load();
int getTotalReplicas();
int getNumVertices();
Expand All @@ -70,12 +76,22 @@ namespace CXXGRAPH
const PartitionMap<T> &getPartitionMap();
};
template <typename T>
CoordinatedPartitionState<T>::CoordinatedPartitionState(Globals &G) : record_map(), GLOBALS(G), machines_load_edges_mutex(std::make_shared<std::mutex>()), machines_load_vertices_mutex(std::make_shared<std::mutex>()), record_map_mutex(std::make_shared<std::mutex>())
CoordinatedPartitionState<T>::CoordinatedPartitionState(Globals &G)
: record_map(),
GLOBALS(G),
machines_load_edges_mutex(std::make_shared<std::mutex>()),
machines_load_vertices_mutex(std::make_shared<std::mutex>()),
machines_weight_edges_mutex(std::make_shared<std::mutex>()),
record_map_mutex(std::make_shared<std::mutex>())
{
machines_load_edges.reserve(GLOBALS.numberOfPartition);
machines_load_vertices.reserve(GLOBALS.numberOfPartition);
machines_weight_edges.reserve(GLOBALS.numberOfPartition);
for (int i = 0; i < GLOBALS.numberOfPartition; ++i)
{
machines_load_edges.push_back(0);
machines_load_vertices.push_back(0);
machines_weight_edges.push_back(0);
partition_map[i] = std::make_shared<PARTITIONING::Partition<T>>(i);
}
MAX_LOAD = 0;
Expand All @@ -102,6 +118,13 @@ namespace CXXGRAPH
return machines_load_edges.at(m);
}

template <typename T>
int CoordinatedPartitionState<T>::getMachineWeight(int m)
{
std::lock_guard<std::mutex> lock(*machines_weight_edges_mutex);
return machines_weight_edges.at(m);
}

template <typename T>
int CoordinatedPartitionState<T>::getMachineLoadVertices(int m)
{
Expand All @@ -121,6 +144,23 @@ namespace CXXGRAPH
partition_map[m]->addEdge(e);
}
template <typename T>
void CoordinatedPartitionState<T>::incrementMachineWeight(int m, const Edge<T> *e)
{
std::lock_guard<std::mutex> lock(*machines_weight_edges_mutex);
double edge_weight = CXXGRAPH::NEGLIGIBLE_WEIGHT;
if (e->isWeighted().has_value() && e->isWeighted().value())
{
edge_weight = (dynamic_cast<const Weighted *>(e))->getWeight();
}
machines_weight_edges[m] = machines_weight_edges[m] + edge_weight;
//double new_value = machines_weight_edges[m];
//if (new_value > MAX_LOAD)
//{
// MAX_LOAD = new_value;
//}
partition_map[m]->addEdge(e);
}
template <typename T>
int CoordinatedPartitionState<T>::getMinLoad()
{
std::lock_guard<std::mutex> lock(*machines_load_edges_mutex);
Expand All @@ -141,6 +181,44 @@ namespace CXXGRAPH
return MAX_LOAD;
}
template <typename T>
int CoordinatedPartitionState<T>::getMachineWithMinWeight()
{
std::lock_guard<std::mutex> lock(*machines_weight_edges_mutex);

double MIN_LOAD = std::numeric_limits<double>::max();
int machine_id = 0;
for (int i = 0; i < machines_weight_edges.size(); ++i)
{
double loadi = machines_weight_edges[i];
if (loadi < MIN_LOAD)
{
MIN_LOAD = loadi;
machine_id = i;
}
}

return machine_id;
}
template <typename T>
int CoordinatedPartitionState<T>::getMachineWithMinWeight(const std::set<int> &partitions)
{
std::lock_guard<std::mutex> lock(*machines_weight_edges_mutex);

double MIN_LOAD = std::numeric_limits<double>::max();
int machine_id = 0;
for (const auto &partition_id : partitions)
{
double loadi = machines_weight_edges.at(partition_id);
if (loadi < MIN_LOAD)
{
MIN_LOAD = loadi;
machine_id = partition_id;
}
}

return machine_id;
}
template <typename T>
std::vector<int> CoordinatedPartitionState<T>::getMachines_load()
{
std::lock_guard<std::mutex> lock(*machines_load_edges_mutex);
Expand Down
36 changes: 27 additions & 9 deletions include/Partitioning/CoordinatedRecord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,35 @@ namespace CXXGRAPH
void incrementDegree();

void addAll(std::set<int> &set);
std::set<int> intersection(CoordinatedRecord &x, CoordinatedRecord &y);
std::set<int> partition_intersection(std::shared_ptr<CoordinatedRecord> other);
std::set<int> partition_union(std::shared_ptr<CoordinatedRecord> other);
std::set<int> partition_difference(std::shared_ptr<CoordinatedRecord> other);
};
template <typename T>
std::set<int> CoordinatedRecord<T>::partition_intersection(std::shared_ptr<CoordinatedRecord> other)
{
std::set<int> result;
set_intersection(this->partitions.begin(), this->partitions.end(), other->partitions.begin(), other->partitions.end(),
std::inserter(result, result.begin()));
return result;
}
template <typename T>
std::set<int> CoordinatedRecord<T>::partition_union(std::shared_ptr<CoordinatedRecord> other)
{
std::set<int> result;
set_union(this->partitions.begin(), this->partitions.end(), other->partitions.begin(), other->partitions.end(),
std::inserter(result, result.begin()));
return result;
}
template <typename T>
std::set<int> CoordinatedRecord<T>::partition_difference(std::shared_ptr<CoordinatedRecord> other)
{
std::set<int> result;
set_difference(this->partitions.begin(), this->partitions.end(), other->partitions.begin(), other->partitions.end(),
std::inserter(result, result.begin()));
return result;
}
template <typename T>
CoordinatedRecord<T>::CoordinatedRecord() : partitions()
{
lock = new std::mutex();
Expand Down Expand Up @@ -120,14 +146,6 @@ namespace CXXGRAPH
{
partitions.insert(set.begin(), set.end());
}
template <typename T>
std::set<int> CoordinatedRecord<T>::intersection(CoordinatedRecord &x, CoordinatedRecord &y)
{
std::set<int> result;
set_intersection(x.partitions.begin(), x.partitions.end(), y.partitions.begin(), y.partitions.end(),
std::inserter(result, result.begin()));
return result;
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion include/Partitioning/PartitionAlgorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace CXXGRAPH
GREEDY_VC_ALG, ///< A Greedy Algorithm
HDRF_ALG, ///< High-Degree (are) Replicated First (HDRF) Algorithm (Stream-Based Vertex-Cut Partitioning)
EBV_ALG, ///< Edge-Balanced Vertex-Cut Offline Algorithm (EBV)
ALG_2
ALG_2,
WB_LIBRA, ///< Weighted Balanced Libra
};
typedef E_PartitionAlgorithm PartitionAlgorithm;
}
Expand Down
6 changes: 5 additions & 1 deletion include/Partitioning/PartitionState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ namespace CXXGRAPH
public:
virtual std::shared_ptr<Record<T>> getRecord(int x) = 0;
virtual int getMachineLoad(int m) = 0;
virtual int getMachineWeight(int m) = 0;
virtual int getMachineLoadVertices(int m) = 0;
virtual void incrementMachineLoad(int m,const Edge<T>* e) = 0;
virtual void incrementMachineLoad(int m, const Edge<T>* e) = 0;
virtual void incrementMachineWeight(int m, const Edge<T>* e) = 0;
virtual int getMinLoad() = 0;
virtual int getMaxLoad() = 0;
virtual int getMachineWithMinWeight() = 0;
virtual int getMachineWithMinWeight(const std::set<int> &partitions) = 0;
virtual std::vector<int> getMachines_load() = 0;
virtual int getTotalReplicas() = 0;
virtual int getNumVertices() = 0;
Expand Down
52 changes: 51 additions & 1 deletion include/Partitioning/Partitioner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "EdgeBalancedVertexCut.hpp"
#include "GreedyVertexCut.hpp"
#include "EBV.hpp"
#include "WeightBalancedLibra.hpp"

namespace CXXGRAPH
{
Expand Down Expand Up @@ -73,8 +74,32 @@ namespace CXXGRAPH
} else if (GLOBALS.partitionStategy == PartitionAlgorithm::EBV_ALG)
{
algorithm = new EBV<T>(GLOBALS);
}
} else if (GLOBALS.partitionStategy == PartitionAlgorithm::WB_LIBRA)
{
// precompute weight sum
double weight_sum = 0.0;
for (const auto &edge_it : *(this->dataset))
{
weight_sum += (edge_it->isWeighted().has_value() && edge_it->isWeighted().value()) ? dynamic_cast<const Weighted *>(edge_it)->getWeight() : CXXGRAPH::NEGLIGIBLE_WEIGHT;
}
double lambda = std::max(1.0, GLOBALS.param1);
double P = static_cast<double>(GLOBALS.numberOfPartition);
// avoid divide by zero when some parameters are invalid
double weight_sum_bound = (GLOBALS.numberOfPartition == 0) ? 0.0 : lambda * weight_sum / P;

// precompute degrees of vertices
std::unordered_map<std::size_t, int> vertices_degrees;
for (const auto &edge_it : *(this->dataset))
{
auto nodePair = edge_it->getNodePair();
std::size_t u = nodePair.first->getId();
std::size_t v = nodePair.second->getId();
vertices_degrees[u]++;
vertices_degrees[v]++;
}

algorithm = new WeightBalancedLibra<T>(GLOBALS, weight_sum_bound, move(vertices_degrees));
}
}

template <typename T>
Expand All @@ -93,6 +118,31 @@ namespace CXXGRAPH
} else if (GLOBALS.partitionStategy == PartitionAlgorithm::EBV_ALG)
{
algorithm = new EBV<T>(GLOBALS);
} else if (GLOBALS.partitionStategy == PartitionAlgorithm::WB_LIBRA)
{
// precompute weight sum
double weight_sum = 0.0;
for (const auto &edge_it : *(this->dataset))
{
weight_sum += (edge_it->isWeighted().has_value() && edge_it->isWeighted().value()) ? dynamic_cast<const Weighted *>(edge_it)->getWeight() : CXXGRAPH::NEGLIGIBLE_WEIGHT;
}
double lambda = GLOBALS.param1;
double P = static_cast<double>(GLOBALS.numberOfPartition);
// avoid divide by zero when some parameters are invalid
double weight_sum_bound = (GLOBALS.numberOfPartition == 0) ? 0.0 : lambda * weight_sum / P;

// precompute degrees of vertices
std::unordered_map<std::size_t, int> vertices_degrees;
for (const auto &edge_it : *(this->dataset))
{
auto nodePair = edge_it->getNodePair();
std::size_t u = nodePair.first->getId();
std::size_t v = nodePair.second->getId();
vertices_degrees[u]++;
vertices_degrees[v]++;
}

algorithm = new WeightBalancedLibra<T>(GLOBALS, weight_sum_bound, move(vertices_degrees));
}
}

Expand Down
7 changes: 6 additions & 1 deletion include/Partitioning/Utility/Globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,18 @@ namespace CXXGRAPH {
};

inline Globals::Globals(int numberOfPartiton, PartitionAlgorithm algorithm,double param1, double param2, double param3, unsigned int threads)
{
{
this->numberOfPartition = numberOfPartiton;
this->partitionStategy = algorithm;
this->threads = threads;
this->param1 = param1;
this->param2 = param2;
this->param3 = param3;
if (this->numberOfPartition <= 0)
{
std::cout << "ERROR: numberOfPartition " << numberOfPartition << std::endl;
exit(-1);
}
}

inline Globals::~Globals()
Expand Down
Loading