}
model_print("Best tuner:\n");
bestTuner->print();
- bestTuner->serialize();
+ bestTuner->serialize("TUNER.conf");
model_print("Received score %f\n", bestScore);
if (bestTuner != NULL)
delete bestTuner;
--- /dev/null
+#include "multituner.h"
+#include "csolver.h"
+#include "searchtuner.h"
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+
+#define UNSETVALUE -1
+#define TIMEOUTSEC 5000
+
+Problem::Problem(const char *_problem) : result(UNSETVALUE) {
+ uint len = strlen(_problem);
+ problem = (char *) ourmalloc(len + 1);
+ memcpy(problem, _problem, len + 1);
+}
+
+Problem::~Problem() {
+ ourfree(problem);
+}
+
+MultiTuner::MultiTuner(uint _budget, uint _timeout) :
+ budget(_budget), timeout(_timeout), execnum(0) {
+}
+
+MultiTuner::~MultiTuner() {
+ for (uint i = 0; i < problems.getSize(); i++)
+ ourfree(problems.get(i));
+}
+
+void MultiTuner::addProblem(const char *filename) {
+ problems.push(new Problem(filename));
+}
+
+void MultiTuner::addTuner(SearchTuner *tuner) {
+ tuners.push(new TunerRecord(tuner));
+}
+
+long long MultiTuner::evaluate(Problem *problem, SearchTuner *tuner) {
+ char buffer[512];
+ //Write out the tuner
+ snprintf(buffer, sizeof(buffer), "tuner%u", execnum);
+ tuner->serialize(buffer);
+
+ //Do run
+ snprintf(buffer, sizeof(buffer), "deserializerun %s %u tuner%u result%s%u", problem->getProblem(), timeout, execnum, problem->getProblem(), 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%s%u", problem->getProblem(), execnum);
+
+ ifstream myfile;
+ myfile.open (buffer, ios::in);
+
+
+ if (myfile.is_open()) {
+ myfile >> metric;
+ myfile >> sat;
+ myfile.close();
+ }
+ }
+ //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;
+}
+
+double MultiTuner::evaluateAll(SearchTuner *tuner) {
+ double product = 1;
+ for (uint i = 0; i < problems.getSize(); i++) {
+ Problem *problem = problems.get(i);
+ double score = evaluate(problem, tuner);
+ product *= score;
+ }
+ return pow(product, 1 / ((double)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;
+}
+
+void MultiTuner::tune() {
+ SearchTuner *bestTuner = NULL;
+ double bestScore = DBL_MAX;
+
+ SearchTuner *oldTuner = new SearchTuner();
+ double base_temperature = evaluateAll(oldTuner);
+ double oldScore = base_temperature;
+
+ for (uint i = 0; i < budget; i++) {
+ SearchTuner *newTuner = mutateTuner(oldTuner, i);
+ double newScore = evaluateAll(newTuner);
+ newTuner->printUsed();
+ model_print("Received score %f\n", newScore);
+ double scoreDiff = newScore - oldScore; //smaller is better
+ if (newScore < bestScore) {
+ if (bestTuner != NULL)
+ delete bestTuner;
+ bestScore = newScore;
+ bestTuner = newTuner->copyUsed();
+ }
+
+ double acceptanceP;
+ if (scoreDiff < 0) {
+ acceptanceP = 1;
+ } else {
+ double currTemp = base_temperature * (((double)budget - i) / budget);
+ acceptanceP = exp(-scoreDiff / currTemp);
+ }
+ double ran = ((double)random()) / RAND_MAX;
+ if (ran <= acceptanceP) {
+ delete oldTuner;
+ oldScore = newScore;
+ oldTuner = newTuner;
+ } else {
+ delete newTuner;
+ }
+ }
+ model_print("Best tuner:\n");
+ bestTuner->print();
+ model_print("Received score %f\n", bestScore);
+ if (bestTuner != NULL)
+ delete bestTuner;
+ delete oldTuner;
+}
--- /dev/null
+#ifndef MULTITUNER_H
+#define MULTITUNER_H
+#include "classlist.h"
+#include "structs.h"
+
+#define AUTOTUNERFACTOR 0.3
+
+class Problem {
+public:
+ Problem(const char *problem);
+ char *getProblem() {return problem;}
+ ~Problem();
+ CMEMALLOC;
+private:
+ int result;
+ char *problem;
+ friend class MultiTuner;
+};
+
+class TunerRecord {
+public:
+ TunerRecord(SearchTuner *_tuner) : tuner(_tuner) {}
+
+private:
+ SearchTuner *tuner;
+ friend class MultiTuner;
+};
+
+class MultiTuner {
+public:
+ MultiTuner(uint budget, uint timeout);
+ ~MultiTuner();
+ void addProblem(const char *filename);
+ void addTuner(SearchTuner *tuner);
+ virtual void tune();
+ CMEMALLOC;
+protected:
+ long long evaluate(Problem *problem, SearchTuner *tuner);
+ double evaluateAll(SearchTuner *tuner);
+ SearchTuner *mutateTuner(SearchTuner *oldTuner, uint k);
+ Vector<Problem *> problems;
+ Vector<TunerRecord *> tuners;
+ uint budget;
+ uint timeout;
+ int execnum;
+};
+#endif
SearchTuner::SearchTuner() {
+}
+
+SearchTuner::SearchTuner(const char *filename) {
ifstream myfile;
- myfile.open (TUNEFILE, ios::in);
+ myfile.open (filename, ios::in);
if (myfile.is_open()) {
bool hasVar;
VarType type1;
}
-void SearchTuner::serialize() {
+void SearchTuner::serialize(const char *filename) {
ofstream myfile;
- myfile.open (TUNEFILE, ios::out | ios::trunc);
+ myfile.open (filename, ios::out | ios::trunc);
SetIteratorTunableSetting *iterator = settings.iterator();
while (iterator->hasNext()) {
TunableSetting *setting = iterator->next();
#include "structs.h"
#include <ostream>
using namespace std;
-#define TUNEFILE "tune.conf"
class TunableSetting {
public:
friend unsigned int tunableSettingHash(TunableSetting *setting);
friend bool tunableSettingEquals(TunableSetting *setting1, TunableSetting *setting2);
friend class SearchTuner;
- friend class StaticSearchTuner;
+ friend class StaticSearchTuner;
};
unsigned int tunableSettingHash(TunableSetting *setting);
class SearchTuner : public Tuner {
public:
SearchTuner();
+ SearchTuner(const char *filename);
~SearchTuner();
int getTunable(TunableParam param, TunableDesc *descriptor);
int getVarTunable(VarType vartype, TunableParam param, TunableDesc *descriptor);
uint getSize() { return usedSettings.getSize();}
void print();
void printUsed();
- void serialize();
+ void serialize(const char *file);
CMEMALLOC;
protected:
StaticSearchTuner *StaticAutoTuner::mutateTuner(StaticSearchTuner *oldTuner) {
StaticSearchTuner *newTuner = oldTuner->copyUsed();
result = newTuner->nextStaticTuner();
- return result==EXIT_FAILURE? newTuner: NULL;
+ return result == EXIT_FAILURE ? newTuner : NULL;
}
void StaticAutoTuner::tune() {
double base_temperature = evaluateAll(oldTuner);
double oldScore = base_temperature;
- while(true){
+ while (true) {
StaticSearchTuner *newTuner = mutateTuner(oldTuner);
- if(newTuner == NULL)
+ if (newTuner == NULL)
return;
double newScore = evaluateAll(newTuner);
newTuner->printUsed();
class StaticAutoTuner : public AutoTuner {
public:
StaticAutoTuner(uint budget);
- virtual void tune();
- CMEMALLOC;
+ virtual void tune();
+ CMEMALLOC;
private:
StaticSearchTuner *mutateTuner(StaticSearchTuner *oldTuner);
};
using namespace std;
StaticSearchTuner::StaticSearchTuner() {
- graphEncoding =false;
- naiveEncoding = ELEM_UNASSIGNED;
+ graphEncoding = false;
+ naiveEncoding = ELEM_UNASSIGNED;
ifstream myfile;
myfile.open (TUNEFILE, ios::in);
if (myfile.is_open()) {
TunableSetting *copy = new TunableSetting(setting);
tuner->settings.add(copy);
}
- if(naiveEncoding != ELEM_UNASSIGNED){
+ if (naiveEncoding != ELEM_UNASSIGNED) {
tuner->graphEncoding = graphEncoding;
tuner->naiveEncoding = naiveEncoding;
}
}
int StaticSearchTuner::nextStaticTuner() {
- if(naiveEncoding == ELEM_UNASSIGNED){
+ if (naiveEncoding == ELEM_UNASSIGNED) {
naiveEncoding = ONEHOT;
SetIteratorTunableSetting *iter = settings.iterator();
- while(iter->hasNext()){
+ while (iter->hasNext()) {
TunableSetting *setting = iter->next();
- if (setting->param == NAIVEENCODER){
+ if (setting->param == NAIVEENCODER) {
setting->selectedValue = ONEHOT;
- } else if(setting->param == ENCODINGGRAPHOPT){
+ } else if (setting->param == ENCODINGGRAPHOPT) {
setting->selectedValue = false;
}
}
delete iter;
return EXIT_FAILURE;
}
- int result=EXIT_FAILURE;
- if(naiveEncoding == BINARYINDEX && graphEncoding){
+ int result = EXIT_FAILURE;
+ if (naiveEncoding == BINARYINDEX && graphEncoding) {
model_print("Best tuner\n");
return EXIT_SUCCESS;
- }else if (naiveEncoding == BINARYINDEX && !graphEncoding){
+ } else if (naiveEncoding == BINARYINDEX && !graphEncoding) {
naiveEncoding = ONEHOT;
graphEncoding = true;
- }else {
+ } else {
naiveEncoding = (ElementEncodingType)((int)naiveEncoding + 1);
}
SetIteratorTunableSetting *iter = settings.iterator();
uint count = 0;
- while(iter->hasNext()){
- TunableSetting * setting = iter->next();
- if (setting->param == NAIVEENCODER){
+ while (iter->hasNext()) {
+ TunableSetting *setting = iter->next();
+ if (setting->param == NAIVEENCODER) {
setting->selectedValue = naiveEncoding;
count++;
- } else if(setting->param == ENCODINGGRAPHOPT){
+ } else if (setting->param == ENCODINGGRAPHOPT) {
setting->selectedValue = graphEncoding;
count++;
}
#ifndef STATICSEARCHTUNER_H
#define STATICSEARCHTUNER_H
#include "searchtuner.h"
+#define TUNEFILE "tune.conf"
class StaticSearchTuner : public SearchTuner {
public:
StaticSearchTuner();
~StaticSearchTuner();
- int nextStaticTuner();
+ int nextStaticTuner();
StaticSearchTuner *copyUsed();
-
+
CMEMALLOC;
private:
- bool graphEncoding;
- ElementEncodingType naiveEncoding;
+ bool graphEncoding;
+ ElementEncodingType naiveEncoding;
};
#endif
return descriptor->defaultValue;
}
-const char* tunableParameterToString(Tunables tunable){
- switch(tunable){
- case DECOMPOSEORDER:
- return "DECOMPOSEORDER";
- case MUSTREACHGLOBAL:
- return "MUSTREACHGLOBAL";
- case MUSTREACHLOCAL:
- return "MUSTREACHLOCAL";
- case MUSTREACHPRUNE:
- return "MUSTREACHPRUNE";
- case OPTIMIZEORDERSTRUCTURE:
- return "OPTIMIZEORDERSTRUCTURE";
- case ORDERINTEGERENCODING:
- return "ORDERINTEGERENCODING";
- case PREPROCESS:
- return "PREPROCESS";
- case NODEENCODING:
- return "NODEENCODING";
- case EDGEENCODING:
- return "EDGEENCODING";
- case MUSTEDGEPRUNE:
- return "MUSTEDGEPRUNE";
- case ELEMENTOPT:
- return "ELEMENTOPT";
- case ELEMENTOPTSETS:
- return "ELEMENTOPTSETS";
- case PROXYVARIABLE:
- return "PROXYVARIABLE";
- case ENCODINGGRAPHOPT:
- return "ENCODINGGRAPHOPT";
- case NAIVEENCODER:
- return "NAIVEENCODER";
- case MUSTVALUE:
- return "MUSTVALUE";
- default:
- ASSERT(0);
- }
+const char *tunableParameterToString(Tunables tunable) {
+ switch (tunable) {
+ case DECOMPOSEORDER:
+ return "DECOMPOSEORDER";
+ case MUSTREACHGLOBAL:
+ return "MUSTREACHGLOBAL";
+ case MUSTREACHLOCAL:
+ return "MUSTREACHLOCAL";
+ case MUSTREACHPRUNE:
+ return "MUSTREACHPRUNE";
+ case OPTIMIZEORDERSTRUCTURE:
+ return "OPTIMIZEORDERSTRUCTURE";
+ case ORDERINTEGERENCODING:
+ return "ORDERINTEGERENCODING";
+ case PREPROCESS:
+ return "PREPROCESS";
+ case NODEENCODING:
+ return "NODEENCODING";
+ case EDGEENCODING:
+ return "EDGEENCODING";
+ case MUSTEDGEPRUNE:
+ return "MUSTEDGEPRUNE";
+ case ELEMENTOPT:
+ return "ELEMENTOPT";
+ case ELEMENTOPTSETS:
+ return "ELEMENTOPTSETS";
+ case PROXYVARIABLE:
+ return "PROXYVARIABLE";
+ case ENCODINGGRAPHOPT:
+ return "ENCODINGGRAPHOPT";
+ case NAIVEENCODER:
+ return "NAIVEENCODER";
+ case MUSTVALUE:
+ return "MUSTVALUE";
+ default:
+ ASSERT(0);
+ }
}
static TunableDesc NodeEncodingDesc(ELEM_UNASSIGNED, BINARYINDEX, ELEM_UNASSIGNED);
static TunableDesc NaiveEncodingDesc(ONEHOT, BINARYINDEX, ONEHOT);
-enum Tunables {DECOMPOSEORDER, MUSTREACHGLOBAL, MUSTREACHLOCAL, MUSTREACHPRUNE, OPTIMIZEORDERSTRUCTURE, ORDERINTEGERENCODING, PREPROCESS, NODEENCODING, EDGEENCODING, MUSTEDGEPRUNE, ELEMENTOPT,
- ENCODINGGRAPHOPT, ELEMENTOPTSETS, PROXYVARIABLE, MUSTVALUE, NAIVEENCODER};
+enum Tunables {DECOMPOSEORDER, MUSTREACHGLOBAL, MUSTREACHLOCAL, MUSTREACHPRUNE, OPTIMIZEORDERSTRUCTURE, ORDERINTEGERENCODING, PREPROCESS, NODEENCODING, EDGEENCODING, MUSTEDGEPRUNE, ELEMENTOPT,
+ ENCODINGGRAPHOPT, ELEMENTOPTSETS, PROXYVARIABLE, MUSTVALUE, NAIVEENCODER};
typedef enum Tunables Tunables;
const char *tunableParameterToString(Tunables tunable);