Skip to content

Commit

Permalink
Generating individuals in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
V0G3L committed Aug 5, 2024
1 parent 44d6d5d commit ed0e46b
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ clang-debug/*
*.cfg~
build/*
build2/*
build_debug/*
build_numa/*
build_nlevel/*
build_interleaved/*
Expand Down
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ if [ ! -f build/Makefile ]; then
mkdir -p build
fi

#cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug $CMAKE_COMMANDS && cd ${ROOT}
#cd build_debug && cmake .. -DCMAKE_BUILD_TYPE=Debug $CMAKE_COMMANDS && cd ${ROOT}
#cmake --build build_debug --parallel "$(get_num_cores)" --target MtKaHyPar
cd build && cmake .. -DCMAKE_BUILD_TYPE=Release $CMAKE_COMMANDS && cd ${ROOT}
cmake --build build --parallel "$(get_num_cores)" --target MtKaHyPar

5 changes: 3 additions & 2 deletions config/evolutionary_preset.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ smallest-maxnet-threshold=50000
maxnet-ignore=1000
num-vcycles=0
partition-evolutionary=true
time-limit= 10
time-limit= 60
#300
# main -> shared_memory
s-use-localized-random-shuffle=false
Expand Down Expand Up @@ -96,7 +96,8 @@ max-steiner-tree-size=4
mapping-largest-he-fraction=0.0
mapping-min-pin-coverage=0.05
#main -> evolutionary
evolutionary.population_size=2;
evolutionary.population_size=1;
#100
evolutionary.dynamic_population_size=false;
evolutionary.dynamic_population_amount_of_time=0.15;
evolutionary.diversify_interval=1;
Expand Down
1 change: 1 addition & 0 deletions mt-kahypar/partition/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ struct EvolutionaryParameters {
bool dynamic_population_size;
double dynamic_population_amount_of_time;
mutable int iteration;
mutable std::chrono::milliseconds time_elapsed;
std::string history_file;
};

Expand Down
4 changes: 3 additions & 1 deletion mt-kahypar/partition/context_enum_classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ namespace mt_kahypar {
std::ostream& operator<< (std::ostream& os, const ContextType& type) {
if (type == ContextType::main) {
return os << "main";
} else {
} else if (type == ContextType::initial_partitioning) {
return os << "ip";
} else {
return os << "evo";
}
return os << static_cast<uint8_t>(type);
}
Expand Down
5 changes: 3 additions & 2 deletions mt-kahypar/partition/context_enum_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ enum class PresetType : int8_t {
UNDEFINED
};

enum class ContextType : bool {
enum class ContextType : uint8_t {
main,
initial_partitioning
initial_partitioning,
evolutionary
};

enum class Mode : uint8_t {
Expand Down
115 changes: 98 additions & 17 deletions mt-kahypar/partition/evo_partitioner.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "evo_partitioner.h"
#include "partitioner.cpp"
#include <mutex>

namespace mt_kahypar {

Expand Down Expand Up @@ -95,6 +96,10 @@ namespace mt_kahypar {
//context.evolutionary.dynamic_population_size = true;
//context.evolutionary.population_size = 50;
utils::Timer& timer = utils::Utilities::instance().getTimer(context.utility_id);
auto start = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
auto time_elapsed = now - start;
auto duration = std::chrono::seconds(timelimit);
// INITIAL POPULATION
if (context.evolutionary.dynamic_population_size) {
HighResClockTimepoint start = std::chrono::high_resolution_clock::now();
Expand All @@ -112,13 +117,17 @@ namespace mt_kahypar {
LOG << context.evolutionary.population_size;
LOG << population;
}
while (population.size() < context.evolutionary.population_size &&
timer.get("evolutionary") <= timelimit) {
while (population.size() < context.evolutionary.population_size &&
time_elapsed <= duration) {
//timer.get("evolutionary") <= timelimit) {
++context.evolutionary.iteration;
timer.start_timer("evolutionary", "Evolutionary");
generateIndividual(hg, context, target_graph, population);
timer.stop_timer("evolutionary");
now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
time_elapsed = now - start;
}
context.evolutionary.time_elapsed = time_elapsed;
context.partition.verbose_output = true;
}

Expand Down Expand Up @@ -249,6 +258,7 @@ namespace mt_kahypar {
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
ret = "" + std::to_string(time.count()) + ", Combine, " + std::to_string(individual.fitness()) + "\n";
}
std::lock_guard<std::mutex> lock = population.getLock();
population.insert(std::move(individual), context);
return ret;
}
Expand Down Expand Up @@ -301,44 +311,115 @@ namespace mt_kahypar {
ret = "" + std::to_string(time.count()) + ", MutateNew, " + std::to_string(individual.fitness()) + "\n";
}
}
std::lock_guard<std::mutex> lock = population.getLock();
population.insert(std::move(individual), context);
return ret;
}

inline void disableTimerAndStatsEvo(const Context& context) {
if ( context.type == ContextType::main && context.partition.mode == Mode::direct ) {
utils::Utilities& utils = utils::Utilities::instance();
parallel::MemoryPool::instance().deactivate_unused_memory_allocations();
utils.getTimer(context.utility_id).disable();
utils.getStats(context.utility_id).disable();
}
}

inline void enableTimerAndStatsEvo(const Context& context) {
if ( context.type == ContextType::main && context.partition.mode == Mode::direct ) {
utils::Utilities& utils = utils::Utilities::instance();
parallel::MemoryPool::instance().activate_unused_memory_allocations();
utils.getTimer(context.utility_id).enable();
utils.getStats(context.utility_id).enable();
}
}

template<typename TypeTraits>
void EvoPartitioner<TypeTraits>::performEvolution(EvoPartitioner<TypeTraits>::Hypergraph& hg, Context& context, TargetGraph* target_graph, Population& population) {
context.partition.verbose_output = false;
int timelimit = context.partition.time_limit;
utils::Timer& timer = utils::Utilities::instance().getTimer(context.utility_id);
int mutations = 0;
int combinations = 0;
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
std::string history = "" + std::to_string(time.count()) + ", Initial, " + std::to_string(population.bestFitness()) + "\n";
while (timer.get("evolutionary") <= timelimit) {
auto time_start = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
std::string history = "" + std::to_string(time_start.count()) + ", Initial, " + std::to_string(population.bestFitness()) + "\n";
std::mutex _history_mutex;
/*while (timer.get("evolutionary") <= timelimit) {
++context.evolutionary.iteration;
timer.start_timer("evolutionary", "Evolutionary");

tbb::parallel_for(0, 1, [&](const int i) {
tbb::parallel_for(0, 4, [&](const int i) {
Context evo_context(context);
evo_context.type = ContextType::main;
evo_context.utility_id = utils::Utilities::instance().registerNewUtilityObjects();
EvoDecision decision = decideNextMove(context);
EvoPartitioner<TypeTraits>::Hypergraph hg_copy = hg.copy();
switch (decision) {
case EvoDecision::mutation:
history += performMutation(hg, context, target_graph, population);
mutations++;
break;
case EvoDecision::combine:
history += performCombine(hg, context, target_graph, population);
combinations++;
break;
case EvoDecision::mutation:
{
std::lock_guard<std::mutex> lock(_history_mutex);
history += performMutation(hg_copy, evo_context, target_graph, population);
mutations++;
break;
}
case EvoDecision::combine:
{
std::lock_guard<std::mutex> lock(_history_mutex);
history += performCombine(hg_copy, evo_context, target_graph, population);
combinations++;
break;
}
default:
LOG << "Error in evo_partitioner.cpp: Non-covered case in decision making";
std::exit(EXIT_FAILURE);
}
});
timer.stop_timer("evolutionary");
}
hg.reset();
}*/

