X-Git-Url: http://plrg.eecs.uci.edu/git/?p=satune.git;a=blobdiff_plain;f=src%2FTuner%2Fmultituner.cc;h=743d4cbf1d16fce5cef6811505338fa5be954cb7;hp=bb80906163af5eafafdd5aa1e75ec45e97002047;hb=ec4122e6d43e951feb8b344bf3511a50e08a3615;hpb=717d7b47d012221acdffe4708de31780252c3315 diff --git a/src/Tuner/multituner.cc b/src/Tuner/multituner.cc index bb80906..743d4cb 100644 --- a/src/Tuner/multituner.cc +++ b/src/Tuner/multituner.cc @@ -1,84 +1,62 @@ #include "multituner.h" -#include "csolver.h" -#include "searchtuner.h" -#include -#include #include -#include +#include +#include "searchtuner.h" #include #include - -#define UNSETVALUE -1 - -Problem::Problem(const char *_problem) : problemnumber(-1), result(UNSETVALUE) { - 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); -} - -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); + BasicTuner(_budget, _timeout), + rounds(_rounds) +{ } -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); +void MultiTuner::findBestThreeTuners() { + if (allTuners.getSize() < 3) { + printData(); + return; + } + TunerRecord *bestTuners[3]; + double score = DBL_MAX; + for (uint i = 0; i < allTuners.getSize() - 2; i++) { + for (uint j = i + 1; j < allTuners.getSize() - 1; j++) { + for (uint k = j + 1; k < allTuners.getSize(); k++) { + TunerRecord *tuner1 = allTuners.get(i); + TunerRecord *tuner2 = allTuners.get(j); + TunerRecord *tuner3 = allTuners.get(k); + double mintimes[problems.getSize()]; + for (uint l = 0; l < problems.getSize(); l++) { + Problem *problem = problems.get(l); + mintimes[l] = pow(min(tuner1->getTime(problem), tuner2->getTime(problem), tuner3->getTime(problem)), (double)1 / problems.getSize()); + } + double result = 1; + for (uint l = 0; l < problems.getSize(); l++) { + result *= mintimes[l]; + } + if (result < score) { + score = result; + bestTuners[0] = tuner1; + bestTuners[1] = tuner2; + bestTuners[2] = tuner3; + } + } + } + } + model_print("Best 3 tuners:\n"); + for (uint i = 0; i < 3; i++) { + TunerRecord *tuner = bestTuners[i]; SearchTuner *stun = tuner->getTuner(); - model_print("Tuner %u\n", i); + char buffer[512]; + snprintf(buffer, sizeof(buffer), "best%u.tuner", i); + stun->serialize(buffer); + model_print("Tuner %u\n", tuner->getTunerNumber()); stun->print(); + tuner->printProblemsInfo(); 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)); - } } } -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; @@ -92,7 +70,7 @@ void MultiTuner::readData(uint numRuns) { allTuners.setSize(tunernumber + 1); if (allTuners.get(tunernumber) == NULL) { snprintf(buffer, sizeof(buffer), "tuner%u", i); - allTuners.set(tunernumber, new TunerRecord(new SearchTuner(buffer))); + allTuners.set(tunernumber, new TunerRecord(new SearchTuner(buffer), tunernumber)); } //Add any new used records snprintf(buffer, sizeof(buffer), "tuner%uused", i); @@ -114,7 +92,7 @@ void MultiTuner::readData(uint numRuns) { long long metric = -1; int sat = IS_INDETER; //Read data in from results file - snprintf(buffer, sizeof(buffer), "result%u", execnum); + snprintf(buffer, sizeof(buffer), "result%u", i); myfile.open (buffer, ios::in); @@ -124,96 +102,32 @@ 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 (metric != -1) { + if (tuner->getTime(problem) == -1) + tuner->addProblem(problem); tuner->setTime(problem, metric); - - - } - -} - -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); - - //Do run - snprintf(buffer, sizeof(buffer), "./run.sh deserializerun %s %u tuner%u result%u > log%u", problem->getProblem(), timeout, 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(); } - 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"); - } - return 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); uint tSize = tunerV->getSize(); for (uint i = 0; i < tSize; i++) { SearchTuner *tmpTuner = mutateTuner(tunerV->get(i)->getTuner(), b); TunerRecord *tmp = new TunerRecord(tmpTuner); - tmp->tunernumber = allTuners.getSize(); + 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); } @@ -227,27 +141,37 @@ void MultiTuner::tuneComp() { long long metric = tuner->getTime(problem); if (metric == -1) { metric = evaluate(problem, tuner); + if (tuner->getTime(problem) == -1) { + tuner->addProblem(problem); + } + 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); + else + tuner->setTime(problem, -2); } - if (metric != -1) { + if (metric >= 0) { uint k = 0; for (; k < places.getSize(); k++) { if (metric < places.get(k)->getTime(problem)) break; } + model_print("place[%u]=Tuner<%p,%d>\n", k, tuner, tuner->getTunerNumber()); places.insertAt(k, tuner); } } int points = 9; for (uint k = 0; k < places.getSize() && points; k++) { TunerRecord *tuner = places.get(k); - points = points / 3; int currScore = 0; if (scores.contains(tuner)) currScore = scores.get(tuner); currScore += points; + 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; } } Vector ranking; @@ -262,13 +186,17 @@ void MultiTuner::tuneComp() { int tscore = 0; if (scores.contains(t)) tscore = scores.get(t); - if (score < tscore) + if (score > tscore) break; } + 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->getTunerNumber()); for (uint j = 0; j < tunerV->getSize(); j++) { if (tunerV->get(j) == tuner) tunerV->removeAt(j); @@ -290,15 +218,17 @@ void MultiTuner::mapProblemsToTuners(Vector *tunerV) { metric = evaluate(problem, tuner); if (metric != -1) tuner->setTime(problem, metric); + else + tuner->setTime(problem, -2); } - if ((bestTuner == NULL && metric != -1) || - (metric < bestscore && metric != -1)) { + if ((bestTuner == NULL && metric >= 0) || + (metric < bestscore && metric >= 0)) { bestTuner = tuner; bestscore = metric; } } if (bestTuner != NULL) - bestTuner->problems.push(problem); + bestTuner->addProblem(problem); } } @@ -337,32 +267,23 @@ 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); if (metric != -1) tuner->setTime(problem, metric); + else + tuner->setTime(problem, -2); } double score = metric; + if (metric < 0) + 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(); - } - return newTuner; + return pow(product, 1 / ((double)tuner->problemsSize())); } TunerRecord *MultiTuner::tune(TunerRecord *tuner) { @@ -376,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) {