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 _rounds, uint _timeout) :
26 budget(_budget), rounds(_rounds), 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);
107 for (uint i = 0; i < rounds; i++) {
109 mapProblemsToTuners(tunerV);
110 improveTuners(tunerV);
112 model_print("Best tuners\n");
113 for (uint j = 0; j < tunerV->getSize(); j++) {
114 TunerRecord *tuner = tunerV->get(j);
116 sprintf(buffer, "tuner%u.conf", j);
117 tuner->getTuner()->serialize(buffer);
118 tuner->getTuner()->print();
123 void MultiTuner::improveTuners(Vector<TunerRecord *> *tunerV) {
124 for (uint j = 0; j < tunerV->getSize(); j++) {
125 TunerRecord *tuner = tunerV->get(j);
126 SearchTuner *newtuner = tune(tuner->getTuner(), &tuner->problems);
130 double MultiTuner::evaluateAll(SearchTuner *tuner, Vector<Problem *> *tProblems) {
132 for (uint i = 0; i < tProblems->getSize(); i++) {
133 Problem *problem = tProblems->get(i);
134 double score = evaluate(problem, tuner);
137 return pow(product, 1 / ((double)tProblems->getSize()));
140 SearchTuner *MultiTuner::mutateTuner(SearchTuner *oldTuner, uint k) {
141 SearchTuner *newTuner = oldTuner->copyUsed();
142 uint numSettings = oldTuner->getSize();
143 uint settingsToMutate = (uint)(AUTOTUNERFACTOR * (((double)numSettings) * (budget - k)) / (budget));
144 if (settingsToMutate < 1)
145 settingsToMutate = 1;
146 model_print("Mutating %u settings\n", settingsToMutate);
147 while (settingsToMutate-- != 0) {
148 newTuner->randomMutate();
153 SearchTuner *MultiTuner::tune(SearchTuner *tuner, Vector<Problem *> *tProblems) {
154 SearchTuner *bestTuner = NULL;
155 double bestScore = DBL_MAX;
157 SearchTuner *oldTuner = tuner->copyUsed();
158 double base_temperature = evaluateAll(oldTuner, tProblems);
159 double oldScore = base_temperature;
161 for (uint i = 0; i < budget; i++) {
162 SearchTuner *newTuner = mutateTuner(oldTuner, i);
163 double newScore = evaluateAll(newTuner, tProblems);
164 newTuner->printUsed();
165 model_print("Received score %f\n", newScore);
166 double scoreDiff = newScore - oldScore; //smaller is better
167 if (newScore < bestScore) {
168 if (bestTuner != NULL)
170 bestScore = newScore;
171 bestTuner = newTuner->copyUsed();
178 double currTemp = base_temperature * (((double)budget - i) / budget);
179 acceptanceP = exp(-scoreDiff / currTemp);
181 double ran = ((double)random()) / RAND_MAX;
182 if (ran <= acceptanceP) {