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 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 ¶m, 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 ¶m, 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