crown  1.0.0
src/CrownScalingILP.cpp
Go to the documentation of this file.
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 &param, 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 &param, 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 &param, 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 &param, 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