Commit b09cfae7 authored by EYRAUD-DUBOIS Lionel's avatar EYRAUD-DUBOIS Lionel

New option 'best'

Also reindent
parent b06768d9
......@@ -27,6 +27,8 @@ static const int opt_no_convert = 10;
static const int opt_no_dependencies = 11;
static const int opt_no_header = 12;
static const int opt_rev_dep = 13;
static const int opt_best = 14;
static struct option long_options[] = {
{"verbose", required_argument, 0, 'v' },
......@@ -44,6 +46,7 @@ static struct option long_options[] = {
{"platform", required_argument, 0, 'p'},
{"help", no_argument, 0, 'h'},
{"default", optional_argument, 0, 'd'},
{"best", optional_argument, 0, opt_best},
{0, 0, 0, 0 }
};
......@@ -57,7 +60,8 @@ ProgramOptions::ProgramOptions() {
mergeTolerance = 0.01;
outputNamesRaw = 0;
noHeader = false;
optRevDep = false;
optRevDep = false;
outputBest = false;
}
void ProgramOptions::parse(int argc, char** argv) {
......@@ -133,6 +137,11 @@ void ProgramOptions::parse(int argc, char** argv) {
cerr << "Unknown default specification: '" << s_optarg <<"'. Valid values: 'slow', 'normal', 'fast'" << endl;
}
break;
case opt_best:
outputBest = true;
if(optarg)
outputBestFile = s_optarg;
break ;
case '?':
case 'h':
usage();
......@@ -147,9 +156,14 @@ void ProgramOptions::parse(int argc, char** argv) {
}
string buildNameRaw(string name, AlgOptions opts) {
return name.append(":").append(opts.serialize());
}
string ProgramOptions::buildName(string name, AlgOptions opts, bool forceRaw) {
if(forceRaw || outputNamesRaw) {
name = name.append(":").append(opts.serialize());
name = buildNameRaw(name, opts);
} else {
for(string s: optionKeys) {
name = name.append(" ").append(opts.asString(s, "NA"));
......
......@@ -10,6 +10,13 @@
typedef std::pair<Algorithm*, AlgOptions> fullAlg;
typedef std::pair<Bound*, AlgOptions> fullBound;
std::string buildNameRaw(std::string name, AlgOptions opts);
template <class T>
std::string buildNameRawLocal(T* t) {
return buildNameRaw(t->first->name(), t->second);
}
class ProgramOptions {
private:
void displayAlgList();
......@@ -39,6 +46,8 @@ class ProgramOptions {
bool outputNamesRaw = 0;
bool noHeader = false;
bool optRevDep = false;
bool outputBest;
std::string outputBestFile;
std::set<std::string> optionKeys;
......
......@@ -15,6 +15,8 @@
using namespace std;
int main(int argc, char** argv) {
ProgramOptions progOpt;
......@@ -35,170 +37,224 @@ int main(int argc, char** argv) {
if(progOpt.platformFiles.size() == 0)
progOpt.platformFiles.push_back("");
if(progOpt.outputBestFile != "") {
ofstream save(progOpt.outputBestFile);
save.close();
}
for(string &input_file: progOpt.inputFiles) {
for(string &platform_file : progOpt.platformFiles) {
// Read instance
Instance* instance;
size_t dotPosition = input_file.rfind('.');
auto start = chrono::steady_clock::now();
if(progOpt.verbosity >= 4)
cerr << "Reading input file '" << input_file << "' with platform file '" << platform_file << "'...";
if(dotPosition != string::npos
&& input_file.compare(dotPosition, string::npos, ".rec") == 0) {
if(platform_file == "")
instance = new RecFileInstance(input_file);
else
instance = new RecFileInstance(input_file, platform_file);
}
// Read instance
Instance* instance;
size_t dotPosition = input_file.rfind('.');
auto start = chrono::steady_clock::now();
if(progOpt.verbosity >= 4)
cerr << "Reading input file '" << input_file << "' with platform file '" << platform_file << "'...";
if(dotPosition != string::npos
&& input_file.compare(dotPosition, string::npos, ".rec") == 0) {
if(platform_file == "")
instance = new RecFileInstance(input_file);
else
instance = new RecFileInstance(input_file, platform_file);
}
else
instance = new Instance(input_file, progOpt.convertIndices);
if(progOpt.noDependencies)
instance->removeDependencies();
if(progOpt.optRevDep)
instance->revertDependencies();
if(progOpt.noDependencies)
instance->removeDependencies();
if(progOpt.optRevDep)
instance->revertDependencies();
if(progOpt.mergeTolerance > 0) {
instance->autoMerge(progOpt.mergeTolerance);
}
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
if(progOpt.verbosity >= 4)
cerr << " done (" << time.count() << " ms)." << endl;
instance->display(progOpt.verbosity);
// Iterate through bound list, execute all
for(auto it = progOpt.bounds.begin(); it < progOpt.bounds.end(); it++) {
auto opts = it->second;
string name = progOpt.buildName(it->first->name(), opts);
auto start = chrono::steady_clock::now();
try {
double result = it->first->compute(*instance);
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
// auto duration =
cout << input_file << " " << name << " " << result << " " <<
time.count();
} catch (int e) {
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
cout << input_file << " " << name << " " << "NA" << " " <<
time.count();
if(progOpt.mergeTolerance > 0) {
instance->autoMerge(progOpt.mergeTolerance);
}
if(progOpt.repartitionFile != "") {
cout << " " << "NA" << " " << "NA";
cout << " " << "NA" << " " << "NA";
}
cout << endl;
}
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
if(progOpt.verbosity >= 4)
cerr << " done (" << time.count() << " ms)." << endl;
instance->display(progOpt.verbosity);
double bestBoundValue = 0;
fullBound* bestBound = NULL;
// Iterate through bound list, execute all
for(auto it = progOpt.bounds.begin(); it < progOpt.bounds.end(); it++) {
auto opts = it->second;
string name = progOpt.buildName(it->first->name(), opts);
auto start = chrono::steady_clock::now();
try {
double result = it->first->compute(*instance);
if(!bestBound && bestBoundValue < result) {
bestBoundValue = result;
bestBound = &(*it);
}
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
// auto duration =
cout << input_file << " " << name << " " << result << " " <<
time.count();
} catch (int e) {
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
cout << input_file << " " << name << " " << "NA" << " " <<
time.count();
}
if(progOpt.repartitionFile != "") {
cout << " " << "NA" << " " << "NA";
cout << " " << "NA" << " " << "NA";
}
cout << endl;
ActionSequence seq;
ExportToFile* globalExport = NULL;
UtilAnalysis* utilAnalyser = NULL;
}
if(progOpt.saveFile != "") {
globalExport = new ExportToFile(progOpt.saveFile, instance, true, "NA");
seq.add(globalExport);
}
if(progOpt.repartitionFile != "") {
utilAnalyser = new UtilAnalysis(instance, progOpt.repartitionFile);
seq.add(utilAnalyser);
}
// Iterate through algorithm list, execute all
for(auto it = progOpt.algs.begin(); it < progOpt.algs.end(); it++) {
auto opts = it->second;
ActionSequence seq;
ExportSchedule* globalExport = NULL;
UtilAnalysis* utilAnalyser = NULL;
ExportToFile* localExport = NULL;
if(opts.isPresent("save")) {
localExport = new ExportToFile(opts.asString("save"), instance, true);
seq.add(localExport);
if(progOpt.saveFile != "") {
globalExport = new ExportToFile(progOpt.saveFile, instance, true, "NA");
seq.add(globalExport);
}
InternalShare* share = NULL;
if(opts.isPresent("share")) {
share = new InternalShare(opts.asString("share"), instance);
seq.add(share);
if(progOpt.repartitionFile != "") {
utilAnalyser = new UtilAnalysis(instance, progOpt.repartitionFile);
seq.add(utilAnalyser);
}
ExportAlloc* exportAlloc = NULL;
if(opts.isPresent("export")) {
exportAlloc = new ExportAlloc(opts.asString("export"), instance);
seq.add(exportAlloc);
}
double bestAlgorithmValue = std::numeric_limits<double>::infinity();
fullAlg* bestAlgorithm = NULL;
ExportToString* bestSchedule = NULL;
ExportBubble * exportBubble = NULL;
if(opts.isPresent("bubble")) {
exportBubble = new ExportBubble(opts.asString("bubble"), instance, opts.asInt("bubbleType"));
seq.add(exportBubble);
}
// Iterate through algorithm list, execute all
for(auto it = progOpt.algs.begin(); it < progOpt.algs.end(); it++) {
auto opts = it->second;
ExportSchedule* localExport = NULL;
if(opts.isPresent("save")) {
localExport = new ExportToFile(opts.asString("save"), instance, true);
seq.add(localExport);
}
string name = progOpt.buildName(it->first->name(), it->second);
ExportToString* bestExport = NULL;
if(progOpt.outputBestFile != ""){
bestExport = new ExportToString(instance, true, input_file
+ (platform_file == ""?"":":"+platform_file));
seq.add(bestExport);
}
// In save files, always use raw names, please.
if(globalExport)
globalExport->changeName(progOpt.buildName(it->first->name(), it->second, true));
auto start = chrono::steady_clock::now();
InternalShare* share = NULL;
if(opts.isPresent("share")) {
share = new InternalShare(opts.asString("share"), instance);
seq.add(share);
}
try {
double result = it->first->compute(*instance, &seq);
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
cout << input_file << " " << name << " " << result << " " << time.count();
if(utilAnalyser){
if(instance->nbWorkerTypes == 2) {
std::vector<std::vector<int> > r = utilAnalyser->getRepartition();
for(int i = 0; i < (int) r.size(); i++) {
double usage = 0.0;
double otherUsage = 0.0;
for(int j = 0; j < (int) r[i].size(); j++){
usage += r[i][j] * instance->execTimes[i][j];
otherUsage += r[i][j] * instance->execTimes[1-i][j];
ExportAlloc* exportAlloc = NULL;
if(opts.isPresent("export")) {
exportAlloc = new ExportAlloc(opts.asString("export"), instance);
seq.add(exportAlloc);
}
ExportBubble * exportBubble = NULL;
if(opts.isPresent("bubble")) {
exportBubble = new ExportBubble(opts.asString("bubble"), instance, opts.asInt("bubbleType"));
seq.add(exportBubble);
}
string name = progOpt.buildName(it->first->name(), it->second);
// In save files, always use raw names, please.
if(globalExport)
globalExport->changeName(progOpt.buildName(it->first->name(), it->second, true));
auto start = chrono::steady_clock::now();
bool isBestSoFar = false;
try {
double result = it->first->compute(*instance, &seq);
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
cout << input_file << " " << name << " " << result << " " << time.count();
if(!bestAlgorithm || bestAlgorithmValue < result) {
bestAlgorithm = &(*it);
bestAlgorithmValue = result;
isBestSoFar = true;
if(bestExport){
if(bestSchedule) free(bestSchedule);
bestSchedule = bestExport;
}
}
if(utilAnalyser){
if(instance->nbWorkerTypes == 2) {
std::vector<std::vector<int> > r = utilAnalyser->getRepartition();
for(int i = 0; i < (int) r.size(); i++) {
double usage = 0.0;
double otherUsage = 0.0;
for(int j = 0; j < (int) r[i].size(); j++){
usage += r[i][j] * instance->execTimes[i][j];
otherUsage += r[i][j] * instance->execTimes[1-i][j];
}
cout << " " << usage << " " << (i == 0 ? usage / otherUsage : otherUsage / usage);
}
cout << " " << usage << " " << (i == 0 ? usage / otherUsage : otherUsage / usage);
} else {
cout << " " << "NA" << " " << "NA";
cout << " " << "NA" << " " << "NA";
}
} else {
cout << " " << "NA" << " " << "NA";
cout << " " << "NA" << " " << "NA";
utilAnalyser->write(input_file + " " + name);
}
utilAnalyser->write(input_file + " " + name);
}
} catch (int e) {
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
} catch (int e) {
auto time = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start);
cout << input_file << " " << name << " " << "NA" << " " << time.count();
}
cout << input_file << " " << name << " " << "NA" << " " << time.count();
}
cout << endl;
cout << endl;
if(localExport){
seq.remove(localExport);
free(localExport);
}
if(exportAlloc) {
seq.remove(exportAlloc);
free(exportAlloc);
if(bestExport) {
seq.remove(bestExport);
if(!isBestSoFar)
free(bestExport);
}
if(localExport){
seq.remove(localExport);
free(localExport);
}
if(exportAlloc) {
seq.remove(exportAlloc);
free(exportAlloc);
}
if(share) {
share->finish();
seq.remove(share);
free(share);
}
if(exportBubble) {
exportBubble->finish();
seq.remove(exportBubble);
free(exportBubble);
}
}
if(share) {
share->finish();
seq.remove(share);
free(share);
if(globalExport) free(globalExport);
if(progOpt.outputBest) {
if(bestBound != NULL)
cerr << "Best bound: " << bestBoundValue << " with " << buildNameRawLocal(bestBound) << endl;
cerr << "Best schedule: " << bestAlgorithmValue << " with " << buildNameRawLocal(bestAlgorithm) << endl;
if(bestBound != NULL)
cerr << "Gap: " << (bestAlgorithmValue - bestBoundValue) / bestBoundValue << endl;
}
if(exportBubble) {
exportBubble->finish();
seq.remove(exportBubble);
free(exportBubble);
if(progOpt.outputBestFile != "" && bestSchedule) {
ofstream save(progOpt.outputBestFile, ios::out | ios::app);
save << bestSchedule->getResult();
save.close();
}
}
if(globalExport) free(globalExport);
}
}
return(0);
}
......@@ -38,41 +38,61 @@ int ActionSequence::chooseTask(int wType, double now) {
return SCHEDACTION_NONE;
}
ExportToFile::ExportToFile(string filename, Instance* ins, bool header, string name)
: output(filename), instance(ins), name(name) {
ExportSchedule::ExportSchedule(ostream *stream, Instance* ins, bool header, string name) : output(stream), instance(ins), name(name) {
if(header) outputHeader();
}
ExportSchedule::ExportSchedule(Instance* ins, string name)
: instance(ins), name(name) {
}
ExportToFile::ExportToFile(string filename, Instance* ins, bool header, string name): ExportSchedule(ins, name), f(new ofstream(filename)) {
output = f;
if(header) outputHeader();
}
ExportToString::ExportToString(Instance* ins, bool header, string name)
: ExportSchedule(ins, name), f(new ostringstream()) {
output = f;
if(header) outputHeader();
}
void ExportSchedule::outputHeader() {
if(name != "")
output << "sched ";
if(header) {
output << "Tid worker taskType ";
if(ins->taskIDs.size() > 0)
output << "JobId ";
output << "start duration end" << endl;
}
*output << "sched ";
*output << "Tid worker taskType ";
if(instance->taskIDs.size() > 0)
*output << "JobId ";
*output << "start duration end" << endl;
}
void ExportToFile::changeName(string newName) {
void ExportSchedule::changeName(string newName) {
if((name == "" && newName != "")) {
cerr << "EtF: Warning, adding a name after the start breaks the header" << endl;
cerr << "ExportSchedule: Warning, adding a name after the start breaks the header" << endl;
}
if(name != "" && newName == "") newName = "NA";
name = newName;
}
void ExportToFile::onSchedule(int i, int w, double s, double f) {
void ExportSchedule::onSchedule(int i, int w, double s, double f) {
if(name != "")
output << name << " ";
output << i << " " << w << " ";
*output << name << " ";
*output << i << " " << w << " ";
if(instance->taskTypeNames.size() > 0)
output << instance->taskTypeNames[instance->taskTypes[i]];
*output << instance->taskTypeNames[instance->taskTypes[i]];
else
output << instance->taskTypes[i];
*output << instance->taskTypes[i];
if(instance->taskIDs.size() > 0)
output << " " << instance->taskIDs[i];
output << " " << s << " " << (f - s) << " " << f << endl;
*output << " " << instance->taskIDs[i];
*output << " " << s << " " << (f - s) << " " << f << endl;
}
ExportToFile::~ExportToFile() {
output.close();
f->close();
}
string ExportToString::getResult() {
return f->str();
}
ExportAlloc::ExportAlloc(string filename, Instance* ins) : output(filename), instance(ins) {
......
......@@ -2,6 +2,7 @@
#define SCHEDACTION_H
#include <fstream>
#include <sstream>
#include <vector>
#include "instance.h"
......@@ -26,16 +27,33 @@ class ActionSequence : public SchedAction {
int chooseTask(int wType, double now);
};
class ExportToFile : public SchedAction {
std::ofstream output;
class ExportSchedule : public SchedAction {
protected:
std::ostream* output;
Instance* instance;
std::string name;
std::string name;
void outputHeader();
public:
ExportToFile(std::string filename, Instance* ins, bool header = false, std::string name ="");
ExportSchedule(std::ostream *stream, Instance* ins, bool header = false, std::string name ="");
ExportSchedule(Instance* ins, std::string name = "");
void onSchedule(int i, int w, double s, double f);
void changeName(std::string newName);
};
class ExportToFile : public ExportSchedule {
std::ofstream* f;
public:
ExportToFile(std::string filename, Instance* ins, bool header = false, std::string name ="");
~ExportToFile();
};
class ExportToString: public ExportSchedule {
std::ostringstream* f;
public:
ExportToString(Instance* ins, bool header = false, std::string name ="");
std::string getResult();
};
class ExportAlloc : public SchedAction {
std::ofstream output;
Instance* instance;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment