schedulers
1.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot 00003 00004 This file is part of Pelib. 00005 00006 Pelib is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Pelib is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with Pelib. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <string> 00021 00022 #include <pelib/PruhsNLP.hpp> 00023 #include <pelib/AmplSolver.hpp> 00024 #include <pelib/Schedule.hpp> 00025 #include <pelib/XMLSchedule.hpp> 00026 #include <pelib/Scalar.hpp> 00027 #include <pelib/Vector.hpp> 00028 #include <pelib/Matrix.hpp> 00029 #include <pelib/Set.hpp> 00030 #include <pelib/Task.hpp> 00031 #include <pelib/Taskgraph.hpp> 00032 #include <pelib/Platform.hpp> 00033 #include <pelib/CastException.hpp> 00034 #include <pelib/ParseException.hpp> 00035 #include <pelib/AmplOutput.hpp> 00036 #include <pelib/PelibException.hpp> 00037 00038 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl; 00039 00040 using namespace std; 00041 using namespace pelib; 00042 00043 extern char _binary_pruhs_mod_start; 00044 extern char _binary_pruhs_mod_end; 00045 extern char _binary_pruhs_run_start; 00046 extern char _binary_pruhs_run_end; 00047 00048 extern char _binary_pruhs_rescale_mod_start; 00049 extern char _binary_pruhs_rescale_mod_end; 00050 extern char _binary_pruhs_rescale_run_start; 00051 extern char _binary_pruhs_rescale_run_end; 00052 00053 PruhsNLP::PruhsNLP(bool showOutput, bool showError) 00054 { 00055 param.insert(new Scalar<float>("alpha", 3)); 00056 this->showError = showError; 00057 this->showOutput = showOutput; 00058 } 00059 00060 PruhsNLP::PruhsNLP(const Algebra ¶m, bool showOutput, bool showError) 00061 { 00062 this->param = param; 00063 this->showError = showError; 00064 this->showOutput = showOutput; 00065 } 00066 00067 PruhsNLP::PruhsNLP(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, bool showOutput, bool showError) 00068 { 00069 this->taskgraph = tg; 00070 this->platform = pt; 00071 this->param = param; 00072 this->showError = showError; 00073 this->showOutput = showOutput; 00074 } 00075 00076 Schedule 00077 PruhsNLP::schedule(const Taskgraph &tg, const Platform &pt, std::map<const string, double>& stats) const 00078 { 00079 return schedule(tg, pt, this->param, stats); 00080 } 00081 00082 Schedule 00083 PruhsNLP::schedule(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, std::map<const string, double>& stats) const 00084 { 00085 // Add default values, if necessary 00086 Algebra p = param; 00087 if(p.find<Scalar<float> >("alpha") == NULL) 00088 { 00089 p.insert(new Scalar<float>("alpha", 3)); 00090 } 00091 00092 // Build input collection 00093 map<const string, const Algebra> data; 00094 data.insert(pair<const string, const Algebra>(string("platform.dat"), pt.buildAlgebra())); 00095 data.insert(pair<const string, const Algebra>(string("parameters.dat"), p)); 00096 00097 // Save and remove name vector from data 00098 Algebra taskgraph = tg.buildAlgebra(pt); 00099 const Vector<int, string> *name_ptr = taskgraph.find<Vector<int, string> >("name"); 00100 if(name_ptr == NULL) 00101 { 00102 throw PelibException("Missing tasks' name vector from taskgraph conversion to Algebra record"); 00103 } 00104 Vector<int, string> name(*name_ptr); 00105 taskgraph.remove("name"); 00106 data.insert(pair<const string, const Algebra>(string("taskgraph.dat"), taskgraph)); 00107 00108 // Build model and run scripts input streams 00109 stringstream model(string(&_binary_pruhs_mod_start, &_binary_pruhs_mod_end)); 00110 stringstream run(string(&_binary_pruhs_run_start, &_binary_pruhs_run_end)); 00111 00112 // Run the solver for the scheduling phase 00113 const Algebra *solution = AmplSolver(model, string("model.mod"), run, data, this->showOutput, this->showError).solve(stats); 00114 if(stats.find("feasible")->second != 0) 00115 { 00116 stats.erase(stats.find("feasible")); 00117 map<const string, double>::iterator ii = stats.find("time"); 00118 double pruhs_time = 0; 00119 if(ii != stats.end()) 00120 { 00121 pruhs_time = ii->second; 00122 } 00123 00124 data = map<const string, const Algebra>(); 00125 data.insert(pair<const string, const Algebra>(string("input.dat"), *solution)); 00126 delete solution; 00127 00128 stringstream rescale_model(string(&_binary_pruhs_rescale_mod_start, &_binary_pruhs_rescale_mod_end)); 00129 stringstream rescale_run(string(&_binary_pruhs_rescale_run_start, &_binary_pruhs_rescale_run_end)); 00130 solution = AmplSolver(rescale_model, string("model.mod"), rescale_run, data, this->showOutput, this->showError).solve(stats); 00131 Algebra alg = Schedule::addStartTime(*solution, tg, pt); 00132 00133 // Insert back name vector 00134 alg.insert(new Vector<int, string>(name)); 00135 p = alg.merge(pt.buildAlgebra()); 00136 00137 ii = stats.find("time"); 00138 if(ii != stats.end()) 00139 { 00140 double time = ii->second; 00141 stats.erase(ii); 00142 stats.insert(pair<const string, double>("time_schedule", pruhs_time)); 00143 stats.insert(pair<const string, double>("time_rescale", time)); 00144 stats.insert(pair<const string, double>("time_global", pruhs_time + time)); 00145 } 00146 if(stats.find("feasible")->second != 0) 00147 { 00148 return Schedule("Pruhs NLP", tg.getName(), p); 00149 } 00150 else 00151 { 00152 return Schedule("Pruhs NLP", tg.getName(), Schedule::table()); 00153 } 00154 } 00155 else 00156 { 00157 return Schedule("Pruhs NLP", tg.getName(), Schedule::table()); 00158 } 00159 } 00160 00161 const Algebra* 00162 PruhsNLP::solve() const 00163 { 00164 map<const string, double> stats; 00165 return new Algebra(schedule(this->taskgraph, this->platform, this->param, stats).buildAlgebra()); 00166 } 00167 00168 const Algebra* 00169 PruhsNLP::solve(map<const string, double> &stats) const 00170 { 00171 return new Algebra(schedule(this->taskgraph, this->platform, this->param, stats).buildAlgebra()); 00172 } 00173 00174 std::string 00175 PruhsNLP::getShortDescription() const 00176 { 00177 float alpha = this->param.find<Scalar<float> >("alpha")->getValue(); 00178 stringstream ss; 00179 00180 std::streamsize p = ss.precision(); 00181 ss.precision(4); 00182 ss << "Pruhs-NLP." << "(a=" << alpha << ")"; 00183 ss.precision(p); 00184 00185 return ss.str(); 00186 } 00187 00188 #ifdef __cplusplus 00189 extern "C" { 00190 #endif 00191 00192 enum config_src {BINARY, ORGAN, TASKGRAPH}; 00193 00194 struct args 00195 { 00196 double alpha; 00197 size_t fin; 00198 bool showError, showOutput; 00199 00200 }; 00201 typedef struct args args_t; 00202 00203 static args_t 00204 parse(char **args) 00205 { 00206 args_t out; 00207 out.showError = false; 00208 out.showOutput = false; 00209 out.alpha = 3; 00210 00211 for(; args[0] != NULL; args++) 00212 { 00213 if(strcmp(args[0], "--show-stdout") == 0) 00214 { 00215 out.showOutput = true; 00216 continue; 00217 } 00218 if(strcmp(args[0], "--show-stderr") == 0) 00219 { 00220 out.showError = true; 00221 continue; 00222 } 00223 if(strcmp(args[0], "--alpha") == 0) 00224 { 00225 args++; 00226 stringstream str(args[0]); 00227 str >> out.alpha; 00228 continue; 00229 } 00230 } 00231 00232 return out; 00233 } 00234 00235 const pelib::Schedule* 00236 pelib_schedule(const pelib::Taskgraph &tg, const pelib::Platform &pt, size_t argc, char **argv, map<const string, double>& statistics) 00237 { 00238 args_t args = parse(argv); 00239 Algebra param; 00240 param.insert(new Scalar<float>("alpha", args.alpha)); 00241 00242 // Convert solver output to general schedule 00243 Schedule *sched; 00244 sched = new Schedule(PruhsNLP(param, args.showOutput, args.showError).schedule(tg, pt, statistics)); 00245 00246 return sched; 00247 } 00248 00249 string 00250 pelib_description(size_t argc, char **argv) 00251 { 00252 args_t args = parse(argv); 00253 Algebra param; 00254 param.insert(new Scalar<float>("alpha", args.alpha)); 00255 00256 // Convert solver output to general schedule 00257 string desc; 00258 desc = PruhsNLP(param, args.showOutput, args.showError).getShortDescription(); 00259 00260 return desc; 00261 } 00262 00263 void 00264 pelib_delete(pelib::Schedule *sched) 00265 { 00266 delete sched; 00267 } 00268 00269 #ifdef __cplusplus 00270 } 00271 #endif 00272 00273