crown  1.0.0
src/CrownModular.cpp
Go to the documentation of this file.
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 <pelib/Algebra.hpp>
00021 #include <pelib/Scalar.hpp>
00022 #include <pelib/AmplSolver.hpp>
00023 #include <pelib/Vector.hpp>
00024 #include <pelib/Matrix.hpp>
00025 #include <pelib/AmplInput.hpp>
00026 #include <pelib/XMLSchedule.hpp>
00027 
00028 #include <crown/CrownModular.hpp>
00029 #include <crown/CrownAllocationFastest.hpp>
00030 #include <crown/CrownMappingLTLG.hpp>
00031 #include <crown/CrownScalingHeight.hpp>
00032 #include <crown/CrownConfigBinary.hpp>
00033 #include <crown/CrownException.hpp>
00034 
00035 #include <crown/mapping.h>
00036 #include <crown/scaling.h>
00037 
00038 #ifdef debug
00039 #undef debug
00040 #endif
00041 
00042 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl;
00043 
00044 using namespace std;
00045 using namespace pelib;
00046 using namespace crown;
00047 
00048 Algebra
00049 CrownModular::solve(const Algebra &tg, const Algebra &pt, const pelib::Algebra &param, std::map<const std::basic_string<char>, double> &stats) const
00050 {
00051         Algebra input = tg;
00052         input = input.merge(pt);
00053         input = input.merge(param);
00054         input = this->alloc->allocate(input, stats);
00055         input = this->mapping->map(input, stats);
00056         input = this->scaling->scale(input, stats);
00057         return input;
00058 }
00059 
00060 Schedule
00061 CrownModular::schedule(const Taskgraph &tg, const Platform &pt, const Algebra &param, map<const string, double> &statistics) const
00062 {
00063         // Take task names apart
00064         Algebra taskgraph = tg.buildAlgebra(pt);
00065         Vector<int, string> name = *taskgraph.find<Vector<int, string> >("name");
00066         taskgraph.remove("name");
00067 
00068         Algebra p = param.merge(config->configure(tg, pt, param, statistics));
00069         p = solve(taskgraph, pt.buildAlgebra(), p, statistics);
00070 
00071         float time = 0;
00072         map<const string, double>::iterator i = statistics.find("time_allocation");
00073         if(i != statistics.end())
00074         {
00075                 time += i->second;
00076         }
00077         i = statistics.find("time_mapping");
00078         if(i != statistics.end())
00079         {
00080                 time += i->second;
00081         }
00082         i = statistics.find("time_scaling");
00083         if(i != statistics.end())
00084         {
00085                 time += i->second;
00086         }
00087         i = statistics.find("time_global");
00088         if(i != statistics.end())
00089         {
00090                 statistics.erase(i);
00091         }
00092         statistics.insert(pair<const string, double>("time_global", time));
00093 
00094         // Put back task names
00095         p.insert(new Vector<int, string>(name));
00096 
00097         float m = p.find<Scalar<float> >("m")->getValue();
00098         float M = p.find<Scalar<float> >("M")->getValue();
00099         if(m >= 0 || M <= 0)
00100         {
00101                 statistics.insert(pair<const string, double>("feasible", 1));
00102                 p = crownToSchedule(p);
00103                 p = Schedule::addStartTime(p, tg, pt);
00104                 Schedule sched(getShortDescription(), tg.getName(), p);
00105                 // for(map<string, double>::iterator it = statistics.begin() ; it != statistics.end() ; ++it)
00106                 // {
00107                 //       debug(it->first);
00108                 //       debug(it->second);
00109                 // }
00110                 return sched;
00111         }
00112         else
00113         {
00114                 statistics.insert(pair<const string, double>("feasible", 0));
00115                 return Schedule(this->getShortDescription(), tg.getName(), Schedule::table());
00116         }
00117 }
00118 
00119 Schedule
00120 CrownModular::schedule(const Taskgraph &tg, const Platform &pt, map<const string, double> &statistics) const
00121 {
00122         return schedule(tg, pt, param, statistics);
00123 }
00124 
00125 float
00126 CrownModular::complexity(const Algebra &problem) const
00127 {
00128         return CrownScheduler::complexity(tg, pt, param) + this->alloc->complexity(problem) + this->mapping->complexity(problem) + this->scaling->complexity(problem);
00129 }
00130 
00131 float
00132 CrownModular::complexity(const Taskgraph &tg, const Platform &pt, const Algebra &param) const
00133 {
00134         return CrownScheduler::complexity(tg,pt, param) + this->alloc->complexity(tg, pt, param, this->config) + this->mapping->complexity(tg, pt, param, this->config) + this->scaling->complexity(tg, pt, param, this->config);
00135 }
00136 
00137 CrownModular*
00138 CrownModular::clone() const
00139 {
00140         return new CrownModular(*this);
00141 }
00142 
00143 void
00144 CrownModular::initialize(const CrownAllocation *alloc, const CrownMapping *mapping, const CrownScaling *scaling)
00145 {
00146         if(alloc == NULL)
00147         {
00148                 this->alloc = new CrownAllocationFastest(0, showOutput, showError);
00149         }
00150         else
00151         {
00152                 this->alloc = alloc->clone();
00153         }
00154 
00155         if(mapping == NULL)
00156         {
00157                 this->mapping = new CrownMappingLTLG(config, alloc, showOutput, showError);
00158         }
00159         else
00160         {
00161                 this->mapping = mapping->clone();
00162         }
00163 
00164         if(scaling == NULL)
00165         {
00166                 this->scaling = new CrownScalingHeight(config, alloc, mapping, showOutput, showError);
00167         }
00168         else
00169         {
00170                 this->scaling = scaling->clone();
00171         }
00172 }
00173 
00174 CrownModular::CrownModular(const CrownConfig *config, const CrownAllocation *alloc, const CrownMapping *mapping, const CrownScaling *scaling, bool showOutput, bool showError) : CrownScheduler(config, showOutput, showError)
00175 {
00176         initialize(alloc, mapping, scaling);
00177 
00178         // TODO: restore arbitrary configuration
00179         //delete this->config;
00180         //this->config = new CrownConfigBinary();
00181 }
00182 
00183 CrownModular::CrownModular(const Algebra &param, const CrownConfig *config, const CrownAllocation *alloc, const CrownMapping *mapping, const CrownScaling *scaling, bool showOutput, bool showError) : CrownScheduler(config, showOutput, showError)
00184 {
00185         initialize(alloc, mapping, scaling);
00186 
00187         // TODO: restore arbitrary configuration
00188         //delete this->config;
00189         //this->config = new CrownConfigBinary();
00190 }
00191 
00192 CrownModular::CrownModular(const Taskgraph &tg, const Platform &pt, const Algebra &param, const CrownConfig*, const CrownAllocation *alloc, const CrownMapping *mapping, const CrownScaling *scaling, bool showOutput, bool showError) : CrownScheduler(config, showOutput, showError)
00193 {
00194         initialize(alloc, mapping, scaling);
00195 
00196         // TODO: restore arbitrary configuration
00197         //delete this->config;
00198         //this->config = new CrownConfigBinary();
00199 }
00200 
00201 CrownModular::CrownModular(const CrownModular &src) : CrownScheduler(src.tg, src.pt, src.param, src.config, src.showOutput, src.showError)
00202 {
00203         initialize(src.alloc, src.mapping, src.scaling);
00204 
00205         // TODO: restore arbitrary configuration
00206         //delete this->config;
00207         //this->config = new CrownConfigBinary();
00208 }
00209 
00210 CrownModular::~CrownModular()
00211 {
00212         delete this->alloc;
00213         delete this->mapping;
00214         delete this->scaling;
00215 }
00216 
00217 string
00218 CrownModular::getShortDescription() const
00219 {
00220         float alpha = this->param.find<Scalar<float> >("alpha")->getValue();
00221         float kappa = this->param.find<Scalar<float> >("kappa")->getValue();
00222         float eta = this->param.find<Scalar<float> >("eta")->getValue();
00223         float zeta = this->param.find<Scalar<float> >("zeta")->getValue();
00224         stringstream ss;
00225 
00226         const CrownConfig *config = this->config;
00227         if(config == NULL)
00228         {
00229                 config = getDefaultConfig();
00230         }
00231 
00232         std::streamsize p = ss.precision();
00233         ss.precision(4);
00234         string alloc = this->alloc->getShortDescription();
00235         string mapping = this->mapping->getShortDescription();
00236         string scaling = this->scaling->getShortDescription();
00237         string conf = this->config->getShortDescription();
00238         ss << "Cr-" << alloc << "-" << mapping << "-" << scaling << "-" << conf << "(a=" << alpha << ",k=" << kappa << ",e=" << eta << ",z=" << zeta << ")";
00239         ss.precision(p);
00240 
00241         if(this->config == NULL)
00242         {
00243                 delete config;
00244         }
00245 
00246         return ss.str();
00247 }
00248 
00249 const Algebra*
00250 CrownModular::solve() const
00251 {
00252         map<const string, double> statistics;
00253         Algebra *sol = new Algebra(schedule(tg, pt, param, statistics).buildAlgebra());
00254         return sol;
00255 }
00256 
00257 const Algebra*
00258 CrownModular::solve(map<const string, double> &statistics) const
00259 {
00260         Algebra *sol = new Algebra(schedule(tg, pt, param, statistics).buildAlgebra());
00261         return sol;
00262 }
00263