auto duration = std::chrono::seconds(timelimit) - context.evolutionary.time_elapsed;
std::atomic<bool> stop_flag(false);
timer.start_timer("evolutionary", "Evolutionary");
tbb::parallel_for(0, int(context.shared_memory.num_threads), [&](int) {
while(!stop_flag) {
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch());
if (now - time_start >= duration) {
stop_flag = true;
break;
}
Context evo_context(context);
evo_context.type = ContextType::main;
evo_context.utility_id = utils::Utilities::instance().registerNewUtilityObjects();
EvoDecision decision = decideNextMove(context);
EvoPartitioner<TypeTraits>::Hypergraph hg_copy = hg.copy();
switch (decision) {
case EvoDecision::mutation:
{
std::string h = performMutation(hg_copy, evo_context, target_graph, population);
std::lock_guard<std::mutex> lock(_history_mutex);
history += h;
mutations++;
++context.evolutionary.iteration;
break;
}
case EvoDecision::combine:
{
std::lock_guard<std::mutex> lock(_history_mutex);
std::string h = performCombine(hg_copy, evo_context, target_graph, population);
combinations++;
history += h;
++context.evolutionary.iteration;
break;
}
default:
LOG << "Error in evo_partitioner.cpp: Non-covered case in decision making";
std::exit(EXIT_FAILURE);
}
}
});
timer.stop_timer("evolutionary");

context.partition.verbose_output = true;
LOG << "Performed " << context.evolutionary.iteration << " Evolutionary Iterations" << "\n";
LOG << " " << (context.evolutionary.iteration - mutations - combinations)
Expand Down
6 changes: 6 additions & 0 deletions mt-kahypar/partition/evolutionary/population.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Population {

public:
explicit Population() :
_population_mutex(),
_individuals() { }

inline size_t insert(Individual&& individual, const Context& context) {
Expand Down Expand Up @@ -225,6 +226,10 @@ class Population {
return output_diff.size();
}

std::lock_guard<std::mutex> getLock() {
return std::lock_guard<std::mutex>(_population_mutex);
}

private:
inline size_t replaceDiverse(Individual&& individual, const bool strong_set) {
size_t max_similarity = std::numeric_limits<size_t>::max();
Expand All @@ -248,6 +253,7 @@ class Population {
return max_similarity_id;
}

std::mutex _population_mutex;
std::vector<Individual> _individuals;
};
std::ostream& operator<< (std::ostream& os, const Population& population);
Expand Down
4 changes: 2 additions & 2 deletions mt-kahypar/partition/multilevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ namespace {
const TargetGraph* target_graph,
const bool is_vcycle,
std::unordered_map<PartitionID, int> comm_to_block) {
disableTimerAndStats(context);
//disableTimerAndStats(context);
using Hypergraph = typename TypeTraits::Hypergraph;
using PartitionedHypergraph = typename TypeTraits::PartitionedHypergraph;
PartitionedHypergraph partitioned_hg;
Expand Down Expand Up @@ -302,7 +302,7 @@ namespace {

io::printPartitioningResults(partitioned_hg, context, "Local Search Results:");

enableTimerAndStats(context);
//enableTimerAndStats(context);
return partitioned_hg;
}
}
Expand Down

0 comments on commit ed0e46b

Please sign in to comment.