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/XuILP.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_xu_mod_start; 00044 extern char _binary_xu_mod_end; 00045 extern char _binary_xu_run_start; 00046 extern char _binary_xu_run_end; 00047 00048 XuILP::XuILP(bool showOutput, bool showError) 00049 { 00050 param.insert(new Scalar<float>("alpha", 3)); 00051 this->showError = showError; 00052 this->showOutput = showOutput; 00053 } 00054 00055 XuILP::XuILP(const Algebra ¶m, bool showOutput, bool showError) 00056 { 00057 this->param = param; 00058 this->showError = showError; 00059 this->showOutput = showOutput; 00060 } 00061 00062 XuILP::XuILP(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, bool showOutput, bool showError) 00063 { 00064 this->taskgraph = tg; 00065 this->platform = pt; 00066 this->param = param; 00067 this->showError = showError; 00068 this->showOutput = showOutput; 00069 } 00070 00071 Schedule 00072 XuILP::schedule(const Taskgraph &tg, const Platform &pt, std::map<const string, double>& stats) const 00073 { 00074 return schedule(tg, pt, this->param, stats); 00075 } 00076 00077 Schedule 00078 XuILP::schedule(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, std::map<const string, double>& stats) const 00079 { 00080 // Add default values, if necessary 00081 Algebra p = param; 00082 if(p.find<Scalar<float> >("alpha") == NULL) 00083 { 00084 p.insert(new Scalar<float>("alpha", 3)); 00085 } 00086 00087 // Build input collection 00088 map<const string, const Algebra> data; 00089 data.insert(pair<const string, const Algebra>(string("platform.dat"), pt.buildAlgebra())); 00090 data.insert(pair<const string, const Algebra>(string("parameters.dat"), p)); 00091 00092 // Save and remove name vector from data 00093 Algebra taskgraph = tg.buildAlgebra(pt); 00094 const Vector<int, string> *name_ptr = taskgraph.find<Vector<int, string> >("name"); 00095 if(name_ptr == NULL) 00096 { 00097 throw PelibException("Missing tasks' name vector from taskgraph conversion to Algebra record"); 00098 } 00099 Vector<int, string> name(*name_ptr); 00100 taskgraph.remove("name"); 00101 data.insert(pair<const string, const Algebra>(string("taskgraph.dat"), taskgraph)); 00102 00103 // Build model and run scripts input streams 00104 stringstream model(string(&_binary_xu_mod_start, &_binary_xu_mod_end)); 00105 stringstream run(string(&_binary_xu_run_start, &_binary_xu_run_end)); 00106 00107 // Run the solver 00108 const Algebra *solution = AmplSolver(model, string("model.mod"), run, data, this->showOutput, this->showError).solve(stats); 00109 Algebra alg = *solution; 00110 00111 // Insert back name vector 00112 alg.insert(new Vector<int, string>(name)); 00113 p = solution->merge(pt.buildAlgebra()); 00114 map<const string, double>::iterator ii = stats.find("time"); 00115 if(ii != stats.end()) 00116 { 00117 double time = ii->second; 00118 stats.erase(ii); 00119 stats.insert(pair<const string, double>("time_schedule", time)); 00120 stats.insert(pair<const string, double>("time_global", time)); 00121 } 00122 if(stats.find("feasible")->second != 0) 00123 { 00124 return this->buildSchedule(alg, tg.getName()); 00125 } 00126 else 00127 { 00128 return Schedule("ILP Unrestricted", tg.getName(), Schedule::table()); 00129 } 00130 } 00131 00132 const Algebra* 00133 XuILP::solve() const 00134 { 00135 map<const string, double> stats; 00136 return new Algebra(schedule(this->taskgraph, this->platform, this->param, stats).buildAlgebra()); 00137 } 00138 00139 const Algebra* 00140 XuILP::solve(map<const string, double> &stats) const 00141 { 00142 return new Algebra(schedule(this->taskgraph, this->platform, this->param, stats).buildAlgebra()); 00143 } 00144 00145 std::string 00146 XuILP::getShortDescription() const 00147 { 00148 float alpha = this->param.find<Scalar<float> >("alpha")->getValue(); 00149 stringstream ss; 00150 00151 std::streamsize p = ss.precision(); 00152 ss.precision(4); 00153 ss << "XuILP." << "(a=" << alpha << ")"; 00154 ss.precision(p); 00155 00156 return ss.str(); 00157 } 00158 00159 Schedule 00160 XuILP::buildSchedule(const Algebra &in, const std::string &name) const 00161 { 00162 AmplOutput output(AmplOutput::floatHandlers()); 00163 00164 Algebra alg = in; 00165 00166 int p = alg.find<Scalar<float> >("p")->getValue(); 00167 map<int, float> degree = alg.find<Vector<int, float> >("wi")->getValues(); 00168 map<int, float> level = alg.find<Vector<int, float> >("level")->getValues(); 00169 map<int, float> time = alg.find<Vector<int, float> >("time")->getValues(); 00170 const Matrix<int, int, float> *ampl_tasks = alg.find<Matrix<int, int, float> >("tasks"); 00171 map<int, map<int, float> > tasks = ampl_tasks->getValues(); 00172 map<int, map<int, float> > schedule; 00173 00174 float cumulated_time = 0; 00175 map<int, float> level_start; 00176 for(map<int, float>::iterator i = level.begin(); i != level.end(); i++) 00177 { 00178 level_start.insert(pair<int, float>(i->first, cumulated_time)); 00179 cumulated_time += time.find(i->first)->second; 00180 } 00181 00182 map<int, float> start; 00183 for(map<int, map<int, float> >::iterator i = tasks.begin(); i != tasks.end(); i++) 00184 { 00185 start.insert(pair<int, float>(i->first, level_start.find(level.find(i->first)->second)->second)); 00186 for(int k = 0; k < p; k++) 00187 { 00188 schedule[k + 1][round(i->first)] = 0; 00189 } 00190 } 00191 00192 for(map<int, map<int, float> >::iterator i = tasks.begin(); i != tasks.end(); i++) 00193 { 00194 int offset = 0; 00195 int level = i->first; 00196 for(map<int, float>::iterator j = i->second.begin(); j != i->second.end(); j++) 00197 { 00198 if(j->second != 0) 00199 { 00200 int task = round(j->second); 00201 int wi = round(degree[task]); 00202 00203 for(int k = 0; k < wi; k++) 00204 { 00205 schedule[offset + k + 1][level] = task; 00206 } 00207 offset += wi; 00208 } 00209 } 00210 } 00211 00212 Vector<int, float> start_vector("start", start); 00213 alg.insert(&start_vector); 00214 Matrix<int, int, float> schedule_matrix("schedule", schedule); 00215 alg.insert(&schedule_matrix); 00216 Schedule sched("Xu ILP", name, alg); 00217 00218 return sched; 00219 } 00220 00221 #ifdef __cplusplus 00222 extern "C" { 00223 #endif 00224 00225 struct args 00226 { 00227 double alpha; 00228 bool showError, showOutput; 00229 00230 }; 00231 typedef struct args args_t; 00232 00233 static args_t 00234 parse(char **args) 00235 { 00236 args_t out; 00237 out.showError = false; 00238 out.showOutput = false; 00239 out.alpha = 3; 00240 00241 for(; args[0] != NULL; args++) 00242 { 00243 if(strcmp(args[0], "--show-stdout") == 0) 00244 { 00245 out.showOutput = true; 00246 continue; 00247 } 00248 if(strcmp(args[0], "--show-stderr") == 0) 00249 { 00250 out.showError = true; 00251 continue; 00252 } 00253 if(strcmp(args[0], "--alpha") == 0) 00254 { 00255 args++; 00256 stringstream str(args[0]); 00257 str >> out.alpha; 00258 continue; 00259 } 00260 } 00261 00262 return out; 00263 } 00264 00265 const pelib::Schedule* 00266 pelib_schedule(const pelib::Taskgraph &tg, const pelib::Platform &pt, size_t argc, char **argv, map<const string, double>& statistics) 00267 { 00268 args_t args = parse(argv); 00269 Algebra param; 00270 param.insert(new Scalar<float>("alpha", args.alpha)); 00271 00272 // Convert solver output to general schedule 00273 Schedule *sched; 00274 sched = new Schedule(XuILP(param, args.showOutput, args.showError).schedule(tg, pt, statistics)); 00275 00276 return sched; 00277 } 00278 00279 string 00280 pelib_description(size_t argc, char **argv) 00281 { 00282 args_t args = parse(argv); 00283 Algebra param; 00284 param.insert(new Scalar<float>("alpha", args.alpha)); 00285 00286 // Convert solver output to general schedule 00287 string desc; 00288 desc = XuILP(param, args.showOutput, args.showError).getShortDescription(); 00289 00290 return desc; 00291 } 00292 00293 void 00294 pelib_delete(pelib::Schedule *sched) 00295 { 00296 delete sched; 00297 } 00298 00299 #ifdef __cplusplus 00300 } 00301 #endif 00302 00303