3 #include "searchtuner.h"
11 #include <condition_variable>
15 #define POSINFINITY 9999999999L
17 using namespace std::chrono_literals;
19 int solve(CSolver *solver)
22 return solver->solve();
24 catch (std::runtime_error &e) {
29 int solveWrapper(CSolver *solver)
32 std::condition_variable cv;
35 std::thread t([&cv, &retValue, solver]()
37 retValue = solve(solver);
44 std::unique_lock<std::mutex> l(m);
45 if (cv.wait_for(l, TIMEOUT) == std::cv_status::timeout)
46 throw std::runtime_error("Timeout");
53 AutoTuner::AutoTuner(uint _budget) :
54 budget(_budget), result(UNSETVALUE) {
57 void AutoTuner::addProblem(CSolver *solver) {
61 long long AutoTuner::evaluate(CSolver *problem, SearchTuner *tuner) {
62 CSolver *copy = problem->clone();
63 copy->setTuner(tuner);
64 model_print("**********************\n");
65 long long metric = 0L;
67 int sat = solveWrapper(copy);
68 if (result == UNSETVALUE)
70 else if (result != sat) {
71 model_print("&&&&&&&&&&&&&&&&&& Result has changed &&&&&&&&&&&&&\n");
72 copy->printConstraints();
74 metric = copy->getElapsedTime();
76 catch (std::runtime_error &e) {
78 model_print("TimeOut has hit\n");
85 double AutoTuner::evaluateAll(SearchTuner *tuner) {
87 for (uint i = 0; i < solvers.getSize(); i++) {
88 CSolver *problem = solvers.get(i);
89 double score = evaluate(problem, tuner);
92 return pow(product, 1 / ((double)solvers.getSize()));
95 SearchTuner *AutoTuner::mutateTuner(SearchTuner *oldTuner, uint k) {
96 SearchTuner *newTuner = oldTuner->copyUsed();
97 uint numSettings = oldTuner->getSize();
98 uint settingsToMutate = (uint)(AUTOTUNERFACTOR * (((double)numSettings) * (budget - k)) / (budget));
99 if (settingsToMutate < 1)
100 settingsToMutate = 1;
101 model_print("Mutating %u settings\n", settingsToMutate);
102 while (settingsToMutate-- != 0) {
103 newTuner->randomMutate();
109 void AutoTuner::tune() {
110 SearchTuner *bestTuner = NULL;
111 double bestScore = DBL_MAX;
113 SearchTuner *oldTuner = new SearchTuner();
114 double base_temperature = evaluateAll(oldTuner);
115 double oldScore = base_temperature;
117 for (uint i = 0; i < budget; i++) {
118 SearchTuner *newTuner = mutateTuner(oldTuner, i);
119 double newScore = evaluateAll(newTuner);
120 newTuner->printUsed();
121 model_print("Received score %f\n", newScore);
122 double scoreDiff = newScore - oldScore; //smaller is better
123 if (newScore < bestScore) {
124 if (bestTuner != NULL)
126 bestScore = newScore;
127 bestTuner = newTuner->copyUsed();
134 double currTemp = base_temperature * (((double)budget - i) / budget);
135 acceptanceP = exp(-scoreDiff / currTemp);
137 double ran = ((double)random()) / RAND_MAX;
138 if (ran <= acceptanceP) {
146 model_print("Best tuner:\n");
148 bestTuner->serialize();
149 model_print("Received score %f\n", bestScore);
150 if (bestTuner != NULL)