From: Hamed Gorjiara Date: Wed, 12 Dec 2018 22:13:03 +0000 (-0800) Subject: Random Tuner X-Git-Url: http://plrg.eecs.uci.edu/git/?p=satune.git;a=commitdiff_plain;h=5461c28369dd5ec459300394a9f9ecd576c4a2ad Random Tuner --- diff --git a/src/Test/runrandomtuner.cc b/src/Test/runrandomtuner.cc new file mode 100644 index 0000000..429d07a --- /dev/null +++ b/src/Test/runrandomtuner.cc @@ -0,0 +1,35 @@ +#include "csolver.h" +#include "randomtuner.h" +#include "searchtuner.h" + +int main(int argc, char **argv) { + if (argc < 6) { + printf("You should specify %s rounds timeout problemfilenames - tunerfilenames", argv[0]); + exit(-1); + } + uint rounds; + uint timeout; + sscanf(argv[1], "%u", &rounds); + sscanf(argv[2], "%u", &timeout); + + RandomTuner *randomTuner = new RandomTuner(rounds, timeout); + bool tunerfiles = false; + for (int i = 3; i < argc; i++) { + if (!tunerfiles) { + if (argv[i][0] == '-' && argv[i][1] == 0) + tunerfiles = true; + else + randomTuner->addProblem(argv[i]); + } else + randomTuner->addTuner(new SearchTuner(argv[i])); + } + + if (!tunerfiles) { + printf("You should specify %s budget rounds timeout problemfilenames - tunerfilenames", argv[0]); + exit(-1); + } + + randomTuner->tune(); + delete randomTuner; + return 0; +} diff --git a/src/Tuner/multituner.h b/src/Tuner/multituner.h index e184540..aaed013 100644 --- a/src/Tuner/multituner.h +++ b/src/Tuner/multituner.h @@ -17,6 +17,7 @@ private: char *problem; long long besttime; friend class MultiTuner; + friend class RandomTuner; }; class TunerRecord { @@ -35,6 +36,7 @@ private: Hashtable timetaken; int tunernumber; friend class MultiTuner; + friend class RandomTuner; friend void clearVector(Vector *tunerV); }; diff --git a/src/Tuner/randomtuner.cc b/src/Tuner/randomtuner.cc new file mode 100644 index 0000000..67e53b8 --- /dev/null +++ b/src/Tuner/randomtuner.cc @@ -0,0 +1,210 @@ +#include "randomtuner.h" +#include "csolver.h" +#include "searchtuner.h" +#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; + } +} + +void RandomTuner::tune() { + for (uint r = 0; r < budget; r++) { + model_print("Round %u of %u\n", r, budget); + for (uint i = 0; i < tuners.getSize(); i++){ + TunerRecord *tuner = tuners.get(i); + for (uint j = 0; j < problems.getSize(); j++){ + Problem *problem = problems.get(j); + long long metric = tuner->getTime(problem); + 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); + if (metric != -1) + tuner->setTime(problem, metric); + else + tuner->setTime(problem, -2); + if(j == 0 && tunerExists(tuner->getTuner())){ + //Solving the first problem and noticing the tuner + //already exists + break; + } else if(j == 0 && !tunerExists(tuner->getTuner())){ + explored.push(tuner); + } + } + } + } + uint tSize = tuners.getSize(); + for (uint i = 0; i < tSize; i++) { + SearchTuner *tmpTuner = mutateTuner(tuners.get(i)->getTuner(), budget); + while(subtuneIndex(tmpTuner) != -1){ + 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); + allTuners.push(tmp); + tuners.set(i, tmp); + } + } + 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 new file mode 100644 index 0000000..36f8531 --- /dev/null +++ b/src/Tuner/randomtuner.h @@ -0,0 +1,43 @@ +#ifndef RANDOMTUNER_H +#define RANDOMTUNER_H +#include "classlist.h" +#include "structs.h" +#include "multituner.h" + +/** + * This is a Tuner which is being used for + */ +class RandomTuner { +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); + + TunerRecord *tune(SearchTuner *tuner); + Vector allTuners; + Vector explored; + Vector problems; + Vector tuners; + uint budget; + uint timeout; + int execnum; +}; + +#endif diff --git a/src/analyzer/tunerloganalyzer.py b/src/analyzer/tunerloganalyzer.py index d4e52cc..92a0912 100644 --- a/src/analyzer/tunerloganalyzer.py +++ b/src/analyzer/tunerloganalyzer.py @@ -130,14 +130,17 @@ def analyzeLogs(file): rows.append(row) return rows -def tunerNumberAnalysis(file, rows): +def tunerCountAnalysis(file, rows): global TUNABLEHEADER tunercount = {} tunernumber = {} for row in rows: mystr="" for i in range(18): - mystr+=row[TUNABLEHEADER[i]] + if not row[TUNABLEHEADER[i]]: + mystr += "." + else: + mystr+=row[TUNABLEHEADER[i]] if mystr not in tunercount: tunercount.update({mystr : 1}) tunernumber.update({mystr : str(row["TUNERNUMBER"])}) @@ -155,7 +158,7 @@ def tunerNumberAnalysis(file, rows): def main(): file = open("tuner.csv", "w") rows = analyzeLogs(file) - tunerNumberAnalysis(file, rows) + tunerCountAnalysis(file, rows) file.close() return