From 8b5be625244b8a2764d254885fad5c67a825caa3 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Fri, 12 Oct 2018 11:06:04 -0700 Subject: [PATCH] Add tuner components --- src/Tuner/autotuner.cc | 2 +- src/Tuner/multituner.cc | 145 +++++++++++++++++++++++++++++++++ src/Tuner/multituner.h | 47 +++++++++++ src/Tuner/searchtuner.cc | 9 +- src/Tuner/searchtuner.h | 6 +- src/Tuner/staticautotuner.cc | 6 +- src/Tuner/staticautotuner.h | 4 +- src/Tuner/staticsearchtuner.cc | 30 +++---- src/Tuner/staticsearchtuner.h | 9 +- src/Tuner/tunable.cc | 74 ++++++++--------- src/Tuner/tunable.h | 4 +- 11 files changed, 266 insertions(+), 70 deletions(-) create mode 100644 src/Tuner/multituner.cc create mode 100644 src/Tuner/multituner.h diff --git a/src/Tuner/autotuner.cc b/src/Tuner/autotuner.cc index e448834..b769993 100644 --- a/src/Tuner/autotuner.cc +++ b/src/Tuner/autotuner.cc @@ -94,7 +94,7 @@ void AutoTuner::tune() { } model_print("Best tuner:\n"); bestTuner->print(); - bestTuner->serialize(); + bestTuner->serialize("TUNER.conf"); model_print("Received score %f\n", bestScore); if (bestTuner != NULL) delete bestTuner; diff --git a/src/Tuner/multituner.cc b/src/Tuner/multituner.cc new file mode 100644 index 0000000..f694084 --- /dev/null +++ b/src/Tuner/multituner.cc @@ -0,0 +1,145 @@ +#include "multituner.h" +#include "csolver.h" +#include "searchtuner.h" +#include +#include +#include +#include +#include +#include + + +#define UNSETVALUE -1 +#define TIMEOUTSEC 5000 + +Problem::Problem(const char *_problem) : result(UNSETVALUE) { + uint len = strlen(_problem); + problem = (char *) ourmalloc(len + 1); + memcpy(problem, _problem, len + 1); +} + +Problem::~Problem() { + ourfree(problem); +} + +MultiTuner::MultiTuner(uint _budget, uint _timeout) : + budget(_budget), timeout(_timeout), execnum(0) { +} + +MultiTuner::~MultiTuner() { + for (uint i = 0; i < problems.getSize(); i++) + ourfree(problems.get(i)); +} + +void MultiTuner::addProblem(const char *filename) { + problems.push(new Problem(filename)); +} + +void MultiTuner::addTuner(SearchTuner *tuner) { + tuners.push(new TunerRecord(tuner)); +} + +long long MultiTuner::evaluate(Problem *problem, SearchTuner *tuner) { + char buffer[512]; + //Write out the tuner + snprintf(buffer, sizeof(buffer), "tuner%u", execnum); + tuner->serialize(buffer); + + //Do run + snprintf(buffer, sizeof(buffer), "deserializerun %s %u tuner%u result%s%u", problem->getProblem(), timeout, execnum, problem->getProblem(), execnum); + int status = system(buffer); + + long long metric = -1; + int sat = IS_INDETER; + if (status == 0) { + //Read data in from results file + snprintf(buffer, sizeof(buffer), "result%s%u", problem->getProblem(), execnum); + + ifstream myfile; + myfile.open (buffer, ios::in); + + + if (myfile.is_open()) { + myfile >> metric; + myfile >> sat; + myfile.close(); + } + } + //Increment execution count + execnum++; + + if (problem->result == UNSETVALUE && sat != IS_INDETER) { + problem->result = sat; + } else if (problem->result != sat && sat != IS_INDETER) { + model_print("******** Result has changed ********\n"); + } + return metric; +} + +double MultiTuner::evaluateAll(SearchTuner *tuner) { + double product = 1; + for (uint i = 0; i < problems.getSize(); i++) { + Problem *problem = problems.get(i); + double score = evaluate(problem, tuner); + product *= score; + } + return pow(product, 1 / ((double)problems.getSize())); +} + +SearchTuner *MultiTuner::mutateTuner(SearchTuner *oldTuner, uint k) { + SearchTuner *newTuner = oldTuner->copyUsed(); + uint numSettings = oldTuner->getSize(); + uint settingsToMutate = (uint)(AUTOTUNERFACTOR * (((double)numSettings) * (budget - k)) / (budget)); + if (settingsToMutate < 1) + settingsToMutate = 1; + model_print("Mutating %u settings\n", settingsToMutate); + while (settingsToMutate-- != 0) { + newTuner->randomMutate(); + } + return newTuner; +} + +void MultiTuner::tune() { + SearchTuner *bestTuner = NULL; + double bestScore = DBL_MAX; + + SearchTuner *oldTuner = new SearchTuner(); + double base_temperature = evaluateAll(oldTuner); + double oldScore = base_temperature; + + for (uint i = 0; i < budget; i++) { + SearchTuner *newTuner = mutateTuner(oldTuner, i); + double newScore = evaluateAll(newTuner); + newTuner->printUsed(); + model_print("Received score %f\n", newScore); + double scoreDiff = newScore - oldScore; //smaller is better + if (newScore < bestScore) { + if (bestTuner != NULL) + delete bestTuner; + bestScore = newScore; + bestTuner = newTuner->copyUsed(); + } + + double acceptanceP; + if (scoreDiff < 0) { + acceptanceP = 1; + } else { + double currTemp = base_temperature * (((double)budget - i) / budget); + acceptanceP = exp(-scoreDiff / currTemp); + } + double ran = ((double)random()) / RAND_MAX; + if (ran <= acceptanceP) { + delete oldTuner; + oldScore = newScore; + oldTuner = newTuner; + } else { + delete newTuner; + } + } + model_print("Best tuner:\n"); + bestTuner->print(); + model_print("Received score %f\n", bestScore); + if (bestTuner != NULL) + delete bestTuner; + delete oldTuner; +} diff --git a/src/Tuner/multituner.h b/src/Tuner/multituner.h new file mode 100644 index 0000000..fffc5c2 --- /dev/null +++ b/src/Tuner/multituner.h @@ -0,0 +1,47 @@ +#ifndef MULTITUNER_H +#define MULTITUNER_H +#include "classlist.h" +#include "structs.h" + +#define AUTOTUNERFACTOR 0.3 + +class Problem { +public: + Problem(const char *problem); + char *getProblem() {return problem;} + ~Problem(); + CMEMALLOC; +private: + int result; + char *problem; + friend class MultiTuner; +}; + +class TunerRecord { +public: + TunerRecord(SearchTuner *_tuner) : tuner(_tuner) {} + +private: + SearchTuner *tuner; + friend class MultiTuner; +}; + +class MultiTuner { +public: + MultiTuner(uint budget, uint timeout); + ~MultiTuner(); + void addProblem(const char *filename); + void addTuner(SearchTuner *tuner); + virtual void tune(); + CMEMALLOC; +protected: + long long evaluate(Problem *problem, SearchTuner *tuner); + double evaluateAll(SearchTuner *tuner); + SearchTuner *mutateTuner(SearchTuner *oldTuner, uint k); + Vector problems; + Vector tuners; + uint budget; + uint timeout; + int execnum; +}; +#endif diff --git a/src/Tuner/searchtuner.cc b/src/Tuner/searchtuner.cc index bfe66bb..674758e 100644 --- a/src/Tuner/searchtuner.cc +++ b/src/Tuner/searchtuner.cc @@ -72,8 +72,11 @@ ostream &operator<<(ostream &os, const TunableSetting &ts) SearchTuner::SearchTuner() { +} + +SearchTuner::SearchTuner(const char *filename) { ifstream myfile; - myfile.open (TUNEFILE, ios::in); + myfile.open (filename, ios::in); if (myfile.is_open()) { bool hasVar; VarType type1; @@ -179,9 +182,9 @@ void SearchTuner::print() { } -void SearchTuner::serialize() { +void SearchTuner::serialize(const char *filename) { ofstream myfile; - myfile.open (TUNEFILE, ios::out | ios::trunc); + myfile.open (filename, ios::out | ios::trunc); SetIteratorTunableSetting *iterator = settings.iterator(); while (iterator->hasNext()) { TunableSetting *setting = iterator->next(); diff --git a/src/Tuner/searchtuner.h b/src/Tuner/searchtuner.h index 107926d..e00a6dd 100644 --- a/src/Tuner/searchtuner.h +++ b/src/Tuner/searchtuner.h @@ -5,7 +5,6 @@ #include "structs.h" #include using namespace std; -#define TUNEFILE "tune.conf" class TunableSetting { public: @@ -29,7 +28,7 @@ private: friend unsigned int tunableSettingHash(TunableSetting *setting); friend bool tunableSettingEquals(TunableSetting *setting1, TunableSetting *setting2); friend class SearchTuner; - friend class StaticSearchTuner; + friend class StaticSearchTuner; }; unsigned int tunableSettingHash(TunableSetting *setting); @@ -41,6 +40,7 @@ typedef SetIteratorcopyUsed(); result = newTuner->nextStaticTuner(); - return result==EXIT_FAILURE? newTuner: NULL; + return result == EXIT_FAILURE ? newTuner : NULL; } void StaticAutoTuner::tune() { @@ -24,9 +24,9 @@ void StaticAutoTuner::tune() { double base_temperature = evaluateAll(oldTuner); double oldScore = base_temperature; - while(true){ + while (true) { StaticSearchTuner *newTuner = mutateTuner(oldTuner); - if(newTuner == NULL) + if (newTuner == NULL) return; double newScore = evaluateAll(newTuner); newTuner->printUsed(); diff --git a/src/Tuner/staticautotuner.h b/src/Tuner/staticautotuner.h index cc0d1e2..127d53f 100644 --- a/src/Tuner/staticautotuner.h +++ b/src/Tuner/staticautotuner.h @@ -6,8 +6,8 @@ class StaticAutoTuner : public AutoTuner { public: StaticAutoTuner(uint budget); - virtual void tune(); - CMEMALLOC; + virtual void tune(); + CMEMALLOC; private: StaticSearchTuner *mutateTuner(StaticSearchTuner *oldTuner); }; diff --git a/src/Tuner/staticsearchtuner.cc b/src/Tuner/staticsearchtuner.cc index e3cc3fa..5cedc71 100644 --- a/src/Tuner/staticsearchtuner.cc +++ b/src/Tuner/staticsearchtuner.cc @@ -4,8 +4,8 @@ using namespace std; StaticSearchTuner::StaticSearchTuner() { - graphEncoding =false; - naiveEncoding = ELEM_UNASSIGNED; + graphEncoding = false; + naiveEncoding = ELEM_UNASSIGNED; ifstream myfile; myfile.open (TUNEFILE, ios::in); if (myfile.is_open()) { @@ -40,7 +40,7 @@ StaticSearchTuner *StaticSearchTuner::copyUsed() { TunableSetting *copy = new TunableSetting(setting); tuner->settings.add(copy); } - if(naiveEncoding != ELEM_UNASSIGNED){ + if (naiveEncoding != ELEM_UNASSIGNED) { tuner->graphEncoding = graphEncoding; tuner->naiveEncoding = naiveEncoding; } @@ -58,38 +58,38 @@ StaticSearchTuner::~StaticSearchTuner() { } int StaticSearchTuner::nextStaticTuner() { - if(naiveEncoding == ELEM_UNASSIGNED){ + if (naiveEncoding == ELEM_UNASSIGNED) { naiveEncoding = ONEHOT; SetIteratorTunableSetting *iter = settings.iterator(); - while(iter->hasNext()){ + while (iter->hasNext()) { TunableSetting *setting = iter->next(); - if (setting->param == NAIVEENCODER){ + if (setting->param == NAIVEENCODER) { setting->selectedValue = ONEHOT; - } else if(setting->param == ENCODINGGRAPHOPT){ + } else if (setting->param == ENCODINGGRAPHOPT) { setting->selectedValue = false; } } delete iter; return EXIT_FAILURE; } - int result=EXIT_FAILURE; - if(naiveEncoding == BINARYINDEX && graphEncoding){ + int result = EXIT_FAILURE; + if (naiveEncoding == BINARYINDEX && graphEncoding) { model_print("Best tuner\n"); return EXIT_SUCCESS; - }else if (naiveEncoding == BINARYINDEX && !graphEncoding){ + } else if (naiveEncoding == BINARYINDEX && !graphEncoding) { naiveEncoding = ONEHOT; graphEncoding = true; - }else { + } else { naiveEncoding = (ElementEncodingType)((int)naiveEncoding + 1); } SetIteratorTunableSetting *iter = settings.iterator(); uint count = 0; - while(iter->hasNext()){ - TunableSetting * setting = iter->next(); - if (setting->param == NAIVEENCODER){ + while (iter->hasNext()) { + TunableSetting *setting = iter->next(); + if (setting->param == NAIVEENCODER) { setting->selectedValue = naiveEncoding; count++; - } else if(setting->param == ENCODINGGRAPHOPT){ + } else if (setting->param == ENCODINGGRAPHOPT) { setting->selectedValue = graphEncoding; count++; } diff --git a/src/Tuner/staticsearchtuner.h b/src/Tuner/staticsearchtuner.h index 407037b..7d7d78d 100644 --- a/src/Tuner/staticsearchtuner.h +++ b/src/Tuner/staticsearchtuner.h @@ -1,18 +1,19 @@ #ifndef STATICSEARCHTUNER_H #define STATICSEARCHTUNER_H #include "searchtuner.h" +#define TUNEFILE "tune.conf" class StaticSearchTuner : public SearchTuner { public: StaticSearchTuner(); ~StaticSearchTuner(); - int nextStaticTuner(); + int nextStaticTuner(); StaticSearchTuner *copyUsed(); - + CMEMALLOC; private: - bool graphEncoding; - ElementEncodingType naiveEncoding; + bool graphEncoding; + ElementEncodingType naiveEncoding; }; #endif diff --git a/src/Tuner/tunable.cc b/src/Tuner/tunable.cc index 115e04e..899bab0 100644 --- a/src/Tuner/tunable.cc +++ b/src/Tuner/tunable.cc @@ -15,41 +15,41 @@ int DefaultTuner::getVarTunable(VarType vartype1, VarType vartype2, TunableParam return descriptor->defaultValue; } -const char* tunableParameterToString(Tunables tunable){ - switch(tunable){ - case DECOMPOSEORDER: - return "DECOMPOSEORDER"; - case MUSTREACHGLOBAL: - return "MUSTREACHGLOBAL"; - case MUSTREACHLOCAL: - return "MUSTREACHLOCAL"; - case MUSTREACHPRUNE: - return "MUSTREACHPRUNE"; - case OPTIMIZEORDERSTRUCTURE: - return "OPTIMIZEORDERSTRUCTURE"; - case ORDERINTEGERENCODING: - return "ORDERINTEGERENCODING"; - case PREPROCESS: - return "PREPROCESS"; - case NODEENCODING: - return "NODEENCODING"; - case EDGEENCODING: - return "EDGEENCODING"; - case MUSTEDGEPRUNE: - return "MUSTEDGEPRUNE"; - case ELEMENTOPT: - return "ELEMENTOPT"; - case ELEMENTOPTSETS: - return "ELEMENTOPTSETS"; - case PROXYVARIABLE: - return "PROXYVARIABLE"; - case ENCODINGGRAPHOPT: - return "ENCODINGGRAPHOPT"; - case NAIVEENCODER: - return "NAIVEENCODER"; - case MUSTVALUE: - return "MUSTVALUE"; - default: - ASSERT(0); - } +const char *tunableParameterToString(Tunables tunable) { + switch (tunable) { + case DECOMPOSEORDER: + return "DECOMPOSEORDER"; + case MUSTREACHGLOBAL: + return "MUSTREACHGLOBAL"; + case MUSTREACHLOCAL: + return "MUSTREACHLOCAL"; + case MUSTREACHPRUNE: + return "MUSTREACHPRUNE"; + case OPTIMIZEORDERSTRUCTURE: + return "OPTIMIZEORDERSTRUCTURE"; + case ORDERINTEGERENCODING: + return "ORDERINTEGERENCODING"; + case PREPROCESS: + return "PREPROCESS"; + case NODEENCODING: + return "NODEENCODING"; + case EDGEENCODING: + return "EDGEENCODING"; + case MUSTEDGEPRUNE: + return "MUSTEDGEPRUNE"; + case ELEMENTOPT: + return "ELEMENTOPT"; + case ELEMENTOPTSETS: + return "ELEMENTOPTSETS"; + case PROXYVARIABLE: + return "PROXYVARIABLE"; + case ENCODINGGRAPHOPT: + return "ENCODINGGRAPHOPT"; + case NAIVEENCODER: + return "NAIVEENCODER"; + case MUSTVALUE: + return "MUSTVALUE"; + default: + ASSERT(0); + } } diff --git a/src/Tuner/tunable.h b/src/Tuner/tunable.h index c2a70b0..da3d44a 100644 --- a/src/Tuner/tunable.h +++ b/src/Tuner/tunable.h @@ -43,8 +43,8 @@ static TunableDesc mustValueBinaryIndex(5, 9, 8); static TunableDesc NodeEncodingDesc(ELEM_UNASSIGNED, BINARYINDEX, ELEM_UNASSIGNED); static TunableDesc NaiveEncodingDesc(ONEHOT, BINARYINDEX, ONEHOT); -enum Tunables {DECOMPOSEORDER, MUSTREACHGLOBAL, MUSTREACHLOCAL, MUSTREACHPRUNE, OPTIMIZEORDERSTRUCTURE, ORDERINTEGERENCODING, PREPROCESS, NODEENCODING, EDGEENCODING, MUSTEDGEPRUNE, ELEMENTOPT, - ENCODINGGRAPHOPT, ELEMENTOPTSETS, PROXYVARIABLE, MUSTVALUE, NAIVEENCODER}; +enum Tunables {DECOMPOSEORDER, MUSTREACHGLOBAL, MUSTREACHLOCAL, MUSTREACHPRUNE, OPTIMIZEORDERSTRUCTURE, ORDERINTEGERENCODING, PREPROCESS, NODEENCODING, EDGEENCODING, MUSTEDGEPRUNE, ELEMENTOPT, + ENCODINGGRAPHOPT, ELEMENTOPTSETS, PROXYVARIABLE, MUSTVALUE, NAIVEENCODER}; typedef enum Tunables Tunables; const char *tunableParameterToString(Tunables tunable); -- 2.34.1