crown
1.0.0
|
00001 // The following definitions might be exchanged for others, 00002 // when integrating the following code into the framework. 00003 // The code implements a greedy heuristic to loadbalance the tasks 00004 // over cores such that the l2-norm of the load vector is minimized. 00005 // This should also minimize the l3-norm of the load vector. 00006 // J. Keller, July 14, 2014 00007 00008 #include <stdio.h> 00009 #include <stdlib.h> 00010 #include <string.h> 00011 #include <math.h> 00012 #include <iostream> 00013 #include <sstream> 00014 #include <fstream> 00015 #include <cstdlib> 00016 #include <set> 00017 #include <map> 00018 00019 #include <crown/CrownScalingILP.hpp> 00020 #include <crown/CrownConfigBinary.hpp> 00021 00022 #include <pelib/AmplSolver.hpp> 00023 #include <pelib/Scalar.hpp> 00024 #include <pelib/Vector.hpp> 00025 #include <pelib/Matrix.hpp> 00026 #include <pelib/Set.hpp> 00027 #include <pelib/Schedule.hpp> 00028 #include <pelib/Algebra.hpp> 00029 00030 #ifdef debug 00031 #undef debug 00032 #endif 00033 00034 #if 01 00035 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << var << "\"" << endl; 00036 #else 00037 #define debug(var) 00038 #endif 00039 00040 using namespace std; 00041 using namespace pelib; 00042 using namespace pelib::crown; 00043 00044 extern char _binary_scaling_mod_start; 00045 extern char _binary_scaling_mod_end; 00046 extern char _binary_scaling_run_start; 00047 extern char _binary_scaling_run_end; 00048 00049 CrownScalingILP::CrownScalingILP(const CrownConfig *config, const CrownAllocation *alloc, const CrownMapping *mapping, bool showOutput, bool showError) : CrownScaling(config, alloc, mapping, showOutput, showError) 00050 { 00051 /* Do nothing else */ 00052 } 00053 00054 CrownScalingILP::CrownScalingILP(const Algebra ¶m, const CrownConfig *config, const CrownAllocation *alloc, const CrownMapping *mapping, bool showOutput, bool showError): CrownScaling(param, config, alloc, mapping, showOutput, showError) 00055 { 00056 /* Do nothing else */ 00057 } 00058 00059 CrownScalingILP::CrownScalingILP(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, const CrownConfig *config, const CrownAllocation *alloc, const CrownMapping *mapping, bool showOutput, bool showError): CrownScaling(tg, pt, param, config, alloc, mapping, showOutput, showError) 00060 { 00061 /* Do nothing else */ 00062 } 00063 00064 Algebra 00065 CrownScalingILP::scale(const Algebra &alg, std::map<const string, double> &stats) const 00066 { 00067 // Build input collection 00068 std::map<const string, const Algebra> data; 00069 data.insert(pair<const string, const Algebra>("parameters.dat", alg)); 00070 00071 // Build model and run scripts input streams 00072 stringstream model(string(&_binary_scaling_mod_start, &_binary_scaling_mod_end)); 00073 stringstream run(string(&_binary_scaling_run_start, &_binary_scaling_run_end)); 00074 00075 // Run the solver 00076 const Algebra *solution = AmplSolver(model, string("model.mod"), run, data, showOutput, showError).solve(stats); 00077 00078 // Insert back tasks' names 00079 std::map<const string, double>::iterator ii = stats.find("time"); 00080 if(ii != stats.end()) 00081 { 00082 double time = ii->second; 00083 stats.erase(ii); 00084 stats.insert(pair<const string, double>("time_scaling", time)); 00085 } 00086 00087 Algebra sol = *solution; 00088 delete solution; 00089 std::map<const string, double>::iterator jj = stats.find("feasible"); 00090 if(jj != stats.end()) 00091 { 00092 if(jj->second > 0) 00093 { 00094 Scalar<float> m("m", 1); 00095 sol.insert(&m); 00096 } 00097 else 00098 { 00099 Scalar<float> m("m", -1); 00100 sol.insert(&m); 00101 } 00102 } 00103 00104 return sol; 00105 } 00106 00107 Schedule 00108 CrownScalingILP::scale(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, const CrownConfig *config, std::map<const string, double> &stats) const 00109 { 00110 Algebra alg = tg.buildAlgebra(pt); 00111 alg = alg.merge(pt.buildAlgebra()); 00112 alg = alg.merge(param); 00113 if(config == NULL) 00114 { 00115 CrownConfigBinary conf; 00116 config = &conf; 00117 } 00118 alg = alg.merge(config->configure(tg, pt, param, stats)); 00119 alg = Schedule::addStartTime(alg, tg, pt); 00120 00121 Schedule sched(getShortDescription(), tg.getName(), alg); 00122 00123 return sched; 00124 } 00125 00126 float 00127 CrownScalingILP::complexity(const Taskgraph &tg, const Platform &pt, const Algebra ¶m, const CrownConfig* config) const 00128 { 00129 Algebra alg = tg.buildAlgebra(pt); 00130 alg = alg.merge(pt.buildAlgebra()); 00131 alg = alg.merge(param); 00132 if(config == NULL) 00133 { 00134 CrownConfigBinary conf; 00135 config = &conf; 00136 } 00137 std::map<const string, double> stats; 00138 alg = alg.merge(config->configure(tg, pt, param, stats)); 00139 00140 return complexity(alg); 00141 } 00142 00143 float 00144 CrownScalingILP::complexity(const pelib::Algebra &input) const 00145 { 00146 double n = input.find<Scalar<float> >("n")->getValue(); 00147 double p = input.find<Scalar<float> >("p")->getValue(); 00148 set<float> F = input.find<Set<float> >("F")->getValues(); 00149 00150 return n * p * (1 + F.size() * log(n)); 00151 } 00152 00153 std::string 00154 CrownScalingILP::getShortDescription() const 00155 { 00156 stringstream ss; 00157 std::streamsize p = ss.precision(); 00158 ss.precision(4); 00159 ss << "ILP"; 00160 ss.precision(p); 00161 00162 return ss.str(); 00163 } 00164 00165 CrownScaling* 00166 CrownScalingILP::clone() const 00167 { 00168 return new CrownScalingILP(*this); 00169 } 00170