crown
1.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot 00003 00004 This file is part of Crown. 00005 00006 Crown 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 Crown 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 Crown. If not, see <http://www.gnu.org/licenses/>. 00018 00019 */ 00020 00021 00022 #include <fstream> 00023 #include <set> 00024 00025 #include <cstdlib> 00026 00027 #include <crown/allocation.h> 00028 00029 #include <pelib/AmplInput.hpp> 00030 #include <pelib/AmplOutput.hpp> 00031 #include <pelib/Vector.hpp> 00032 #include <pelib/Matrix.hpp> 00033 00034 #ifdef debug 00035 #undef debug 00036 #endif 00037 #if 0 00038 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << var << "\"" << endl; 00039 #else 00040 #define debug(var) 00041 #endif 00042 00043 using namespace pelib; 00044 using namespace std; 00045 00046 static const long long int nsec_in_sec = 1000000000; 00047 00048 static int 00049 timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y) 00050 { 00051 /* Perform the carry for the later subtraction by updating y. */ 00052 if (x->tv_nsec < y->tv_nsec) 00053 { 00054 int nsec = (y->tv_nsec - x->tv_nsec) / nsec_in_sec + 1; 00055 y->tv_nsec -= nsec_in_sec * nsec; 00056 y->tv_sec += nsec; 00057 } 00058 if (x->tv_nsec - y->tv_nsec > nsec_in_sec) 00059 { 00060 int nsec = (x->tv_nsec - y->tv_nsec) / nsec_in_sec; 00061 y->tv_nsec += nsec_in_sec * nsec; 00062 y->tv_sec -= nsec; 00063 } 00064 00065 /* Compute the time remaining to wait. tv_nsec is certainly positive. */ 00066 result->tv_sec = x->tv_sec - y->tv_sec; 00067 result->tv_nsec = x->tv_nsec - y->tv_nsec; 00068 00069 /* Return 1 if result is negative. */ 00070 return x->tv_sec < y->tv_sec; 00071 } 00072 00073 pelib::Algebra 00074 allocation_fastest(const pelib::Algebra &schedule) 00075 { 00076 Algebra input = schedule; 00077 struct timespec start, stop, total_time; 00078 00079 // Read tasks's efficiency and decide on their optimal allocation 00080 int p = (int)input.find<Scalar<float> >("p")->getValue(); 00081 int b = (int)input.find<Scalar<float> >("b")->getValue(); 00082 map<int, float> vector_tau = input.find<Vector<int, float> >("Tau")->getValues(); 00083 map<int, map<int, float> > matrix_e = input.find<Matrix<int, int, float> >("e")->getValues(); 00084 map<int, float> vector_wi; 00085 00086 clock_gettime(CLOCK_MONOTONIC, &start); 00087 00088 for(map<int, float>::iterator i = vector_tau.begin(); i != vector_tau.end(); i++) 00089 { 00090 int task = i->first; 00091 float max_efft = 0; 00092 int best_p = 0; 00093 00094 map<int, float> et = matrix_e[task]; 00095 00096 for(map<int, float>::iterator j = et.begin(); j != et.end() && j->first <= p; j++) 00097 { 00098 int p = j->first; 00099 00100 // Only proceed if p in a power of b 00101 if(pow(b, floor(log(p) / log(b))) == p) 00102 { 00103 float e = j->second; 00104 float efft = p * e; 00105 if(max_efft < efft) 00106 { 00107 max_efft = efft; 00108 best_p = p; 00109 } 00110 } 00111 } 00112 vector_wi.insert(pair<int, float>(task, best_p)); 00113 } 00114 00115 clock_gettime(CLOCK_MONOTONIC, &stop); 00116 timespec_subtract(&total_time, &stop, &start); 00117 00118 Scalar<float> *param_time = new Scalar<float>("_total_solve_elapsed_time", (total_time.tv_sec * nsec_in_sec + total_time.tv_nsec) / (float)nsec_in_sec); 00119 input.insert(param_time); 00120 00121 Vector<int, float> *wi = new Vector<int, float>("wi", vector_wi); 00122 input.insert(wi); 00123 00124 return input; 00125 } 00126 00127 Algebra 00128 allocation_random(const Algebra &schedule) 00129 { 00130 Algebra input = schedule; 00131 00132 struct timespec start, stop, total_time; 00133 00134 // Read tasks's efficiency and decide on their optimal allocation 00135 int b = (int)input.find<Scalar<float> >("b")->getValue(); 00136 int L = (int)(log(input.find<Scalar<float> >("p")->getValue()) / log(b)); 00137 map<int, float> vector_Wi = input.find<Vector<int, float> >("Wi")->getValues(); 00138 map<int, float> vector_wi; 00139 00140 clock_gettime(CLOCK_MONOTONIC, &start); 00141 00142 for(map<int, float>::iterator i = vector_Wi.begin(); i != vector_Wi.end(); i++) 00143 { 00144 int task = i->first; 00145 int Wi = (int)i ->second; 00146 00147 Wi = (int)(log(Wi) / log(b)); 00148 Wi = Wi > L ? L : Wi; 00149 00150 vector_wi.insert(pair<int, float>(task, (float)pow((double)b, (double)(rand() % (Wi + 1))))); 00151 } 00152 00153 clock_gettime(CLOCK_MONOTONIC, &stop); 00154 timespec_subtract(&total_time, &stop, &start); 00155 Scalar<float> *param_time = new Scalar<float>("_total_solve_elapsed_time", (total_time.tv_sec * nsec_in_sec + total_time.tv_nsec) / (float)nsec_in_sec); 00156 input.insert(param_time); 00157 00158 Vector<int, float> *wi = new Vector<int, float>("wi", vector_wi); 00159 input.insert(wi); 00160 00161 return input; 00162 } 00163 00164 Algebra 00165 allocation_temin(const Algebra &schedule) 00166 { 00167 Algebra input = schedule; 00168 struct timespec start, stop, total_time; 00169 00170 // Read tasks's efficiency and decide on their optimal allocation 00171 int p = (int)input.find<Scalar<float> >("p")->getValue(); 00172 int b = (int)input.find<Scalar<float> >("b")->getValue(); 00173 map<int, float> vector_tau = input.find<Vector<int, float> >("Tau")->getValues(); 00174 map<int, map<int, float> > matrix_e = input.find<Matrix<int, int, float> >("e")->getValues(); 00175 map<int, float> vector_wi; 00176 00177 // Extract the global threshold scalar, if any, or build one 00178 const Scalar<float> *gemin = input.find<Scalar<float> >("gemin"); 00179 if(gemin == NULL) 00180 { 00181 gemin = new Scalar<float>("gemin", 0.5); 00182 input.insert(gemin); 00183 delete gemin; 00184 gemin = input.find<Scalar<float> >("gemin"); 00185 } 00186 00187 // Extract the threshold vector, if any, or build one 00188 const Vector<int, float> *temin = input.find<Vector<int, float> >("temin"); 00189 if(temin == NULL) 00190 { 00191 map<int, float> t; 00192 for(map<int, float>::iterator iter = vector_wi.begin(); iter != vector_wi.end(); iter++) 00193 { 00194 //cerr << "Task " << iter->first << ", efficiency = " << global_threshold->getValue() << endl; 00195 t.insert(pair<int, float>(iter->first, gemin->getValue())); 00196 } 00197 00198 temin = new Vector<int, float>("temin", t); 00199 input.insert(temin); 00200 delete temin; 00201 temin = input.find<Vector<int, float> >("temin"); 00202 } 00203 map<int, float> map_temin = temin->getValues(); 00204 00205 clock_gettime(CLOCK_MONOTONIC, &start); 00206 00207 for(map<int, float>::iterator i = vector_tau.begin(); i != vector_tau.end(); i++) 00208 { 00209 int task = i->first; 00210 float max_efft = 0; 00211 int best_p = 0; 00212 float emin = map_temin[task]; 00213 //cerr << "# Task " << task << "; emin = " << emin << endl; 00214 00215 map<int, float> et = matrix_e[task]; 00216 00217 for(map<int, float>::iterator j = et.begin(); j != et.end() && j->first <= p; j++) 00218 { 00219 int p = j->first; 00220 //cerr << "# Task " << task << "; p = " << p << endl; 00221 00222 // Only proceed if p in a power of b 00223 if(pow(b, floor(log(p) / log(b))) == p) 00224 { 00225 float e = j->second; 00226 float efft = p * e; 00227 //cerr << "# Task " << task << "; p = " << p << "; e = " << e << "; efft = " << efft << "; max_efft = " << max_efft << "; emin = " << emin << endl; 00228 if(max_efft < efft && e >= emin) 00229 { 00230 //cerr << "# Task " << task << "; best_p = " << p << "; max_efft = " << efft << endl; 00231 max_efft = efft; 00232 best_p = p; 00233 } 00234 } 00235 } 00236 vector_wi.insert(pair<int, int>(task, best_p)); 00237 } 00238 00239 clock_gettime(CLOCK_MONOTONIC, &stop); 00240 timespec_subtract(&total_time, &stop, &start); 00241 00242 Scalar<float> *param_time = new Scalar<float>("_total_solve_elapsed_time", (total_time.tv_sec * nsec_in_sec + total_time.tv_nsec) / (float)nsec_in_sec); 00243 input.insert(param_time); 00244 00245 Vector<int, float> *wi = new Vector<int, float>("wi", vector_wi); 00246 input.insert(wi); 00247 00248 cerr << "# Redoing allocation" << endl; 00249 00250 return input; 00251 } 00252 00253 Algebra 00254 allocation_gemin(const Algebra &schedule, float gemin) 00255 { 00256 Algebra input = schedule; 00257 struct timespec start, stop, total_time; 00258 00259 // Read tasks's efficiency and decide on their optimal allocation 00260 int p = (int)input.find<Scalar<float> >("p")->getValue(); 00261 int b = (int)input.find<Scalar<float> >("b")->getValue(); 00262 map<int, float> vector_tau = input.find<Vector<int, float> >("Tau")->getValues(); 00263 map<int, map<int, float> > matrix_e = input.find<Matrix<int, int, float> >("e")->getValues(); 00264 map<int, float> vector_wi; 00265 00266 clock_gettime(CLOCK_MONOTONIC, &start); 00267 00268 for(map<int, float>::iterator i = vector_tau.begin(); i != vector_tau.end(); i++) 00269 { 00270 int task = i->first; 00271 float max_efft = 0; 00272 int best_p = 0; 00273 00274 map<int, float> et = matrix_e[task]; 00275 00276 for(map<int, float>::iterator j = et.begin(); j != et.end() && j->first <= p; j++) 00277 { 00278 int p = j->first; 00279 00280 // Only proceed if p in a power of b 00281 if(pow(b, floor(log(p) / log(b))) == p) 00282 { 00283 float e = j->second; 00284 float efft = p * e; 00285 00286 //cerr << "e = " << e << "; efft = " << efft << endl; 00287 if(max_efft < efft && e >= gemin) 00288 { 00289 max_efft = efft; 00290 best_p = p; 00291 //cerr << "max_efft = " << efft << "; best p = " << p << endl; 00292 } 00293 } 00294 } 00295 vector_wi.insert(pair<int, int>(task, best_p)); 00296 } 00297 00298 clock_gettime(CLOCK_MONOTONIC, &stop); 00299 timespec_subtract(&total_time, &stop, &start); 00300 00301 Scalar<float> *param_time = new Scalar<float>("_total_solve_elapsed_time", (total_time.tv_sec * nsec_in_sec + total_time.tv_nsec) / (float)nsec_in_sec); 00302 input.insert(param_time); 00303 00304 Vector<int, float> *wi = new Vector<int, float>("wi", vector_wi); 00305 input.insert(wi); 00306 00307 return input; 00308 } 00309 00310 float 00311 allocation_fastest_complexity(const pelib::Algebra &schedule) 00312 { 00313 float n = schedule.find<Scalar<float> >("n")->getValue(); 00314 float p = schedule.find<Scalar<float> >("p")->getValue(); 00315 00316 return n * log(p); 00317 } 00318