1 #include "multituner.h"
3 #include "searchtuner.h"
13 #define TIMEOUTSEC 5000
15 Problem::Problem(const char *_problem) : result(UNSETVALUE) {
16 uint len = strlen(_problem);
17 problem = (char *) ourmalloc(len + 1);
18 memcpy(problem, _problem, len + 1);
25 MultiTuner::MultiTuner(uint _budget, uint _timeout) :
26 budget(_budget), timeout(_timeout), execnum(0) {
29 MultiTuner::~MultiTuner() {
30 for (uint i = 0; i < problems.getSize(); i++)
31 ourfree(problems.get(i));
34 void MultiTuner::addProblem(const char *filename) {
35 problems.push(new Problem(filename));
38 void MultiTuner::addTuner(SearchTuner *tuner) {
39 tuners.push(new TunerRecord(tuner));
42 long long MultiTuner::evaluate(Problem *problem, SearchTuner *tuner) {
45 snprintf(buffer, sizeof(buffer), "tuner%u", execnum);
46 tuner->serialize(buffer);
49 snprintf(buffer, sizeof(buffer), "deserializerun %s %u tuner%u result%s%u > log%u", problem->getProblem(), timeout, execnum, problem->getProblem(), execnum, execnum);
50 int status = system(buffer);
52 long long metric = -1;
55 //Read data in from results file
56 snprintf(buffer, sizeof(buffer), "result%s%u", problem->getProblem(), execnum);
59 myfile.open (buffer, ios::in);
62 if (myfile.is_open()) {
68 //Increment execution count
71 if (problem->result == UNSETVALUE && sat != IS_INDETER) {
72 problem->result = sat;
73 } else if (problem->result != sat && sat != IS_INDETER) {
74 model_print("******** Result has changed ********\n");
79 void MultiTuner::mapProblemsToTuners(Vector<TunerRecord *> *tunerV) {
80 for (uint i = 0; i < problems.getSize(); i++) {
81 Problem *problem = problems.get(i);
82 TunerRecord *bestTuner = NULL;
83 long long bestscore = 0;
84 for (uint j = 0; j < tunerV->getSize(); j++) {
85 TunerRecord *tuner = tunerV->get(j);
86 long long metric = evaluate(problem, tuner->getTuner());
87 if ((bestTuner == NULL && metric != -1) ||
88 (metric < bestscore && metric != -1)) {
93 if (bestTuner != NULL)
94 bestTuner->problems.push(problem);
98 void clearVector(Vector<TunerRecord *> *tunerV) {
99 for (uint j = 0; j < tunerV->getSize(); j++) {
100 TunerRecord *tuner = tunerV->get(j);
101 tuner->problems.clear();
105 void MultiTuner::tuneK() {
106 Vector<TunerRecord *> *tunerV = new Vector<TunerRecord *>(&tuners);
109 mapProblemsToTuners(tunerV);
110 improveTuners(tunerV);
116 void MultiTuner::improveTuners(Vector<TunerRecord *> *tunerV) {
117 for (uint j = 0; j < tunerV->getSize(); j++) {
118 TunerRecord *tuner = tunerV->get(j);
119 SearchTuner *newtuner = tune(tuner->getTuner(), &tuner->problems);
123 double MultiTuner::evaluateAll(SearchTuner *tuner, Vector<Problem *> *tProblems) {
125 for (uint i = 0; i < tProblems->getSize(); i++) {
126 Problem *problem = tProblems->get(i);
127 double score = evaluate(problem, tuner);
130 return pow(product, 1 / ((double)tProblems->getSize()));
133 SearchTuner *MultiTuner::mutateTuner(SearchTuner *oldTuner, uint k) {
134 SearchTuner *newTuner = oldTuner->copyUsed();
135 uint numSettings = oldTuner->getSize();
136 uint settingsToMutate = (uint)(AUTOTUNERFACTOR * (((double)numSettings) * (budget - k)) / (budget));
137 if (settingsToMutate < 1)
138 settingsToMutate = 1;
139 model_print("Mutating %u settings\n", settingsToMutate);
140 while (settingsToMutate-- != 0) {
141 newTuner->randomMutate();
146 SearchTuner *MultiTuner::tune(SearchTuner *tuner, Vector<Problem *> *tProblems) {
147 SearchTuner *bestTuner = NULL;
148 double bestScore = DBL_MAX;
150 SearchTuner *oldTuner = tuner->copyUsed();
151 double base_temperature = evaluateAll(oldTuner, tProblems);
152 double oldScore = base_temperature;
154 for (uint i = 0; i < budget; i++) {
155 SearchTuner *newTuner = mutateTuner(oldTuner, i);
156 double newScore = evaluateAll(newTuner, tProblems);
157 newTuner->printUsed();
158 model_print("Received score %f\n", newScore);
159 double scoreDiff = newScore - oldScore; //smaller is better
160 if (newScore < bestScore) {
161 if (bestTuner != NULL)
163 bestScore = newScore;
164 bestTuner = newTuner->copyUsed();
171 double currTemp = base_temperature * (((double)budget - i) / budget);
172 acceptanceP = exp(-scoreDiff / currTemp);
174 double ran = ((double)random()) / RAND_MAX;
175 if (ran <= acceptanceP) {