pelib
2.0.0
|
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 00021 #include <pelib/Platform.hpp> 00022 #include <pelib/Core.hpp> 00023 #include <pelib/DummyCore.hpp> 00024 00025 #include <pelib/Scalar.hpp> 00026 #include <pelib/Set.hpp> 00027 #include <pelib/ParseException.hpp> 00028 #include <pelib/CastException.hpp> 00029 00030 #define debug(var) std::cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << std::endl; 00031 00032 using namespace std; 00033 00034 namespace pelib 00035 { 00036 Platform::Platform() 00037 { 00038 set<float> f; 00039 f.insert(1); 00040 Core *core = new DummyCore(f, 1); 00041 this->cores.insert(core); 00042 island isl; 00043 isl.insert(core); 00044 main.insert(island(isl)); 00045 shared.insert(island(isl)); 00046 priv.insert(island(isl)); 00047 voltage.insert(island(isl)); 00048 freq.insert(island(isl)); 00049 } 00050 00051 Platform::Platform(const island &cores) 00052 { 00053 //set<const Core*> shared; 00054 for(set<const Core*>::const_iterator i = cores.begin(); i != cores.end(); i++) 00055 { 00056 Core *core = (*i)->clone(); 00057 this->cores.insert(core); 00058 island isl; 00059 isl.insert(core); 00060 //shared.insert(core); 00061 00062 // Each core is its own Platform::island of anything 00063 this->shared.insert(island(isl)); 00064 this->main.insert(island(isl)); 00065 this->priv.insert(island(isl)); 00066 this->voltage.insert(island(isl)); 00067 this->freq.insert(island(isl)); 00068 } 00069 //this->shared.insert(set<const Core*>(shared)); 00070 } 00071 00072 Platform::Platform(const island& cores, const islands &shared, const islands &main, const islands &priv, const islands &voltage, const islands &freq) 00073 { 00074 this->cores = cores; 00075 this->shared = shared; 00076 this->main = main; 00077 this->priv = priv; 00078 this->voltage = voltage; 00079 this->freq = freq; 00080 } 00081 00082 Platform::Platform(size_t p, const Core* ref) 00083 { 00084 //set<const Core*> shared; 00085 for(size_t i = 0; i < p; i++) 00086 { 00087 Core *core = ref->clone(); 00088 this->cores.insert(core); 00089 island isl; 00090 isl.insert(core); 00091 //shared.insert(core); 00092 00093 // Each core is its own Platform::island of anything 00094 this->shared.insert(island(isl)); 00095 this->main.insert(island(isl)); 00096 this->priv.insert(island(isl)); 00097 this->voltage.insert(island(isl)); 00098 this->freq.insert(island(isl)); 00099 } 00100 //this->shared.insert(shared); 00101 } 00102 00103 void 00104 Platform::copy(const Platform *arch) 00105 { 00106 this->cores.clear(); 00107 for(island::const_iterator i = arch->getCores().begin(); i != arch->getCores().end(); i++) 00108 { 00109 this->cores.insert((*i)->clone()); 00110 } 00111 00112 this->shared.clear(); 00113 this->main.clear(); 00114 this->priv.clear(); 00115 this->voltage.clear(); 00116 this->freq.clear(); 00117 00118 for(islands::const_iterator i = arch->getSharedMemoryIslands().begin(); i != arch->getSharedMemoryIslands().end(); i++) 00119 { 00120 island isl; 00121 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00122 { 00123 isl.insert(this->getCore(arch->getCoreId(*arch->getCores().find(*j)))); 00124 } 00125 00126 this->shared.insert(isl); 00127 } 00128 00129 for(islands::const_iterator i = arch->getMainMemoryIslands().begin(); i != arch->getMainMemoryIslands().end(); i++) 00130 { 00131 island isl; 00132 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00133 { 00134 isl.insert(this->getCore(arch->getCoreId(*arch->getCores().find(*j)))); 00135 } 00136 00137 this->main.insert(isl); 00138 } 00139 00140 for(islands::const_iterator i = arch->getPrivateMemoryIslands().begin(); i != arch->getPrivateMemoryIslands().end(); i++) 00141 { 00142 island isl; 00143 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00144 { 00145 isl.insert(this->getCore(arch->getCoreId(*arch->getCores().find(*j)))); 00146 } 00147 00148 this->priv.insert(isl); 00149 } 00150 00151 for(islands::const_iterator i = arch->getVoltageIslands().begin(); i != arch->getVoltageIslands().end(); i++) 00152 { 00153 island isl; 00154 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00155 { 00156 isl.insert(this->getCore(arch->getCoreId(*arch->getCores().find(*j)))); 00157 } 00158 00159 this->voltage.insert(isl); 00160 } 00161 00162 for(islands::const_iterator i = arch->getFrequencyIslands().begin(); i != arch->getFrequencyIslands().end(); i++) 00163 { 00164 island isl; 00165 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00166 { 00167 isl.insert(this->getCore(arch->getCoreId(*arch->getCores().find(*j)))); 00168 } 00169 00170 this->freq.insert(isl); 00171 } 00172 } 00173 00174 Platform::Platform(const Platform *arch) 00175 { 00176 copy(arch); 00177 } 00178 00179 Platform::Platform(const Platform &pt) 00180 { 00181 copy(&pt); 00182 } 00183 00184 Platform::Platform(const Algebra &arch) 00185 { 00186 const Scalar<float> *scalar_p = arch.find<Scalar<float> >("p"); 00187 const Scalar<float> *scalar_fin = arch.find<Scalar<float> >("Fin"); 00188 //const Scalar<float> *scalar_sin = arch.find<Scalar<float> >("Sin"); 00189 const Scalar<float> *f_unit = arch.find<Scalar<float> >("Funit"); 00190 const Set<float> *set_F = arch.find<Set<float> >("F"); 00191 const Set<float> *set_Fi = arch.find<Set<float> >("Fi"); 00192 const Set<float> *set_Si = arch.find<Set<float> >("Si"); 00193 00194 if(scalar_p == NULL || set_F == NULL || f_unit == NULL || set_Fi == NULL || scalar_fin == NULL) 00195 { 00196 throw ParseException(std::string("Missing core number scalar \"p\", frequency set \"F\", frequency unit \"Funit\" or frequency islands number \"Fin\" and details set \"Fi[1..Fin]\" in input.")); 00197 } 00198 00199 // Create empty frequency islands, if a description is given 00200 vector<island> frequency; 00201 if(set_Fi != NULL) 00202 { 00203 Set<float>::SetOfSetsType Fi = set_Fi->getSubsets(); 00204 for(Set<float>::SetOfSetsType::iterator i = Fi.begin(); i != Fi.end(); i++) 00205 { 00206 frequency.push_back(island()); 00207 } 00208 } 00209 00210 // Create empty frequency islands, if a description is given 00211 vector<island> shared; 00212 if(set_Si != NULL) 00213 { 00214 Set<float>::SetOfSetsType Si = set_Si->getSubsets(); 00215 for(Set<float>::SetOfSetsType::iterator i = Si.begin(); i != Si.end(); i++) 00216 { 00217 shared.push_back(island()); 00218 } 00219 } 00220 00221 for(size_t i = 0; i < scalar_p->getValue(); i++) 00222 { 00223 const Core *core = new DummyCore(i + 1, set_F->getValues(), f_unit == NULL ? 1 : f_unit->getValue()); 00224 this->cores.insert(core); 00225 island isl; 00226 isl.insert(core); 00227 00228 // Each core is its own shared mamory island 00229 main.insert(island(isl)); 00230 00231 // If frequency islands are provided, then insert core in the right island 00232 if(set_Fi != NULL) 00233 { 00234 size_t core_id = i + 1; 00235 vector<Platform::island>::iterator jj = frequency.begin(); 00236 00237 // Find the frequency island that holds this core 00238 Set<float>::SetOfSetsType Fi = set_Fi->getSubsets(); 00239 for(Set<float>::SetOfSetsType::iterator j = Fi.begin(); j != Fi.end(); j++) 00240 { 00241 if(j->second.find(core_id) != j->second.end()) 00242 { 00243 size_t island_id = std::distance(Fi.begin(), j); 00244 std::advance(jj, island_id); 00245 island isl = *jj; 00246 frequency[island_id].insert(core); 00247 00248 break; 00249 } 00250 } 00251 } 00252 00253 // If shared memory islands are provided, then insert core in the right island 00254 if(set_Si != NULL) 00255 { 00256 size_t core_id = i + 1; 00257 vector<Platform::island>::iterator jj = shared.begin(); 00258 00259 // Find the frequency island that holds this core 00260 Set<float>::SetOfSetsType Si = set_Si->getSubsets(); 00261 for(Set<float>::SetOfSetsType::iterator j = Si.begin(); j != Si.end(); j++) 00262 { 00263 if(j->second.find(core_id) != j->second.end()) 00264 { 00265 size_t island_id = std::distance(Si.begin(), j); 00266 std::advance(jj, island_id); 00267 island isl = *jj; 00268 shared[island_id].insert(core); 00269 00270 break; 00271 } 00272 } 00273 } 00274 00275 this->priv = main; 00276 00277 // If voltage/frequency islands are provided, then copy the 00278 // frequency island set computed above to voltage and frequency 00279 // islands 00280 if(set_Fi == NULL) 00281 { 00282 this->voltage = main; 00283 this->freq = main; 00284 } 00285 else 00286 { 00287 islands isls; 00288 for(vector<Platform::island>::iterator i = frequency.begin(); i != frequency.end(); i++) 00289 { 00290 isls.insert(*i); 00291 } 00292 this->voltage = isls; 00293 this->freq = isls; 00294 } 00295 00296 // If ishared memory islands are provided, then copy the 00297 // frequency island set computed above to voltage and frequency 00298 // islands 00299 if(set_Si == NULL) 00300 { 00301 this->shared = main; 00302 } 00303 else 00304 { 00305 islands isls; 00306 for(vector<Platform::island>::iterator i = shared.begin(); i != shared.end(); i++) 00307 { 00308 isls.insert(*i); 00309 } 00310 this->shared = isls; 00311 } 00312 } 00313 } 00314 00315 Platform::~Platform() 00316 { 00317 for(island::const_iterator i = this->getCores().begin(); i != this->getCores().end(); i++) 00318 { 00319 delete *i; 00320 } 00321 } 00322 00323 Platform* 00324 Platform::clone() const 00325 { 00326 Platform* res = new Platform(this); 00327 return res; 00328 } 00329 00330 const Platform::island& 00331 Platform::getCores() const 00332 { 00333 return this->cores; 00334 } 00335 00336 bool 00337 Platform::isHomogeneous() const 00338 { 00339 const char* type = NULL; 00340 00341 for(island::const_iterator i = this->getCores().begin(); i != this->getCores().end(); i++) 00342 { 00343 if(type != NULL) 00344 { 00345 if(string(type).compare(typeid(**i).name()) != 0) 00346 { 00347 return false; 00348 } 00349 } 00350 00351 type = typeid(**i).name(); 00352 } 00353 00354 // If we reach this point having read at least one string, then this is homogeneous 00355 return type != NULL; 00356 } 00357 00358 Algebra 00359 Platform::buildAlgebra() const 00360 { 00361 Algebra record; 00362 00363 if(!this->isHomogeneous()) 00364 { 00365 throw CastException(std::string("Missing core number scalar \"p\" or frequency set \"F\" in input.")); 00366 } 00367 00368 Scalar<float> scalar_p("p", this->getCores().size()); 00369 Scalar<float> f_unit("Funit", (*this->getCores().begin())->getFrequencyUnit()); 00370 Set<float> set_F("F", (*this->getCores().begin())->getFrequencies()); 00371 00372 Set<float>::SetOfSetsType Fi; 00373 for(set<island>::iterator i = this->freq.begin(); i != this->freq.end(); i++) 00374 { 00375 Set<float>::SetType isl; 00376 for(island::const_iterator j = i->begin(); j != i->end(); j++) 00377 { 00378 island::iterator core_iter = cores.find(*j); 00379 isl.insert(std::distance(cores.begin(), core_iter) + 1); 00380 } 00381 Fi.insert(pair<size_t, Set<float>::SetType>((size_t)(std::distance(this->freq.begin(), i) + 1), isl)); 00382 } 00383 Set<float> set_Fi("Fi", Fi); 00384 00385 record.insert(&scalar_p); 00386 record.insert(&f_unit); 00387 record.insert(&set_F); 00388 record.insert(&set_Fi); 00389 Scalar<float> scalar_Fin("Fin", Fi.size()); 00390 record.insert(&scalar_Fin); 00391 00392 return record; 00393 } 00394 00395 const Core* 00396 Platform::getCore(size_t id) const 00397 { 00398 if(id > this->getCores().size()) 00399 { 00400 throw CastException("Requesting core beyond the number of core in the platform."); 00401 } 00402 island::iterator it = this->cores.begin(); 00403 std::advance(it, id - 1); 00404 return *it; 00405 } 00406 00407 size_t 00408 Platform::getCoreId(const Core* core) const 00409 { 00410 if(this->getCores().find(core) == this->getCores().end()) 00411 { 00412 throw CastException("Core is not part of the platform."); 00413 } 00414 00415 return std::distance(this->cores.begin(), this->cores.find(core)) + 1; 00416 } 00417 00418 const Platform::islands& 00419 Platform::getSharedMemoryIslands() const 00420 { 00421 return this->shared; 00422 } 00423 00424 const Platform::islands 00425 Platform::getSharedMemoryIslands(size_t id) const 00426 { 00427 if(id > this->getCores().size()) 00428 { 00429 throw CastException("Requesting shared memory island beyond the number of islands in the platform."); 00430 } 00431 islands isls; 00432 const Core* core = this->getCore(id); 00433 for(islands::const_iterator i = this->getSharedMemoryIslands().begin(); i != this->getSharedMemoryIslands().end(); i++) 00434 { 00435 if(i->find(core) != i->end()) 00436 { 00437 isls.insert(*i); 00438 } 00439 } 00440 00441 return isls; 00442 } 00443 00444 const std::set<int> 00445 Platform::getSharedMemoryIslands(const islands& isls) const 00446 { 00447 set<int> indexes; 00448 for(Platform::islands::const_iterator i = isls.begin(); i != isls.end(); i++) 00449 { 00450 if(this->getSharedMemoryIslands().find(*i) != this->getSharedMemoryIslands().end()) 00451 { 00452 indexes.insert((int)std::distance(this->getSharedMemoryIslands().begin(), this->getSharedMemoryIslands().find(*i)) + 1); 00453 } 00454 else 00455 { 00456 throw CastException("Could not find island in platform."); 00457 } 00458 } 00459 00460 return indexes; 00461 } 00462 00463 const Platform::islands 00464 Platform::getSharedMemoryIslands(const std::set<int>& isls) const 00465 { 00466 Platform::islands out; 00467 for(std::set<int>::const_iterator i = isls.begin(); i != isls.end(); i++) 00468 { 00469 set<island>::const_iterator ii = this->getSharedMemoryIslands().begin(); 00470 if(*i > (ptrdiff_t)this->getSharedMemoryIslands().size()) 00471 { 00472 throw CastException("Trying to get shared memory island beyond the capacity of the platform."); 00473 } 00474 std::advance(ii, *i); 00475 out.insert(*ii); 00476 } 00477 00478 return out; 00479 } 00480 00481 const Platform::islands& 00482 Platform::getMainMemoryIslands() const 00483 { 00484 return this->main; 00485 } 00486 00487 const Platform::islands 00488 Platform::getMainMemoryIslands(size_t id) const 00489 { 00490 islands isls; 00491 const Core* core = this->getCore(id); 00492 for(Platform::islands::const_iterator i = this->getMainMemoryIslands().begin(); i != this->getMainMemoryIslands().end(); i++) 00493 { 00494 if(i->find(core) != i->end()) 00495 { 00496 isls.insert(*i); 00497 } 00498 } 00499 00500 return isls; 00501 } 00502 00503 const Platform::islands& 00504 Platform::getPrivateMemoryIslands() const 00505 { 00506 return this->priv; 00507 } 00508 00509 const Platform::islands 00510 Platform::getPrivateMemoryIslands(size_t id) const 00511 { 00512 Platform::islands isls; 00513 const Core* core = this->getCore(id); 00514 for(Platform::islands::const_iterator i = this->getPrivateMemoryIslands().begin(); i != this->getPrivateMemoryIslands().end(); i++) 00515 { 00516 if(i->find(core) != i->end()) 00517 { 00518 isls.insert(*i); 00519 } 00520 } 00521 00522 return isls; 00523 } 00524 00525 const Platform::islands& 00526 Platform::getVoltageIslands() const 00527 { 00528 return this->voltage; 00529 } 00530 00531 const Platform::island& 00532 Platform::getVoltageIsland(size_t id) const 00533 { 00534 const Core* core = this->getCore(id); 00535 for(Platform::islands::const_iterator i = this->getVoltageIslands().begin(); i != this->getVoltageIslands().end(); i++) 00536 { 00537 if(i->find(core) != i->end()) 00538 { 00539 return *i; 00540 } 00541 } 00542 00543 throw CastException("Cannot find core in any Platform::island of the platform."); 00544 } 00545 00546 const Platform::islands& 00547 Platform::getFrequencyIslands() const 00548 { 00549 return this->freq; 00550 } 00551 00552 const Platform::island& 00553 Platform::getFrequencyIsland(size_t id) const 00554 { 00555 const Core* core = this->getCore(id); 00556 for(Platform::islands::const_iterator i = this->getFrequencyIslands().begin(); i != this->getFrequencyIslands().end(); i++) 00557 { 00558 if(i->find(core) != i->end()) 00559 { 00560 return *i; 00561 } 00562 } 00563 00564 throw CastException("Cannot find core in any Platform::island of the platform."); 00565 } 00566 00567 Platform& 00568 Platform::operator=(const Platform& cpy) 00569 { 00570 for(island::const_iterator i = this->getCores().begin(); i != this->getCores().end(); i++) 00571 { 00572 delete *i; 00573 } 00574 00575 copy(&cpy); 00576 return *this; 00577 } 00578 }