diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 93061cfef..66abd52ec 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -4,7 +4,8 @@ on: push: branches: [ master ] pull_request: - branches: [ master ] + branches: [ master ] + env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release @@ -58,5 +59,5 @@ jobs: working-directory: ${{github.workspace}}/build/test # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest + run: ctest --output-on-failure diff --git a/include/CXXGraph/Partitioning/CoordinatedPartitionState.hpp b/include/CXXGraph/Partitioning/CoordinatedPartitionState.hpp index 1cb2ab62e..d5ae2747f 100644 --- a/include/CXXGraph/Partitioning/CoordinatedPartitionState.hpp +++ b/include/CXXGraph/Partitioning/CoordinatedPartitionState.hpp @@ -54,15 +54,51 @@ class CoordinatedPartitionState : public PartitionState { PartitionMap partition_map; Globals GLOBALS; int MAX_LOAD; - std::shared_ptr machines_load_edges_mutex = nullptr; - std::shared_ptr machines_load_vertices_mutex = nullptr; - std::shared_ptr machines_weight_edges_mutex = nullptr; - std::shared_ptr record_map_mutex = nullptr; + mutable std::mutex machines_load_edges_mutex; + mutable std::mutex machines_load_vertices_mutex; + mutable std::mutex machines_weight_edges_mutex; + mutable std::mutex record_map_mutex; // DatWriter out; //to print the final partition of each edge public: CoordinatedPartitionState(const Globals &G); ~CoordinatedPartitionState(); + // Disable copy + CoordinatedPartitionState(const CoordinatedPartitionState&) = delete; + CoordinatedPartitionState& operator=(const CoordinatedPartitionState&) = delete; + + // Custom move constructor + CoordinatedPartitionState(CoordinatedPartitionState&& other) noexcept + : record_map(std::move(other.record_map)), + machines_load_edges(std::move(other.machines_load_edges)), + machines_weight_edges(std::move(other.machines_weight_edges)), + machines_load_vertices(std::move(other.machines_load_vertices)), + partition_map(std::move(other.partition_map)), + GLOBALS(std::move(other.GLOBALS)), + MAX_LOAD(other.MAX_LOAD) + // mutexes are default-constructed + {} + + // Custom move assignment + CoordinatedPartitionState& operator=(CoordinatedPartitionState&& other) noexcept { + if (this != &other) { + std::lock_guard lock1(machines_load_edges_mutex); + std::lock_guard lock2(machines_load_vertices_mutex); + std::lock_guard lock3(machines_weight_edges_mutex); + std::lock_guard lock4(record_map_mutex); + + record_map = std::move(other.record_map); + machines_load_edges = std::move(other.machines_load_edges); + machines_weight_edges = std::move(other.machines_weight_edges); + machines_load_vertices = std::move(other.machines_load_vertices); + partition_map = std::move(other.partition_map); + GLOBALS = std::move(other.GLOBALS); + MAX_LOAD = other.MAX_LOAD; + // mutexes are default-constructed + } + return *this; + } + std::shared_ptr> getRecord(CXXGraph::id_t x) override; int getMachineLoad(const int m) const override; int getMachineWeight(const int m) const override; @@ -86,11 +122,7 @@ class CoordinatedPartitionState : public PartitionState { template CoordinatedPartitionState::CoordinatedPartitionState(const Globals &G) : record_map(), - GLOBALS(G), - machines_load_edges_mutex(std::make_shared()), - machines_load_vertices_mutex(std::make_shared()), - machines_weight_edges_mutex(std::make_shared()), - record_map_mutex(std::make_shared()) { + GLOBALS(G) { machines_load_edges.reserve(GLOBALS.numberOfPartition); machines_load_vertices.reserve(GLOBALS.numberOfPartition); machines_weight_edges.reserve(GLOBALS.numberOfPartition); @@ -104,12 +136,12 @@ CoordinatedPartitionState::CoordinatedPartitionState(const Globals &G) } template -CoordinatedPartitionState::~CoordinatedPartitionState() {} +CoordinatedPartitionState::~CoordinatedPartitionState() = default; template std::shared_ptr> CoordinatedPartitionState::getRecord( CXXGraph::id_t x) { - std::lock_guard lock(*record_map_mutex); + std::lock_guard lock(record_map_mutex); if (record_map.find(x) == record_map.end()) { record_map[x] = std::make_shared>(); } @@ -118,25 +150,25 @@ std::shared_ptr> CoordinatedPartitionState::getRecord( template int CoordinatedPartitionState::getMachineLoad(const int m) const { - std::lock_guard lock(*machines_load_edges_mutex); + std::lock_guard lock(machines_load_edges_mutex); return (int)machines_load_edges.at(m); } template int CoordinatedPartitionState::getMachineWeight(const int m) const { - std::lock_guard lock(*machines_weight_edges_mutex); + std::lock_guard lock(machines_weight_edges_mutex); return (int)machines_weight_edges.at(m); } template int CoordinatedPartitionState::getMachineLoadVertices(const int m) const { - std::lock_guard lock(*machines_load_vertices_mutex); + std::lock_guard lock(machines_load_vertices_mutex); return (int)machines_load_vertices.at(m); } template void CoordinatedPartitionState::incrementMachineLoad( const int m, shared> e) { - std::lock_guard lock(*machines_load_edges_mutex); + std::lock_guard lock(machines_load_edges_mutex); machines_load_edges[m] = machines_load_edges[m] + 1; int new_value = machines_load_edges.at(m); if (new_value > MAX_LOAD) { @@ -147,22 +179,17 @@ void CoordinatedPartitionState::incrementMachineLoad( template void CoordinatedPartitionState::incrementMachineWeight( const int m, shared> e) { - std::lock_guard lock(*machines_weight_edges_mutex); + std::lock_guard lock(machines_weight_edges_mutex); double edge_weight = CXXGraph::NEGLIGIBLE_WEIGHT; if (e->isWeighted().has_value() && e->isWeighted().value()) { edge_weight = (std::dynamic_pointer_cast(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 int CoordinatedPartitionState::getMinLoad() const { - std::lock_guard lock(*machines_load_edges_mutex); + std::lock_guard lock(machines_load_edges_mutex); int MIN_LOAD = std::numeric_limits::max(); for (const auto &machines_load_edges_it : machines_load_edges) { int loadi = machines_load_edges_it; @@ -178,7 +205,7 @@ int CoordinatedPartitionState::getMaxLoad() const { } template int CoordinatedPartitionState::getMachineWithMinWeight() const { - std::lock_guard lock(*machines_weight_edges_mutex); + std::lock_guard lock(machines_weight_edges_mutex); double MIN_LOAD = std::numeric_limits::max(); int machine_id = 0; @@ -195,7 +222,7 @@ int CoordinatedPartitionState::getMachineWithMinWeight() const { template int CoordinatedPartitionState::getMachineWithMinWeight( const std::set &partitions) const { - std::lock_guard lock(*machines_weight_edges_mutex); + std::lock_guard lock(machines_weight_edges_mutex); double MIN_LOAD = std::numeric_limits::max(); int machine_id = 0; @@ -211,7 +238,7 @@ int CoordinatedPartitionState::getMachineWithMinWeight( } template std::vector CoordinatedPartitionState::getMachines_load() const { - std::lock_guard lock(*machines_load_edges_mutex); + std::lock_guard lock(machines_load_edges_mutex); std::vector result; for (const auto &machines_load_edges_it : machines_load_edges) { result.push_back(machines_load_edges_it); @@ -221,7 +248,7 @@ std::vector CoordinatedPartitionState::getMachines_load() const { template size_t CoordinatedPartitionState::getTotalReplicas() const { // TODO - std::lock_guard lock(*record_map_mutex); + std::lock_guard lock(record_map_mutex); size_t result = 0; for (const auto &record_map_it : record_map) { size_t r = record_map_it.second->getReplicas(); @@ -235,12 +262,12 @@ size_t CoordinatedPartitionState::getTotalReplicas() const { } template size_t CoordinatedPartitionState::getNumVertices() const { - std::lock_guard lock(*record_map_mutex); + std::lock_guard lock(record_map_mutex); return (size_t)record_map.size(); } template std::set CoordinatedPartitionState::getVertexIds() const { - std::lock_guard lock(*record_map_mutex); + std::lock_guard lock(record_map_mutex); // if (GLOBALS.OUTPUT_FILE_NAME!=null){ out.close(); } std::set result; for (const auto &record_map_it : record_map) { @@ -250,13 +277,13 @@ std::set CoordinatedPartitionState::getVertexIds() const { } template void CoordinatedPartitionState::incrementMachineLoadVertices(const int m) { - std::lock_guard lock(*machines_load_vertices_mutex); + std::lock_guard lock(machines_load_vertices_mutex); machines_load_vertices[m] = machines_load_vertices[m] + 1; } template std::vector CoordinatedPartitionState::getMachines_loadVertices() const { - std::lock_guard lock(*machines_load_vertices_mutex); + std::lock_guard lock(machines_load_vertices_mutex); std::vector result; for (const auto &machines_load_vertices_it : machines_load_vertices) { result.push_back(machines_load_vertices_it); diff --git a/include/CXXGraph/Partitioning/Partitioner.hpp b/include/CXXGraph/Partitioning/Partitioner.hpp index e94adbde8..328e7d9a2 100644 --- a/include/CXXGraph/Partitioning/Partitioner.hpp +++ b/include/CXXGraph/Partitioning/Partitioner.hpp @@ -17,11 +17,11 @@ /*** License: MPL v2.0 ***/ /***********************************************************/ -#ifndef __CXXGRAPH_PARTITIONING_PARTITIONER_H__ -#define __CXXGRAPH_PARTITIONING_PARTITIONER_H__ +#ifndef CXXGRAPH_PARTITIONING_PARTITIONER_H_ +#define CXXGRAPH_PARTITIONING_PARTITIONER_H_ -#include #pragma once +#include #include #include "CXXGraph/Edge/Edge.h" @@ -170,6 +170,7 @@ Partitioner::Partitioner(const Partitioner &other) { template CoordinatedPartitionState Partitioner::startCoordinated() { CoordinatedPartitionState state(GLOBALS); + auto shared_state = make_shared>(std::move(state)); int processors = GLOBALS.threads; std::vector myThreads(processors); @@ -184,28 +185,18 @@ CoordinatedPartitionState Partitioner::startCoordinated() { list_vector[t] = std::vector>>( std::next(dataset->begin(), iStart), std::next(dataset->begin(), iEnd)); - myRunnable[t].reset(new PartitionerThread( - list_vector[t], make_shared>(state), - algorithm)); + myRunnable[t].reset( + new PartitionerThread(list_vector[t], shared_state, algorithm)); myThreads[t] = std::thread(&Runnable::run, myRunnable[t].get()); } } for (int t = 0; t < processors; ++t) { - if (myThreads[t].joinable()) { - myThreads[t].join(); - } - // if(myRunnable[t] != nullptr){ - // delete myRunnable[t]; - //} + myThreads[t].join(); } - /* - for (int t = 0; t < processors; ++t){ - if (runnableList[t] != nullptr){ - delete runnableList[t]; - } - } - */ - return state; + + // new shared state is move constructed then returned + // (so has no effect on the shared ponter) + return std::move(*shared_state); } template @@ -235,4 +226,4 @@ PartitionMap Partitioner::partitionGraph( } // namespace Partitioning } // namespace CXXGraph -#endif // __CXXGRAPH_PARTITIONING_PARTITIONER_H__ +#endif // CXXGRAPH_PARTITIONING_PARTITIONER_H_