crown
1.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 #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 ¶m, 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