pelib  2.0.0
src/Platform.cpp
Go to the documentation of this file.
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 }