crown  1.0.0
src/CrownConfigBinary.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 #include <crown/CrownConfigBinary.hpp>
00021 #include <crown/CrownException.hpp>
00022 #include <pelib/Matrix.hpp>
00023 #include <pelib/time.h>
00024 #include <pelib/AmplInput.hpp>
00025 
00026 #ifdef debug
00027 #undef debug
00028 #endif
00029 
00030 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl;
00031 
00032 using namespace pelib;
00033 using namespace crown;
00034 using namespace std;
00035 
00036 static
00037 map<int, map<int, float> >
00038 build_crown(size_t p, size_t wi, size_t skip, const map<int, map<int, float> > matrix, map<int, map<int, float> > &tree, const Platform::islands &isl)
00039 {
00040         map<int, map<int, float> > config = matrix;
00041         map<int, float> group;
00042         for(size_t i = 0; i < p; i++)
00043         {
00044                 if(i < skip || i >= skip + wi)
00045                 {
00046                         group.insert(pair<int, float>(i + 1, 0));
00047                 }
00048                 else
00049                 {
00050                         group.insert(pair<int, float>(i + 1, 1));
00051                 }
00052         }
00053 
00054         // Dependencies fo this group
00055         map<int, float> deps;
00056         for(size_t i = 0; i < 2 * p - 1; i++)
00057         {
00058                 deps.insert(pair<int, float>(i + 1, 0));
00059         }
00060 
00061         // Browse all other groups already formed
00062         for(map<int, map<int, float> >::iterator i = config.begin(); i != config.end(); i++)
00063         {
00064                 // Browse all cores
00065                 int ii = std::distance(config.begin(), i) + 1;
00066                 for(map<int, float>::iterator j = i->second.begin(); j != i->second.end(); j++)
00067                 {
00068                         int jj = std::distance(i->second.begin(), j) + 1;
00069                         // If both groups have the core, then there is a dependency link
00070                         if(group[jj] == j->second && j->second > 0)
00071                         {
00072                                 deps[ii] = 1;
00073                                 break;
00074                         }
00075                 }
00076         }
00077 
00078         // Add groups membership and dependencies to temporary outcome
00079         config.insert(pair<int, map<int, float> >(config.size() + 1, group));
00080         tree.insert(pair<int, map<int, float> >(tree.size() + 1, deps));
00081 
00082         // Recurse, if necessary
00083         if(wi > 1)
00084         {
00085                 size_t size = 0;
00086                 Platform::islands::const_iterator i;
00087                 for(i = isl.begin(); size < skip && i != isl.end(); i++)
00088                 {
00089                         size += i->size();
00090                 }
00091                 if(size > skip && wi + skip > size)
00092                 {
00093                         // This should never happen
00094                         throw CrownException("Configuring group misaligned with frequency islands");
00095                 }
00096 
00097                 // At this point, size = sum(size(all previous islands))
00098                 size_t left = floor((float)wi / 2);
00099                 Platform::islands::const_iterator j = i;
00100                 j++;
00101                 
00102                 if(left > i->size() && j == isl.end())
00103                 {
00104                         throw CrownException("Creating group spanning beyond last frequency island");
00105                 }
00106         
00107                 size_t next = i->size();
00108                 for(; j != isl.end() && left > next; j++)
00109                 {
00110                         next += j->size();
00111                 }
00112                 if(left < next && next < wi)
00113                 {
00114                         left = next;
00115                 }
00116                 config = build_crown(p, left, skip, config, tree, isl);
00117                 config = build_crown(p, wi - left, skip + left, config, tree, isl);
00118         }
00119 
00120         return config;
00121 }
00122 
00123 string
00124 CrownConfigBinary::getShortDescription() const
00125 {
00126         return string("bin");
00127 }
00128 
00129 Algebra
00130 CrownConfigBinary::configure(const Taskgraph &tg, const Platform &pt, const Algebra &param, map<const string, double> &stats) const
00131 {
00132         // Compute a binary crown and place it in class' Algebra container
00133         size_t p = pt.getCores().size();
00134         map<int, map<int, float> > tree;
00135         struct timespec start, stop, total_time;
00136         clock_gettime(CLOCK_MONOTONIC, &start); 
00137         map<int, map<int, float> > config = build_crown(p, p, 0, map<int, map<int, float> >(), tree, pt.getFrequencyIslands());
00138         clock_gettime(CLOCK_MONOTONIC, &stop);
00139         pelib_timespec_subtract(&total_time, &stop, &start);
00140         Algebra conf;
00141 
00142         stats.insert(pair<const string, double>("time_config", (float)(total_time.tv_sec * pelib_nsec_in_sec + total_time.tv_nsec) / (float)pelib_nsec_in_sec));
00143         conf.insert(new Matrix<int, int, float>(CrownConfig::crownConfigGroups, config));
00144         conf.insert(new Matrix<int, int, float>(CrownConfig::crownConfigTree, tree));
00145 
00146         return conf;
00147 }
00148 
00149 CrownConfigBinary::~CrownConfigBinary()
00150 {
00151         // Do nothing
00152 }
00153 
00154 CrownConfig*
00155 CrownConfigBinary::clone() const
00156 {
00157         return new CrownConfigBinary(*this);
00158 }
00159 
00160 float
00161 CrownConfigBinary::complexity(const Algebra &problem) const
00162 {
00163         return 0;
00164 }
00165 
00166 float
00167 CrownConfigBinary::complexity(const Taskgraph&, const Platform&, const Algebra&) const
00168 {
00169         return 0;
00170 }
00171