crown  1.0.0
src/CrownAllocationFastest.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 
00015 #include <crown/allocation.h>
00016 #include <crown/mapping.h>
00017 #include <crown/scaling.h>
00018 #include <crown/crown.h>
00019 #include <crown/CrownAllocationFastest.hpp>
00020 #include <crown/CrownConfigBinary.hpp>
00021 
00022 #include <pelib/XMLSchedule.hpp>
00023 #include <pelib/AmplInput.hpp>
00024 #include <pelib/AmplOutput.hpp>
00025 #include <pelib/Vector.hpp>
00026 #include <pelib/Matrix.hpp>
00027 #include <pelib/Set.hpp>
00028 #include <pelib/GraphML.hpp>
00029 #include <pelib/Schedule.hpp>
00030 #include <pelib/Task.hpp>
00031 #include <pelib/time.h>
00032 
00033 #ifdef debug
00034 #undef debug
00035 #endif
00036 
00037 #if 10
00038 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << var << "\"" << endl;
00039 #else
00040 #define debug(var)
00041 #endif
00042 
00043 using namespace std;
00044 using namespace pelib;
00045 using namespace pelib::crown;
00046 
00047 static const long long int nsec_in_sec = 1000000000;
00048 
00049 // Group structure containing the number of the groupand its width
00050 struct Group
00051 {
00052     int number;
00053     int width;
00054 
00055     Group(int gn, int gt, int gw)
00056         {
00057             number = gn;
00058             width = gw;
00059         }
00060 };
00061 
00062 CrownAllocationFastest::CrownAllocationFastest(float gemin, bool showOutput, bool showError) : CrownAllocation(showOutput, showError)
00063 {
00064     this->gemin = gemin;
00065 }
00066 
00067 Algebra
00068 CrownAllocationFastest::allocate(const Algebra &alg, std::map<const string, double> &stats) const
00069 {
00070     Algebra input = alg;
00071     struct timespec start, stop, total_time;
00072 
00073     // Read tasks's efficiency and decide on their optimal allocation
00074     int p = (int)input.find<Scalar<float> >("p")->getValue();
00075 
00076     map<int, float> vector_tau = input.find<Vector<int, float> >("Tau")->getValues();
00077     map<int, map<int, float> > matrix_e = input.find<Matrix<int, int, float> >("e")->getValues();
00078     map<int, float> vector_wi;
00079     map<int, map<int, float> > matrix_groups = input.find<Matrix<int, int, float> >(CrownConfig::crownConfigGroups)->getValues();
00080     set<int> vector_wig = set<int>();
00081     map<int, Group*> groupmap = map<int, Group*>();
00082 
00083     // Creating the group map and setting the width
00084     for(unsigned int i = 1 ; i <= matrix_groups.size() ; ++i)
00085     {
00086         groupmap.insert(std::make_pair(i, new Group(i, 0, 0)));
00087         for(unsigned int j = 1 ; j <= matrix_groups.begin()->second.size() ; ++j)
00088         {
00089             if(matrix_groups.find(i)->second.find(j)->second) groupmap[i]->width++;
00090         }
00091     }
00092 
00093     // Creating the group queue
00094     for(map<int, Group*>::iterator it = groupmap.begin() ; it != groupmap.end() ; ++it)
00095     {
00096         if(vector_wig.find(it->second->width) == vector_wig.end())
00097         {
00098             vector_wig.insert(it->second->width);
00099         }
00100     }
00101 
00102     clock_gettime(CLOCK_MONOTONIC, &start);     
00103 
00104     for(map<int, float>::iterator i = vector_tau.begin(); i != vector_tau.end(); i++)
00105     {
00106         int task = i->first;
00107         float max_efft = 0;
00108         int best_p = 0;
00109 
00110         map<int, float> et = matrix_e[task];
00111                 
00112         for(map<int, float>::iterator j = et.begin(); j != et.end() && j->first <= p; j++)
00113         {
00114             int p = j->first;
00115 
00116             float e = j->second;
00117             float efft = p * e;
00118 
00119             if(max_efft < efft && e >= gemin && vector_wig.find(p) != vector_wig.end())
00120             {
00121                 max_efft = efft;
00122                 best_p = p;
00123             }
00124         }
00125         vector_wi.insert(pair<int, int>(task, best_p));
00126     }
00127 
00128     clock_gettime(CLOCK_MONOTONIC, &stop);
00129     pelib_timespec_subtract(&total_time, &stop, &start);
00130         
00131     stats.insert(pair<const string, double>("time", (total_time.tv_sec * nsec_in_sec + total_time.tv_nsec) / (float)nsec_in_sec));
00132 
00133     Vector<int, float> *wi = new Vector<int, float>("wi", vector_wi);
00134     input.insert(wi);
00135 
00136     return input;
00137 }
00138 
00139 Taskgraph
00140 CrownAllocationFastest::allocate(const Taskgraph &tg, const Platform &pt, const Algebra &param, const CrownConfig *config, std::map<const string, double> &stats) const
00141 {
00142     Algebra alg = tg.buildAlgebra(pt);
00143     alg = alg.merge(pt.buildAlgebra());
00144     alg = alg.merge(param);
00145     if(config == NULL)
00146     {
00147         CrownConfigBinary conf;
00148         config = &conf;
00149     }
00150     alg = alg.merge(config->configure(tg, pt, param, stats));
00151 
00152     return Taskgraph(allocate(alg, stats));
00153 }
00154 
00155 float
00156 CrownAllocationFastest::complexity(const Taskgraph &tg, const Platform &pt, const Algebra &param, const CrownConfig* config) const
00157 {
00158     Algebra alg = tg.buildAlgebra(pt);
00159     alg = alg.merge(pt.buildAlgebra());
00160     alg = alg.merge(param);
00161     if(config == NULL)
00162     {
00163         CrownConfigBinary conf;
00164         config = &conf;
00165     }
00166     std::map<const string, double> stats;
00167     alg = alg.merge(config->configure(tg, pt, param, stats));
00168 
00169     return complexity(alg);
00170 }
00171 
00172 float
00173 CrownAllocationFastest::complexity(const pelib::Algebra &schedule) const
00174 {
00175     float n = schedule.find<Scalar<float> >("n")->getValue();
00176     float p = schedule.find<Scalar<float> >("p")->getValue();
00177 
00178     return n * p;
00179 }
00180 
00181 std::string
00182 CrownAllocationFastest::getShortDescription() const
00183 {
00184     stringstream ss;
00185     std::streamsize p = ss.precision();
00186     ss.precision(4);
00187     ss << "newFast";
00188     ss.precision(p);
00189 
00190     return ss.str();
00191 }
00192 
00193 CrownAllocation*
00194 CrownAllocationFastest::clone() const
00195 {
00196     return new CrownAllocationFastest(*this);
00197 }
00198