From ec4122e6d43e951feb8b344bf3511a50e08a3615 Mon Sep 17 00:00:00 2001 From: Hamed Gorjiara Date: Wed, 19 Dec 2018 15:19:08 -0800 Subject: [PATCH] Changing the design by adding basic tuner --- src/Test/runcomptuner.cc | 2 +- src/Tuner/basictuner.cc | 224 +++++++++++++++++++++++++++++++++ src/Tuner/basictuner.h | 99 +++++++++++++++ src/Tuner/multituner.cc | 259 ++++----------------------------------- src/Tuner/multituner.h | 58 +-------- src/Tuner/randomtuner.cc | 169 ++----------------------- src/Tuner/randomtuner.h | 29 +---- 7 files changed, 365 insertions(+), 475 deletions(-) create mode 100644 src/Tuner/basictuner.cc create mode 100644 src/Tuner/basictuner.h diff --git a/src/Test/runcomptuner.cc b/src/Test/runcomptuner.cc index f625e62..de751d1 100644 --- a/src/Test/runcomptuner.cc +++ b/src/Test/runcomptuner.cc @@ -31,7 +31,7 @@ int main(int argc, char **argv) { exit(-1); } - multituner->tuneComp(); + multituner->tune(); delete multituner; return 0; } diff --git a/src/Tuner/basictuner.cc b/src/Tuner/basictuner.cc new file mode 100644 index 0000000..23e4d38 --- /dev/null +++ b/src/Tuner/basictuner.cc @@ -0,0 +1,224 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: basictuner.cc + * Author: hamed + * + * Created on December 17, 2018, 2:02 PM + */ + +#include "basictuner.h" +#include "common.h" +#include "csolver.h" +#include "searchtuner.h" +#include +#include +#include +#include + +Problem::Problem(const char *_problem) : + problemnumber(-1), + result(TUNERUNSETVALUE), + besttime(LLONG_MAX) +{ + uint len = strlen(_problem); + problem = (char *) ourmalloc(len + 1); + memcpy(problem, _problem, len + 1); +} + +Problem::~Problem() { + ourfree(problem); +} + +void TunerRecord::setTime(Problem *problem, long long time) { + timetaken.put(problem, time); +} + +void TunerRecord::print(){ + model_print("*************TUNER NUMBER=%d***********\n", tunernumber); + tuner->print(); + model_print("&&&&&&&&&&&&&USED SETTINGS &&&&&&&&&&&&\n"); + tuner->printUsed(); + model_print("\n"); +} + +void TunerRecord::printProblemsInfo(){ + for (uint j = 0; j < problems.getSize(); j++) { + Problem *problem = problems.get(j); + model_print("Problem %s\n", problem->getProblem()); + model_print("Time = %lld\n", getTime(problem)); + } +} + +long long TunerRecord::getTime(Problem *problem) { + if (timetaken.contains(problem)) + return timetaken.get(problem); + else return -1; +} + +TunerRecord *TunerRecord::changeTuner(SearchTuner *_newtuner) { + TunerRecord *tr = new TunerRecord(_newtuner); + for (uint i = 0; i < problems.getSize(); i++) { + tr->problems.push(problems.get(i)); + } + return tr; +} + + +BasicTuner::BasicTuner(uint _budget, uint _timeout) : + budget(_budget), timeout(_timeout), execnum(0){ +} + +BasicTuner::~BasicTuner() { + for (uint i = 0; i < problems.getSize(); i++) + ourfree(problems.get(i)); + for (uint i = 0; i < allTuners.getSize(); i++) + delete allTuners.get(i); +} + +void BasicTuner::addProblem(const char *filename) { + Problem *p = new Problem(filename); + p->setProblemNumber(problems.getSize()); + problems.push(p); +} + +void BasicTuner::printData() { + model_print("*********** DATA DUMP ***********\n"); + for (uint i = 0; i < allTuners.getSize(); i++) { + TunerRecord *tuner = allTuners.get(i); + SearchTuner *stun = tuner->getTuner(); + model_print("Tuner %u\n", i); + stun->print(); + model_print("----------------------------------\n\n\n"); + for (uint j = 0; j < tuner->problemsSize(); j++) { + Problem *problem = tuner->getProblem(j); + model_print("Problem %s\n", problem->getProblem()); + model_print("Time = %lld\n", tuner->getTime(problem)); + } + } +} + +bool BasicTuner::tunerExists(SearchTuner *tuner){ + for(uint i=0; i< explored.getSize(); i++){ + if(explored.get(i)->getTuner()->equalUsed(tuner)) + return true; + } + return false; +} + +void BasicTuner::addTuner(SearchTuner *tuner) { + TunerRecord *t = new TunerRecord(tuner); + tuners.push(t); + t->setTunerNumber( allTuners.getSize() ); + allTuners.push(t); +} + +long long BasicTuner::evaluate(Problem *problem, TunerRecord *tuner) { + char buffer[512]; + { + snprintf(buffer, sizeof(buffer), "problem%u", execnum); + + ofstream myfile; + myfile.open (buffer, ios::out); + + + if (myfile.is_open()) { + myfile << problem->getProblem() << endl; + myfile << problem->getProblemNumber() << endl; + myfile.close(); + } + } + + { + snprintf(buffer, sizeof(buffer), "tunernum%u", execnum); + + ofstream myfile; + myfile.open (buffer, ios::out); + + + if (myfile.is_open()) { + myfile << tuner->getTunerNumber() << endl; + myfile.close(); + } + } + + //Write out the tuner + snprintf(buffer, sizeof(buffer), "tuner%u", execnum); + tuner->getTuner()->serialize(buffer); + + //compute timeout + uint timeinsecs = problem->getBestTime() / NANOSEC; + uint adaptive = (timeinsecs > 30) ? timeinsecs * 5 : 150; + uint maxtime = (adaptive < timeout) ? adaptive : timeout; + + //Do run + snprintf(buffer, sizeof(buffer), "./run.sh deserializerun %s %u tuner%u result%u > log%u", problem->getProblem(), maxtime, execnum, execnum, 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%u", execnum); + + ifstream myfile; + myfile.open (buffer, ios::in); + + + if (myfile.is_open()) { + myfile >> metric; + myfile >> sat; + myfile.close(); + } + updateTimeout(problem, metric); + snprintf(buffer, sizeof(buffer), "tuner%uused", execnum); + tuner->getTuner()->addUsed(buffer); + } + //Increment execution count + execnum++; + + if (problem->getResult() == TUNERUNSETVALUE && sat != IS_INDETER) { + problem->setResult( sat ); + } else if (problem->getResult() != sat && sat != IS_INDETER) { + model_print("******** Result has changed ********\n"); + } + if (sat == IS_INDETER && metric != -1) {//The case when we have a timeout + metric = -1; + } + return metric; +} + +SearchTuner *BasicTuner::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; +} + +bool BasicTuner::subTunerExist(SearchTuner *newTuner){ + for (uint i=0; i< explored.getSize(); i++){ + SearchTuner *tuner = explored.get(i)->getTuner(); + if(tuner->isSubTunerof(newTuner)){ + return true; + } + } + return false; +} + + +void BasicTuner::updateTimeout(Problem *problem, long long metric) { + if (metric < problem->getBestTime()) { + problem->setBestTime( metric ); + } +} \ No newline at end of file diff --git a/src/Tuner/basictuner.h b/src/Tuner/basictuner.h new file mode 100644 index 0000000..83d1196 --- /dev/null +++ b/src/Tuner/basictuner.h @@ -0,0 +1,99 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: basictuner.h + * Author: hamed + * + * Created on December 17, 2018, 2:02 PM + */ + +#ifndef BASICTUNER_H +#define BASICTUNER_H +#include "mymemory.h" +#include "classlist.h" +#include "cppvector.h" +#include "hashtable.h" + +#define TUNERUNSETVALUE -1 +#define AUTOTUNERFACTOR 0.3 + +class Problem { +public: + Problem(const char *problem); + char *getProblem() {return problem;} + inline int getResult(){return result;} + inline int getProblemNumber(){return problemnumber;} + inline void setResult(int res){result = res;} + inline void setProblemNumber(int probNum){problemnumber = probNum;} + inline long long getBestTime() {return besttime ;} + inline void setBestTime(long long time) {besttime = time;} + ~Problem(); + CMEMALLOC; +private: + int problemnumber; + int result; + char *problem; + long long besttime; +}; + +class TunerRecord { +public: + TunerRecord(SearchTuner *_tuner) : tuner(_tuner), tunernumber(-1) {} + TunerRecord(SearchTuner *_tuner, int _tunernumber) : tuner(_tuner), tunernumber(_tunernumber) {} + SearchTuner *getTuner() {return tuner;} + void inline addProblem(Problem * problem){problems.push(problem);} + TunerRecord *changeTuner(SearchTuner *_newtuner); + void updateTuner(SearchTuner *_newtuner) {tuner = _newtuner;} + long long getTime(Problem *problem); + void setTime(Problem *problem, long long time); + inline void setTunerNumber(int numb){tunernumber = numb;} + inline int getTunerNumber(){return tunernumber;} + inline uint problemsSize() {return problems.getSize();} + inline Problem *getProblem(uint index){return problems.get(index);} + void print(); + void printProblemsInfo(); + CMEMALLOC; +private: + SearchTuner *tuner; + Vector problems; + Hashtable timetaken; + int tunernumber; + friend void clearVector(Vector *tunerV); +}; + +class BasicTuner { +public: + BasicTuner(uint _budget, uint _timeout); + void addProblem(const char *filename); + void addTuner(SearchTuner *tuner); + void printData(); + virtual ~BasicTuner(); + virtual void tune() = 0; + CMEMALLOC; +protected: + long long evaluate(Problem *problem, TunerRecord *tuner); + /** + * returns the index of the tuner which is subtune of + * the newTuner + * @param newTuner + * @return + */ + bool subTunerExist(SearchTuner *newTuner); + bool tunerExists(SearchTuner *tunerRec); + SearchTuner *mutateTuner(SearchTuner *oldTuner, uint k); + void updateTimeout(Problem *problem, long long metric); + Vector allTuners; + Vector explored; + Vector problems; + Vector tuners; + uint budget; + uint timeout; + int execnum; +}; + +#endif /* BASICTUNER_H */ + diff --git a/src/Tuner/multituner.cc b/src/Tuner/multituner.cc index c69891f..743d4cb 100644 --- a/src/Tuner/multituner.cc +++ b/src/Tuner/multituner.cc @@ -1,87 +1,15 @@ #include "multituner.h" -#include "csolver.h" -#include "searchtuner.h" -#include -#include #include -#include +#include +#include "searchtuner.h" #include #include -#include - -#define UNSETVALUE -1 - -Problem::Problem(const char *_problem) : - problemnumber(-1), - result(UNSETVALUE), - besttime(LLONG_MAX) -{ - uint len = strlen(_problem); - problem = (char *) ourmalloc(len + 1); - memcpy(problem, _problem, len + 1); -} - -Problem::~Problem() { - ourfree(problem); -} - -void TunerRecord::setTime(Problem *problem, long long time) { - timetaken.put(problem, time); -} - -void TunerRecord::print(){ - model_print("*************TUNER NUMBER=%d***********\n", tunernumber); - tuner->print(); - model_print("&&&&&&&&&&&&&USED SETTINGS &&&&&&&&&&&&\n"); - tuner->printUsed(); - model_print("\n"); -} - -long long TunerRecord::getTime(Problem *problem) { - if (timetaken.contains(problem)) - return timetaken.get(problem); - else return -1; -} - -TunerRecord *TunerRecord::changeTuner(SearchTuner *_newtuner) { - TunerRecord *tr = new TunerRecord(_newtuner); - for (uint i = 0; i < problems.getSize(); i++) { - tr->problems.push(problems.get(i)); - } - return tr; -} +#include "solver_interface.h" MultiTuner::MultiTuner(uint _budget, uint _rounds, uint _timeout) : - budget(_budget), rounds(_rounds), timeout(_timeout), execnum(0) { -} - -MultiTuner::~MultiTuner() { - for (uint i = 0; i < problems.getSize(); i++) - ourfree(problems.get(i)); - for (uint i = 0; i < allTuners.getSize(); i++) - delete allTuners.get(i); -} - -void MultiTuner::addProblem(const char *filename) { - Problem *p = new Problem(filename); - p->problemnumber = problems.getSize(); - problems.push(p); -} - -void MultiTuner::printData() { - model_print("*********** DATA DUMP ***********\n"); - for (uint i = 0; i < allTuners.getSize(); i++) { - TunerRecord *tuner = allTuners.get(i); - SearchTuner *stun = tuner->getTuner(); - model_print("Tuner %u\n", i); - stun->print(); - model_print("----------------------------------\n\n\n"); - for (uint j = 0; j < tuner->problems.getSize(); j++) { - Problem *problem = tuner->problems.get(j); - model_print("Problem %s\n", problem->getProblem()); - model_print("Time = %lld\n", tuner->getTime(problem)); - } - } + BasicTuner(_budget, _timeout), + rounds(_rounds) +{ } void MultiTuner::findBestThreeTuners() { @@ -122,34 +50,13 @@ void MultiTuner::findBestThreeTuners() { char buffer[512]; snprintf(buffer, sizeof(buffer), "best%u.tuner", i); stun->serialize(buffer); - model_print("Tuner %u\n", tuner->tunernumber); + model_print("Tuner %u\n", tuner->getTunerNumber()); stun->print(); - for (uint j = 0; j < tuner->problems.getSize(); j++) { - Problem *problem = tuner->problems.get(j); - model_print("Problem %s\n", problem->getProblem()); - model_print("Time = %lld\n", tuner->getTime(problem)); - } + tuner->printProblemsInfo(); model_print("----------------------------------\n\n\n"); } } -bool MultiTuner::finishTunerExist(TunerRecord *tunerRec){ - SearchTuner *tuner = tunerRec->getTuner(); - for(uint i=0; i< explored.getSize(); i++){ - if(explored.get(i)->getTuner()->equalUsed(tuner)) - return true; - } - return false; -} - -void MultiTuner::addTuner(SearchTuner *tuner) { - TunerRecord *t = new TunerRecord(tuner); - tuners.push(t); - t->tunernumber = allTuners.getSize(); - allTuners.push(t); -} - - void MultiTuner::readData(uint numRuns) { for (uint i = 0; i < numRuns; i++) { ifstream myfile; @@ -195,15 +102,15 @@ void MultiTuner::readData(uint numRuns) { myfile >> sat; myfile.close(); } - if (problem->result == UNSETVALUE && sat != IS_INDETER) { - problem->result = sat; - } else if (problem->result != sat && sat != IS_INDETER) { + if (problem->getResult() == TUNERUNSETVALUE && sat != IS_INDETER) { + problem->setResult(sat); + } else if (problem->getResult() != sat && sat != IS_INDETER) { model_print("******** Result has changed ********\n"); } if (metric != -1) { if (tuner->getTime(problem) == -1) - tuner->problems.push(problem); + tuner->addProblem(problem); tuner->setTime(problem, metric); } @@ -211,92 +118,7 @@ void MultiTuner::readData(uint numRuns) { } -long long MultiTuner::evaluate(Problem *problem, TunerRecord *tuner) { - char buffer[512]; - { - snprintf(buffer, sizeof(buffer), "problem%u", execnum); - - ofstream myfile; - myfile.open (buffer, ios::out); - - - if (myfile.is_open()) { - myfile << problem->getProblem() << endl; - myfile << problem->problemnumber << endl; - myfile.close(); - } - } - - { - snprintf(buffer, sizeof(buffer), "tunernum%u", execnum); - - ofstream myfile; - myfile.open (buffer, ios::out); - - - if (myfile.is_open()) { - myfile << tuner->tunernumber << endl; - myfile.close(); - } - } - - //Write out the tuner - snprintf(buffer, sizeof(buffer), "tuner%u", execnum); - tuner->getTuner()->serialize(buffer); - - //compute timeout - uint timeinsecs = problem->besttime / NANOSEC; - uint adaptive = (timeinsecs > 30) ? timeinsecs * 5 : 150; - uint maxtime = (adaptive < timeout) ? adaptive : timeout; - - //Do run - snprintf(buffer, sizeof(buffer), "./run.sh deserializerun %s %u tuner%u result%u > log%u", problem->getProblem(), maxtime, execnum, execnum, 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%u", execnum); - - ifstream myfile; - myfile.open (buffer, ios::in); - - - if (myfile.is_open()) { - myfile >> metric; - myfile >> sat; - myfile.close(); - } - updateTimeout(problem, metric); - snprintf(buffer, sizeof(buffer), "tuner%uused", execnum); - tuner->getTuner()->addUsed(buffer); - if(!finishTunerExist(tuner)){ - explored.push(tuner); - } - } - //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"); - } - if (sat == IS_INDETER && metric != -1) {//The case when we have a timeout - metric = -1; - } - return metric; -} - -void MultiTuner::updateTimeout(Problem *problem, long long metric) { - if (metric < problem->besttime) { - problem->besttime = metric; - } -} - -void MultiTuner::tuneComp() { +void MultiTuner::tune() { Vector *tunerV = new Vector(&tuners); for (uint b = 0; b < budget; b++) { model_print("Round %u of %u\n", b, budget); @@ -304,8 +126,8 @@ void MultiTuner::tuneComp() { for (uint i = 0; i < tSize; i++) { SearchTuner *tmpTuner = mutateTuner(tunerV->get(i)->getTuner(), b); TunerRecord *tmp = new TunerRecord(tmpTuner); - tmp->tunernumber = allTuners.getSize(); - model_print("Mutated tuner %u to generate tuner %u\n", tunerV->get(i)->tunernumber, tmp->tunernumber); + tmp->setTunerNumber(allTuners.getSize()); + model_print("Mutated tuner %u to generate tuner %u\n", tunerV->get(i)->getTunerNumber(), tmp->getTunerNumber()); allTuners.push(tmp); tunerV->push(tmp); } @@ -320,9 +142,9 @@ void MultiTuner::tuneComp() { if (metric == -1) { metric = evaluate(problem, tuner); if (tuner->getTime(problem) == -1) { - tuner->problems.push(problem); + tuner->addProblem(problem); } - model_print("%u.Problem<%s>\tTuner<%p, %d>\tMetric<%lld>\n", i, problem->problem,tuner, tuner->tunernumber, metric); + model_print("%u.Problem<%s>\tTuner<%p, %d>\tMetric<%lld>\n", i, problem->getProblem(),tuner, tuner->getTunerNumber(), metric); model_print("*****************************\n"); if (metric != -1) tuner->setTime(problem, metric); @@ -335,7 +157,7 @@ void MultiTuner::tuneComp() { if (metric < places.get(k)->getTime(problem)) break; } - model_print("place[%u]=Tuner<%p,%d>\n", k, tuner, tuner->tunernumber); + model_print("place[%u]=Tuner<%p,%d>\n", k, tuner, tuner->getTunerNumber()); places.insertAt(k, tuner); } } @@ -346,7 +168,7 @@ void MultiTuner::tuneComp() { if (scores.contains(tuner)) currScore = scores.get(tuner); currScore += points; - model_print("Problem<%s>\tTuner<%p,%d>\tmetric<%d>\n", problem->problem, tuner, tuner->tunernumber, currScore); + model_print("Problem<%s>\tTuner<%p,%d>\tmetric<%d>\n", problem->getProblem(), tuner, tuner->getTunerNumber(), currScore); model_print("**************************\n"); scores.put(tuner, currScore); points = points / 3; @@ -367,14 +189,14 @@ void MultiTuner::tuneComp() { if (score > tscore) break; } - model_print("ranking[%u]=tuner<%p,%u>(Score=%d)\n", j, tuner, tuner->tunernumber, score); + model_print("ranking[%u]=tuner<%p,%u>(Score=%d)\n", j, tuner, tuner->getTunerNumber(), score); model_print("************************\n"); ranking.insertAt(j, tuner); } model_print("tunerSize=%u\trankingSize=%u\ttunerVSize=%u\n", tuners.getSize(), ranking.getSize(), tunerV->getSize()); for (uint i = tuners.getSize(); i < ranking.getSize(); i++) { TunerRecord *tuner = ranking.get(i); - model_print("Removing tuner %u\n", tuner->tunernumber); + model_print("Removing tuner %u\n", tuner->getTunerNumber()); for (uint j = 0; j < tunerV->getSize(); j++) { if (tunerV->get(j) == tuner) tunerV->removeAt(j); @@ -406,7 +228,7 @@ void MultiTuner::mapProblemsToTuners(Vector *tunerV) { } } if (bestTuner != NULL) - bestTuner->problems.push(problem); + bestTuner->addProblem(problem); } } @@ -445,8 +267,8 @@ void MultiTuner::improveTuners(Vector *tunerV) { double MultiTuner::evaluateAll(TunerRecord *tuner) { double product = 1; - for (uint i = 0; i < tuner->problems.getSize(); i++) { - Problem *problem = tuner->problems.get(i); + for (uint i = 0; i < tuner->problemsSize(); i++) { + Problem *problem = tuner->getProblem(i); long long metric = tuner->getTime(problem); if (metric == -1) { metric = evaluate(problem, tuner); @@ -461,34 +283,7 @@ double MultiTuner::evaluateAll(TunerRecord *tuner) { score = timeout; product *= score; } - return pow(product, 1 / ((double)tuner->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(); - if(hasExplored(newTuner)){ - model_print("Note:A repetitive tuner has found\n"); - settingsToMutate++; - } - } - return newTuner; -} - -bool MultiTuner::hasExplored(SearchTuner *newTuner){ - for (uint i=0; i< explored.getSize(); i++){ - SearchTuner *tuner = explored.get(i)->getTuner(); - if(tuner->isSubTunerof(newTuner)){ - return true; - } - } - return false; + return pow(product, 1 / ((double)tuner->problemsSize())); } TunerRecord *MultiTuner::tune(TunerRecord *tuner) { @@ -502,10 +297,10 @@ TunerRecord *MultiTuner::tune(TunerRecord *tuner) { for (uint i = 0; i < budget; i++) { SearchTuner *tmpTuner = mutateTuner(oldTuner->getTuner(), i); TunerRecord *newTuner = oldTuner->changeTuner(tmpTuner); - newTuner->tunernumber = allTuners.getSize(); + newTuner->setTunerNumber( allTuners.getSize() ); allTuners.push(newTuner); double newScore = evaluateAll(newTuner); - newTuner->tuner->printUsed(); + newTuner->getTuner()->printUsed(); model_print("Received score %f\n", newScore); double scoreDiff = newScore - oldScore; //smaller is better if (newScore < bestScore) { diff --git a/src/Tuner/multituner.h b/src/Tuner/multituner.h index aaed013..cf42d9f 100644 --- a/src/Tuner/multituner.h +++ b/src/Tuner/multituner.h @@ -2,74 +2,22 @@ #define MULTITUNER_H #include "classlist.h" #include "structs.h" +#include "basictuner.h" -#define AUTOTUNERFACTOR 0.3 -class Problem { -public: - Problem(const char *problem); - char *getProblem() {return problem;} - ~Problem(); - CMEMALLOC; -private: - int problemnumber; - int result; - char *problem; - long long besttime; - friend class MultiTuner; - friend class RandomTuner; -}; - -class TunerRecord { -public: - TunerRecord(SearchTuner *_tuner) : tuner(_tuner), tunernumber(-1) {} - TunerRecord(SearchTuner *_tuner, int _tunernumber) : tuner(_tuner), tunernumber(_tunernumber) {} - SearchTuner *getTuner() {return tuner;} - TunerRecord *changeTuner(SearchTuner *_newtuner); - void updateTuner(SearchTuner *_newtuner) {tuner = _newtuner;} - long long getTime(Problem *problem); - void setTime(Problem *problem, long long time); - void print(); -private: - SearchTuner *tuner; - Vector problems; - Hashtable timetaken; - int tunernumber; - friend class MultiTuner; - friend class RandomTuner; - friend void clearVector(Vector *tunerV); -}; - -class MultiTuner { +class MultiTuner : public BasicTuner { public: MultiTuner(uint budget, uint rounds, uint timeout); - ~MultiTuner(); - void addProblem(const char *filename); - void addTuner(SearchTuner *tuner); void readData(uint numRuns); - void updateTimeout(Problem *problem, long long metric); void tuneK(); - bool finishTunerExist(TunerRecord *tuner); - void tuneComp(); - void printData(); + void tune(); void findBestThreeTuners(); - CMEMALLOC; protected: - long long evaluate(Problem *problem, TunerRecord *tuner); double evaluateAll(TunerRecord *tuner); - SearchTuner *mutateTuner(SearchTuner *oldTuner, uint k); - bool hasExplored(SearchTuner *newTuner); void mapProblemsToTuners(Vector *tunerV); void improveTuners(Vector *tunerV); TunerRecord *tune(TunerRecord *tuner); - Vector allTuners; - Vector explored; - Vector problems; - Vector tuners; - uint budget; uint rounds; - uint timeout; - int execnum; }; inline long long min(long long num1, long long num2, long long num3) { diff --git a/src/Tuner/randomtuner.cc b/src/Tuner/randomtuner.cc index 3156190..1c1a0f3 100644 --- a/src/Tuner/randomtuner.cc +++ b/src/Tuner/randomtuner.cc @@ -4,142 +4,12 @@ #include "multituner.h" #include #include -#include -#include -#include -#include #include #define UNSETVALUE -1 -RandomTuner::RandomTuner(uint _budget, uint _timeout) : - budget(_budget), timeout(_timeout), execnum(0) { -} - -RandomTuner::~RandomTuner() { - for (uint i = 0; i < problems.getSize(); i++) - ourfree(problems.get(i)); - for (uint i = 0; i < allTuners.getSize(); i++) - delete allTuners.get(i); -} - -void RandomTuner::addProblem(const char *filename) { - Problem *p = new Problem(filename); - p->problemnumber = problems.getSize(); - problems.push(p); -} - -void RandomTuner::printData() { - model_print("*********** DATA DUMP ***********\n"); - for (uint i = 0; i < allTuners.getSize(); i++) { - TunerRecord *tuner = allTuners.get(i); - SearchTuner *stun = tuner->getTuner(); - model_print("Tuner %u\n", i); - stun->print(); - model_print("----------------------------------\n\n\n"); - for (uint j = 0; j < tuner->problems.getSize(); j++) { - Problem *problem = tuner->problems.get(j); - model_print("Problem %s\n", problem->getProblem()); - model_print("Time = %lld\n", tuner->getTime(problem)); - } - } -} - -bool RandomTuner::tunerExists(SearchTuner *tuner){ - for(uint i=0; i< explored.getSize(); i++){ - if(explored.get(i)->getTuner()->equalUsed(tuner)) - return true; - } - return false; -} - -void RandomTuner::addTuner(SearchTuner *tuner) { - TunerRecord *t = new TunerRecord(tuner); - tuners.push(t); - t->tunernumber = allTuners.getSize(); - allTuners.push(t); -} - -long long RandomTuner::evaluate(Problem *problem, TunerRecord *tuner) { - char buffer[512]; - { - snprintf(buffer, sizeof(buffer), "problem%u", execnum); - - ofstream myfile; - myfile.open (buffer, ios::out); - - - if (myfile.is_open()) { - myfile << problem->getProblem() << endl; - myfile << problem->problemnumber << endl; - myfile.close(); - } - } - - { - snprintf(buffer, sizeof(buffer), "tunernum%u", execnum); - - ofstream myfile; - myfile.open (buffer, ios::out); - - - if (myfile.is_open()) { - myfile << tuner->tunernumber << endl; - myfile.close(); - } - } - - //Write out the tuner - snprintf(buffer, sizeof(buffer), "tuner%u", execnum); - tuner->getTuner()->serialize(buffer); - - //compute timeout - uint timeinsecs = problem->besttime / NANOSEC; - uint adaptive = (timeinsecs > 30) ? timeinsecs * 5 : 150; - uint maxtime = (adaptive < timeout) ? adaptive : timeout; - - //Do run - snprintf(buffer, sizeof(buffer), "./run.sh deserializerun %s %u tuner%u result%u > log%u", problem->getProblem(), maxtime, execnum, execnum, 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%u", execnum); - - ifstream myfile; - myfile.open (buffer, ios::in); - - - if (myfile.is_open()) { - myfile >> metric; - myfile >> sat; - myfile.close(); - } - updateTimeout(problem, metric); - snprintf(buffer, sizeof(buffer), "tuner%uused", execnum); - tuner->getTuner()->addUsed(buffer); - } - //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"); - } - if (sat == IS_INDETER && metric != -1) {//The case when we have a timeout - metric = -1; - } - return metric; -} - -void RandomTuner::updateTimeout(Problem *problem, long long metric) { - if (metric < problem->besttime) { - problem->besttime = metric; - } +RandomTuner::RandomTuner(uint _budget, uint _timeout) : + BasicTuner(_budget, _timeout) { } void RandomTuner::tune() { @@ -154,14 +24,14 @@ void RandomTuner::tune() { if(metric == -1){ metric = evaluate(problem, tuner); ASSERT(tuner->getTime(problem) == -1); - tuner->problems.push(problem); - model_print("%u.Problem<%s>\tTuner<%p, %d>\tMetric<%lld>\n", i, problem->problem,tuner, tuner->tunernumber, metric); + tuner->addProblem(problem); + model_print("%u.Problem<%s>\tTuner<%p, %d>\tMetric<%lld>\n", i, problem->getProblem(),tuner, tuner->getTunerNumber(), metric); if (metric != -1) tuner->setTime(problem, metric); else tuner->setTime(problem, -2); if(tunerExists(tuner->getTuner())){ - //Solving the first problem and noticing the tuner + //Solving the problem and noticing the tuner //already exists isNew = false; break; @@ -176,12 +46,12 @@ void RandomTuner::tune() { uint tSize = tuners.getSize(); for (uint i = 0; i < tSize; i++) { SearchTuner *tmpTuner = mutateTuner(tuners.get(i)->getTuner(), budget); - while(subtuneIndex(tmpTuner) != -1){ + while(subTunerExist(tmpTuner)){ tmpTuner->randomMutate(); } TunerRecord *tmp = new TunerRecord(tmpTuner); - tmp->tunernumber = allTuners.getSize(); - model_print("Mutated tuner %u to generate tuner %u\n", tuners.get(i)->tunernumber, tmp->tunernumber); + tmp->setTunerNumber(allTuners.getSize()); + model_print("Mutated tuner %u to generate tuner %u\n", tuners.get(i)->getTunerNumber(), tmp->getTunerNumber()); allTuners.push(tmp); tuners.set(i, tmp); } @@ -189,26 +59,3 @@ void RandomTuner::tune() { printData(); } - -SearchTuner *RandomTuner::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; -} - -int RandomTuner::subtuneIndex(SearchTuner *newTuner){ - for (uint i=0; i< explored.getSize(); i++){ - SearchTuner *tuner = explored.get(i)->getTuner(); - if(tuner->isSubTunerof(newTuner)){ - return i; - } - } - return -1; -} diff --git a/src/Tuner/randomtuner.h b/src/Tuner/randomtuner.h index 36f8531..bc063f0 100644 --- a/src/Tuner/randomtuner.h +++ b/src/Tuner/randomtuner.h @@ -3,41 +3,18 @@ #include "classlist.h" #include "structs.h" #include "multituner.h" +#include "basictuner.h" /** * This is a Tuner which is being used for */ -class RandomTuner { +class RandomTuner : public BasicTuner { public: RandomTuner(uint _budget, uint _timeout); - ~RandomTuner(); - void addProblem(const char *filename); - void addTuner(SearchTuner *tuner); void tune(); - void printData(); - CMEMALLOC; protected: - long long evaluate(Problem *problem, TunerRecord *tuner); - SearchTuner *mutateTuner(SearchTuner *oldTuner, uint k); - void updateTimeout(Problem *problem, long long metric); - bool randomMutation(SearchTuner *tuner); - bool tunerExists(SearchTuner *tunerRec); - /** - * returns the index of the tuner which is subtune of - * the newTuner - * @param newTuner - * @return - */ - int subtuneIndex(SearchTuner *newTuner); - + bool randomMutation(SearchTuner *tuner); TunerRecord *tune(SearchTuner *tuner); - Vector allTuners; - Vector explored; - Vector problems; - Vector tuners; - uint budget; - uint timeout; - int execnum; }; #endif -- 2.34.1