Bug fixes
[satune.git] / src / Tuner / autotuner.cc
1 #include "autotuner.h"
2 #include "csolver.h"
3 #include "searchtuner.h"
4 #include <math.h>
5 #include <stdlib.h>
6 #include <float.h>
7
8 AutoTuner::AutoTuner(uint _budget) :
9         budget(_budget) {
10 }
11
12 void AutoTuner::addProblem(CSolver *solver) {
13         solvers.push(solver);
14 }
15
16 long long AutoTuner::evaluate(CSolver * problem, SearchTuner *tuner) {
17         CSolver * copy=problem->clone();
18         copy->setTuner(tuner);
19         int result = copy->startEncoding();
20         long long elapsedTime=copy->getElapsedTime();
21         long long encodeTime=copy->getEncodeTime();
22         long long solveTime=copy->getSolveTime();
23         long long metric=elapsedTime;
24         model_print("Elapsed Time: %llu\n", elapsedTime);
25         model_print("Encode Time: %llu\n", encodeTime);
26         model_print("Solve Time: %llu\n", solveTime);
27         delete copy;
28         return metric;
29 }
30
31 double AutoTuner::evaluateAll(SearchTuner *tuner) {
32         double product=1;
33         for(uint i=0;i<solvers.getSize();i++) {
34                 CSolver * problem=solvers.get(i);
35                 double score=evaluate(problem, tuner);
36                 product*=score;
37         }
38         return pow(product, 1/((double)solvers.getSize()));
39 }
40
41 SearchTuner * AutoTuner::mutateTuner(SearchTuner * oldTuner, uint k) {
42         SearchTuner *newTuner=oldTuner->copyUsed();
43         uint numSettings=oldTuner->getSize();
44         double factor=0.3;//Adjust this factor...
45         uint settingsToMutate=(uint)(factor*(((double)numSettings) * k)/(budget));
46         if (settingsToMutate < 1)
47                 settingsToMutate=1;
48         model_print("Mutating %u settings\n", settingsToMutate);
49         while(settingsToMutate-- != 0) {
50                 newTuner->randomMutate();
51         }
52         return newTuner;
53 }
54
55
56 void AutoTuner::tune() {
57         SearchTuner * bestTuner = NULL;
58         double bestScore=DBL_MAX;
59
60         SearchTuner * oldTuner=new SearchTuner();
61         double base_temperature=evaluateAll(oldTuner);
62         double oldScore=base_temperature;
63
64         for (uint i=0;i<budget;i++) {
65                 SearchTuner *newTuner=mutateTuner(oldTuner, i);
66                 double newScore=evaluateAll(newTuner);
67                 newTuner->printUsed();
68                 model_print("Received score %f\n", newScore);
69                 double scoreDiff=newScore - oldScore; //smaller is better
70                 if (newScore < bestScore) {
71                         if (bestTuner != NULL)
72                                 delete bestTuner;
73                         bestScore = newScore;
74                         bestTuner = newTuner->copyUsed();
75                 }
76
77                 double acceptanceP;
78                 if (scoreDiff < 0) {
79                         acceptanceP = 1;
80                 } else {
81                         double currTemp=base_temperature * (((double)budget - i) / budget);
82                         acceptanceP = exp(-scoreDiff / currTemp);
83                 }
84                 double ran = ((double)random()) / RAND_MAX;
85                 if (ran <= acceptanceP) {
86                         delete oldTuner;
87                         oldScore = newScore;
88                         oldTuner = newTuner;
89                 } else {
90                         delete newTuner;
91                 }
92         }
93         model_print("Best tuner:\n");
94         bestTuner->print();
95         model_print("Received score %f\n", bestScore);
96         if (bestTuner != NULL)
97                 delete bestTuner;
98         delete oldTuner;
99 }