00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "GeneticAlgorithm.h"
00052
00053 namespace DREAM
00054 {
00055
00056 std::ostream& operator<< (std::ostream& out, DREAM::Solution& solution)
00057 {
00058 TASK_AVLTREE::iterator task_iter;
00059 out << "f:" << solution.fitness_;
00060 for (task_iter = solution.task_avltree_.begin ();
00061 task_iter != solution.task_avltree_.end (); ++task_iter)
00062 {
00063 out << " " << task_iter->second->subpriority ();
00064 }
00065 out << "\n";
00066 return out;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075 Solution::Solution (DREAM::System* system_ptr)
00076 : copy_ (false)
00077 {
00078 system_ptr_ = system_ptr;
00079 system_ptr->visitor_task_avltree (&task_avltree_);
00080 }
00081
00082 Solution::~Solution ()
00083 {
00084 if (copy_)
00085 task_avltree_.destroy ();
00086 }
00087
00088 bool Solution::deterministic ()
00089 {
00090 std::map<uint, uint> subpriority_map;
00091 std::map<uint, uint>::iterator uint_iter;
00092 TASK_AVLTREE::iterator task_iter;
00093
00094 for (task_iter = task_avltree_.begin ();
00095 task_iter != task_avltree_.end (); ++task_iter)
00096 {
00097 uint_iter = subpriority_map.find (task_iter->second->subpriority ());
00098 if (uint_iter != subpriority_map.end ())
00099 return false;
00100
00101 subpriority_map.insert (std::pair<uint, uint> (task_iter->second->subpriority (), 0));
00102 }
00103
00104 return true;
00105 }
00106
00107 double Solution::fitness (bool verbose, bool deterministic, double* endtoend)
00108 {
00109 double score = 0.0, priority_score, subpriority_score;
00110 DREAM::TASK_AVLTREE error_avltree;
00111
00112 system_ptr_->visitor_update_task_avltree (&task_avltree_);
00113 system_ptr_->reset ();
00114 system_ptr_->simulate (verbose, deterministic, endtoend);
00115
00116 system_ptr_->visitor_error_avltree (&error_avltree);
00117
00118 if (error_avltree.empty ())
00119 {
00120 fitness_ = 0;
00121 return 0.0;
00122 }
00123
00124 DREAM::TASK_AVLTREE::const_iterator error_iter;
00125 DREAM::Task* task_ptr;
00126
00127 for (error_iter = error_avltree.begin (); error_iter != error_avltree.end (); error_iter++)
00128 {
00129 task_ptr = error_iter->second;
00130 priority_score = task_ptr->priority () + 1;
00131 subpriority_score = task_ptr->subpriority () + 1;
00132
00133 score += (2 * (1/priority_score)) + (1/subpriority_score);
00134 }
00135
00136 fitness_ = score;
00137 return score;
00138 }
00139
00140 void Solution::generate_priorities ()
00141 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00142 throw (DREAM::Exception)
00143 #endif
00144 {
00145 if (copy_)
00146 {
00147 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00148 throw DREAM::Exception ("Solution::generate_priorities () may be called only once for a Solution.");
00149 #else
00150 return;
00151 #endif
00152 }
00153
00154
00155 copy_ = true;
00156
00157 TASK_AVLTREE::iterator iter;
00158
00159 for (iter = task_avltree_.begin (); iter != task_avltree_.end (); iter++)
00160 {
00161 iter->second = new DREAM::Task (*iter->second);
00162 }
00163
00164 uint i = 0;
00165
00166
00167 for (iter = task_avltree_.begin (); iter != task_avltree_.end (); iter++)
00168 {
00169 iter->second->subpriority (i++);
00170 }
00171
00172 regenerate_priorities ();
00173 }
00174
00175 void Solution::generate_subpriorities ()
00176 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00177 throw (DREAM::Exception)
00178 #endif
00179 {
00180 if (copy_)
00181 {
00182 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00183 throw DREAM::Exception ("Solution::generate_priorities () may be called only once for a Solution.");
00184 #else
00185 return;
00186 #endif
00187 }
00188
00189
00190 copy_ = true;
00191
00192 TASK_AVLTREE::iterator iter;
00193
00194 for (iter = task_avltree_.begin (); iter != task_avltree_.end (); iter++)
00195 {
00196 iter->second = new DREAM::Task (*iter->second);
00197 }
00198
00199 uint i = 0;
00200
00201
00202 for (iter = task_avltree_.begin (); iter != task_avltree_.end (); iter++)
00203 {
00204 iter->second->subpriority (i++);
00205 }
00206
00207 regenerate_subpriorities ();
00208 }
00209
00210 void Solution::regenerate_priorities ()
00211 {
00212
00213
00214
00215
00216 const DREAM::SCHEDULER_MAP* scheduler_map = system_ptr_->scheduler_map ();
00217 DREAM::SCHEDULER_MAP::const_iterator scheduler_iter;
00218
00219 const DREAM::THREAD_MAP* thread_map;
00220 DREAM::THREAD_MAP::const_iterator thread_iter;
00221 DREAM::TASK_AVLTREE task_avltree;
00222 DREAM::TASK_AVLTREE::iterator task_iter;
00223
00224 for (scheduler_iter = scheduler_map->begin (); scheduler_iter != scheduler_map->end (); scheduler_iter++)
00225 {
00226 thread_map = scheduler_iter->second->thread_map ();
00227
00228
00229
00230 DREAM::AVLTree<uint, const DREAM::Thread*> thread_avltree;
00231
00232 for (thread_iter = thread_map->begin (); thread_iter != thread_map->end (); thread_iter++)
00233 {
00234 thread_avltree.insert (thread_iter->first, thread_iter->second);
00235 }
00236
00237
00238
00239 scheduler_iter->second->visitor_task_avltree (&task_avltree);
00240
00241 for (task_iter = task_avltree.begin (); task_iter != task_avltree.end (); task_iter++)
00242 {
00243
00244 uint index = (uint) random (scheduler_iter->second->threadpoolsize ());
00245
00246
00247 task_iter->second->priority (task_avltree[index]->priority ());
00248 }
00249 }
00250
00251
00252 regenerate_subpriorities ();
00253 }
00254
00255 void Solution::regenerate_subpriorities ()
00256 {
00257
00258 for (uint i = 0; i < task_avltree_.size () - 1; i++)
00259 {
00260 uint rand = (uint) random (task_avltree_.size () - i) + i;
00261 uint subpriority_temp = task_avltree_[rand]->subpriority ();
00262 task_avltree_[rand]->subpriority (task_avltree_[i]->subpriority ());
00263 task_avltree_[i]->subpriority (subpriority_temp);
00264 }
00265
00266 fitness (false, true);
00267 }
00268
00269 void Solution::visitor (std::string& out)
00270 {
00271 TASK_AVLTREE::iterator task_iter;
00272
00273 for (task_iter = task_avltree_.begin ();
00274 task_iter != task_avltree_.end (); task_iter++)
00275 {
00276 out << "\tTask " << task_iter->second->id () << " p: " << task_iter->second->priority () << " sp: " << task_iter->second->subpriority () << "\n";
00277 }
00278 out << "Fitness: ";
00279
00280 char number[double_size];
00281 snprintf (number, double_size, "%.8f", fitness_);
00282 out << number << "\n";
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 GeneticOptimize::GeneticOptimize ()
00292 {
00293 }
00294
00295 void GeneticOptimize::mutate (DREAM::Solution* solution) const
00296 {
00297
00298 for (uint i = 0; i < solution->task_avltree_.size (); i++)
00299 {
00300 uint rand = (uint) random (solution->task_avltree_.size () - i) + i;
00301
00302 if ((uint) random (2) == 0)
00303 {
00304 uint subpriority_temp = solution->task_avltree_[rand]->subpriority ();
00305 solution->task_avltree_[rand]->subpriority (solution->task_avltree_[i]->subpriority ());
00306 solution->task_avltree_[i]->subpriority (subpriority_temp);
00307 }
00308 }
00309
00310 solution->fitness (false, true);
00311 }
00312
00313 void GeneticOptimize::mutate (DREAM::Solution* father, DREAM::Solution* mother, DREAM::Solution* child) const
00314 {
00315 uint i;
00316 for (i = 0; i < father->task_avltree_.size (); i++)
00317 {
00318 child->task_avltree_[i]->subpriority (father->task_avltree_[i]->subpriority ());
00319 }
00320
00321 for (i = 0; i < child->task_avltree_.size (); i++)
00322 {
00323 bool swap = false;
00324
00325 if (father->task_avltree_[i]->subpriority () ==
00326 mother->task_avltree_[i]->subpriority ())
00327 {
00328
00329 if ((uint) random (9) == 0)
00330 swap = true;
00331 }
00332 else
00333 {
00334
00335 if ((uint) random (7) > 2)
00336 swap = true;
00337 }
00338
00339 if (swap)
00340 {
00341
00342 uint j;
00343 for (j = 0; mother->task_avltree_[j]->subpriority () !=
00344 child->task_avltree_[i]->subpriority (); j++)
00345 {
00346
00347 }
00348
00349
00350 uint subpriority_temp = child->task_avltree_[i]->subpriority ();
00351 child->task_avltree_[i]->subpriority (child->task_avltree_[j]->subpriority ());
00352 child->task_avltree_[j]->subpriority (subpriority_temp);
00353 }
00354 }
00355
00356 child->fitness (false, true);
00357 }
00358
00359 void GeneticOptimize::thread_level (DREAM::System* system_ptr)
00360 {
00361 if (Option::optimization_space_ < 8)
00362 Option::optimization_space_ = 8;
00363 bool perfect = false;
00364 time_t start_time;
00365 time (&start_time);
00366
00367 std::cout << std::endl << "Thread-level scheduling optimization." << std::endl;
00368
00369
00370 system_ptr_ = system_ptr;
00371
00372 for (uint i = 0; i < Option::optimization_space_; i++)
00373 {
00374 DREAM::Solution* solution_ptr = new DREAM::Solution (system_ptr);
00375 solution_ptr->generate_subpriorities ();
00376 solution_vector_.push_back (solution_ptr);
00377 }
00378
00379 std::sort (solution_vector_.begin (), solution_vector_.end ());
00380
00381 uint e;
00382 for (e = 0; e < Option::number_of_repetitions_; e++)
00383 {
00384 uint i;
00385
00386 for (i = ((uint) solution_vector_.size () / 8*3); i < ((uint) solution_vector_.size () / 4 * 3); i++)
00387 {
00388
00389 uint father = (uint) random ((uint) solution_vector_.size () / 8 * 3);
00390 uint mother = (uint) random ((uint) solution_vector_.size () / 8 * 3);
00391 mutate (solution_vector_[father], solution_vector_[mother], solution_vector_[i]);
00392 }
00393
00394 for (i = 1; i < ((uint) solution_vector_.size () / 8 * 3); i++)
00395 {
00396
00397 mutate (solution_vector_[i]);
00398 }
00399
00400 for (i = ((uint) solution_vector_.size () / 4 * 3); i < solution_vector_.size (); i++)
00401 {
00402
00403 solution_vector_[i]->regenerate_subpriorities ();
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 std::sort (solution_vector_.begin (), solution_vector_.end (), sort_solutions ());
00421
00422
00423
00424
00425
00426 if (solution_vector_[0]->fitness_ == 0.0)
00427 {
00428 perfect = true;
00429 break;
00430 }
00431 }
00432
00433 if (perfect)
00434 std::cout << "Optimal solution found in "
00435 << e << " iterations with optimization space "
00436 << Option::optimization_space_ << ".\n";
00437 else
00438 std::cout << "Solution found in "
00439 << e << " iterations with optimization space "
00440 << Option::optimization_space_ << ".\n";
00441
00442 std::string message;
00443 solution_vector_[0]->visitor (message);
00444
00445
00446 system_ptr_->visitor_update_task_avltree (&solution_vector_[0]->task_avltree_);
00447 system_ptr_->reset ();
00448
00449
00450 std::for_each (solution_vector_.begin (), solution_vector_.end (), delete_object ());
00451
00452 solution_vector_.clear ();
00453
00454 time_t end_time;
00455 time (&end_time);
00456 uint perf = end_time - start_time;
00457 std::cout << message << "\nEnd of priority assignment optimization." << std::endl
00458 << "Analysis time: " << perf << " seconds." << std::endl;
00459 }
00460
00461 void GeneticOptimize::CPU_level (DREAM::System* system_ptr)
00462 {
00463 if (Option::optimization_space_ < 8)
00464 Option::optimization_space_ = 8;
00465 bool perfect = false;
00466 time_t start_time;
00467 time (&start_time);
00468
00469 std::cout << std::endl << "CPU-level scheduling optimization started." << std::endl;
00470
00471
00472 system_ptr_ = system_ptr;
00473
00474 for (uint i = 0; i < Option::optimization_space_; i++)
00475 {
00476 DREAM::Solution* solution_ptr = new DREAM::Solution (system_ptr);
00477 solution_ptr->generate_subpriorities ();
00478 solution_vector_.push_back (solution_ptr);
00479 }
00480
00481 std::sort (solution_vector_.begin (), solution_vector_.end ());
00482
00483 uint e;
00484 for (e = 0; e < Option::number_of_repetitions_; e++)
00485 {
00486 uint i;
00487
00488 for (i = ((uint) solution_vector_.size () / 8*3); i < ((uint) solution_vector_.size () / 4 * 3); i++)
00489 {
00490
00491 uint father = (uint) random ((uint) solution_vector_.size () / 8 * 3);
00492 uint mother = (uint) random ((uint) solution_vector_.size () / 8 * 3);
00493 mutate (solution_vector_[father], solution_vector_[mother], solution_vector_[i]);
00494 }
00495
00496 for (i = 1; i < ((uint) solution_vector_.size () / 8 * 3); i++)
00497 {
00498
00499 mutate (solution_vector_[i]);
00500 }
00501
00502 for (i = ((uint) solution_vector_.size () / 4 * 3); i < solution_vector_.size (); i++)
00503 {
00504
00505 solution_vector_[i]->regenerate_subpriorities ();
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 std::sort (solution_vector_.begin (), solution_vector_.end (), sort_solutions ());
00523
00524
00525
00526
00527
00528 if (solution_vector_[0]->fitness_ == 0.0)
00529 {
00530 perfect = true;
00531 break;
00532 }
00533 }
00534
00535 if (perfect)
00536 std::cout << "Optimal solution found in "
00537 << e << " iterations with optimization space "
00538 << Option::optimization_space_ << ".\n";
00539 else
00540 std::cout << "Solution found in "
00541 << e << " iterations with optimization space "
00542 << Option::optimization_space_ << ".\n";
00543
00544 std::string message;
00545 solution_vector_[0]->visitor (message);
00546
00547
00548 system_ptr_->visitor_update_task_avltree (&solution_vector_[0]->task_avltree_);
00549 system_ptr_->reset ();
00550
00551
00552 std::for_each (solution_vector_.begin (), solution_vector_.end (), delete_object ());
00553
00554 solution_vector_.clear ();
00555
00556 time_t end_time;
00557 time (&end_time);
00558 uint perf = end_time - start_time;
00559 std::cout << message << "\nEnd of priority assignment optimization." << std::endl
00560 << "Analysis time: " << perf << " seconds." << std::endl;
00561 }
00562
00563 };
00564