OpenASIP 2.2
Loading...
Searching...
No Matches
FrequencySweepExplorer.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file FrequencySweepExplorer.cc
26 *
27 * Explorer plugin that that uses algorithm that sets one target frequency as
28 * requirement and sweeps all frequencies given by user.
29 *
30 * @author Jari Mäntyneva 2007 (jari.mantyneva-no.spam-tut.fi)
31 * @author Esa Määttä 2008 (esa.maatta-no.spam-tut.fi)
32 * @note rating: red
33 */
34
35#include <vector>
36#include <string>
37#include <set>
38#include <map>
39#include <sstream>
40#include <boost/format.hpp>
41
44#include "Conversion.hh"
45#include "DSDBManager.hh"
46#include "Machine.hh"
47#include "TestApplication.hh"
48#include "Program.hh"
49#include "Instruction.hh"
50#include "Move.hh"
51#include "Terminal.hh"
52#include "Operation.hh"
54#include "HDBRegistry.hh"
56#include "ControlUnit.hh"
57#include "HWOperation.hh"
58#include "StringTools.hh"
59#include "ADFSerializer.hh"
60#include "IDFSerializer.hh"
61#include "Segment.hh"
62#include "RFPort.hh"
64#include "TemplateSlot.hh"
65#include "CostEstimates.hh"
66#include "Application.hh"
67#include "Guard.hh"
68#include "Exception.hh"
69#include "FrequencySweep.hh"
73
74
75using namespace TTAProgram;
76using namespace TTAMachine;
77using namespace HDB;
78using namespace IDF;
79using std::endl;
80using std::map;
81using std::vector;
82using std::set;
83
84/**
85 * Explorer plugin for finding processor configurations that
86 * satisfy the runtime requirements with certain clock frequencies.
87 *
88 * Sweeps the user-set allowed frequency range with the given
89 * steps and collects all configurations that are suitable for
90 * running the given applications in the given clock frequencies.
91 *
92 * Uses all HDBs found in the HDB registry to create the configurations.
93 *
94 * Supported parameters:
95 * - start_freq_mhz, lowest frequency in the swept range in MHz
96 * - end_freq_mhz, highest frequency in the range in MHz
97 * - step_freq_mhz, frequency step in MHz
98 *
99 * - ic_dec, name of the ic decoder plugin, default is DefaultICDecoder
100 * - ic_hdb, name of the HDB that is used in IC estimation
101 */
103 PLUGIN_DESCRIPTION("Frequency sweep algorithm.");
104
106 icDec_("DefaultICDecoder"),
107 icDecHDB_("asic_130nm_1.5V.hdb"),
108 superiority_(10) {
109
110 // compulsory parameters
114
115 // parameters that have a default value
120 }
121
122 virtual bool requiresStartingPointArchitecture() const { return true; }
123 virtual bool producesArchitecture() const { return false; }
124 virtual bool requiresHDB() const { return true; }
125 virtual bool requiresSimulationData() const { return false; }
126
127
128 /**
129 * Explores from the given start configuration.
130 *
131 * @param startPointConfigurationID Configuration ID to start the
132 * exploration from.
133 * @return Returns a set of best found configuration IDs.
134 */
135 virtual std::vector<RowID>
136 explore(const RowID& startPointConfigurationID, const unsigned int&) {
137
140
141 openHDBs();
142 std::vector<RowID> result;
143
144 RowID startPointConfID = startPointConfigurationID;
145
146 // other explorer plugins used
147 DesignSpaceExplorerPlugin* icOptimizer =
149 "SimpleICOptimizer", &db());
150 DesignSpaceExplorerPlugin* minimizeMachine =
152 "MinimizeMachine", &db());
153 DesignSpaceExplorerPlugin* growMachine =
155 "GrowMachine", &db());
156
157 DSDBManager& dsdb = db();
158
159 // Sweep is always done from the lowest frequency towards the highest
160 // frequency.
161 if (startMHz_ > endMHz_) {
162 int tempMHz = startMHz_;
164 endMHz_ = tempMHz;
165 }
166
167 // helper for returning the stepped frequencies in order
169
170 // parameters for GrowMachine plugin
171 growMachine->giveParameter("superiority", Conversion::toString(superiority_));
172
173 // find new configurations by adding components until the cycle
174 // count stops going down
175 vector<RowID> cycleOptimizedConfs =
176 growMachine->explore(startPointConfID);
177 if (Application::verboseLevel() > 1) {
178 std::ostringstream msg(std::ostringstream::out);
179 msg << "GrowMachine plugin produced initial configs: ";
180 for (unsigned int i = 0; i < cycleOptimizedConfs.size(); ++i) {
181 msg << cycleOptimizedConfs.at(i) << " ";
182 }
183 msg << endl;
184 verboseLog(msg.str())
185 }
186 delete growMachine;
187 growMachine = NULL;
188
189 int currentFrequencyMHz = sweeper.nextFrequency();
190 vector<RowID>::const_iterator archIter;
191 while (currentFrequencyMHz != 0) {
192
193 verboseLogC("Testing frequency: " + Conversion::toString(
194 currentFrequencyMHz), 3)
195 /* Find the configurations that are fast enough for the
196 real time requirements of the applications at the
197 currently examined frequency. */
198 for (archIter = cycleOptimizedConfs.begin();
199 archIter != cycleOptimizedConfs.end();
200 archIter++) {
201
202 verboseLogC("Testing (fast enough) init config: " +
203 Conversion::toString(*archIter), 3)
204 // if is fast enough for all apps
205 if (fastEnough(*archIter, currentFrequencyMHz, dsdb)) {
206 verboseLogC("Calling minimize machine for init config: " +
207 Conversion::toString(*archIter), 3)
208
209 // calling MimimizeMachine plugin with confToMinimize
210 // (architer) and currentFrequencyMHz
211 minimizeMachine->giveParameter("frequency",
212 Conversion::toString(currentFrequencyMHz));
214 callPlugin(minimizeMachine, *archIter, dsdb);
215
216 // create implementation for configuration
217 RowID selectedConf = createImplementationAndStore(minConf,
218 currentFrequencyMHz, 0, true, icDec_, icDecHDB_);
219
220 verboseLogC("Implementation selection produced a config: "
221 + Conversion::toString(selectedConf), 3)
222
223 // check if component selection failed
224 if (selectedConf == 0) {
225 verboseLogC("Component selection failed for minimized"
226 " arch: " + Conversion::toString(
227 minConf.architectureID), 3)
228 continue;
229 }
230
231 // IC optimization with SimpleICOptimizer plugin
232 vector<RowID> icOptimizedResult =
233 icOptimizer->explore(selectedConf);
234 if (icOptimizedResult.size() == 1) {
236 std::ostringstream msg(std::ostringstream::out);
237 msg << "Config " << icOptimizedResult.at(0)
238 << " created for frequency "
239 << currentFrequencyMHz << "." << endl;
240 verboseLogC(msg.str(), 1)
241 }
242 result.push_back(icOptimizedResult.at(0));
243 } else {
244 // simpleICOptimizer can make a machine not fully
245 // connected, and so, register file requirements can
246 // change. Meaning evaluating the machine can fail in
247 // the plugin.
248 verboseLogC("SimpleICOptimzer failed for arch: "
249 + Conversion::toString(selectedConf), 3)
250 continue;
251 }
252
253 /// @todo Optimization of the instruction size
254 /// not required for 1st version!
255
256 /// @todo Final optimization/tuning
257 /// not required for 1st version!
258
259 } else {
260 verboseLogC("Init config was too slow.", 3)
261 // the architecture was too slow
262 }
263
264 }
265 // advance to next frequency
266 currentFrequencyMHz = sweeper.nextFrequency();
267 }
268
269 delete minimizeMachine;
270 minimizeMachine = NULL;
271 delete icOptimizer;
272 icOptimizer = NULL;
273
274 // Idea:
275 // All results will be given to a result explorer that returns
276 // the given number of best configuration id:s that can be returned
277 // to the user.
278 // BestResultExplorer resultExplorer(dsdb, explorer.results());
279 // result = resultExplorer.find(5);
280
281 return result;
282 }
283
284private:
285 /// Selector used by the plugin.
287 /// Default value of busCount_
288 static const int busCountDefault_ = 4;
289
290 static const unsigned int immSlotBusIndexDefault_ = 0;
291
292 static const int registerFileSizeDefault_ = 4;
293 static const int maxNumberOfRegisterFilesDefault_ = 16;
294 static const int rfReadPortsDefault_ = 1;
295 static const int rfWritePortsDefault_ = 1;
296
297 // parameter names
298 const static std::string startMHzPN_;
299 const static std::string endMHzPN_;
300 const static std::string stepMHzPN_;
301
302 const static std::string icDecPN_;
303 const static std::string icDecHDBPN_;
304 const static std::string superiorityPN_;
305
306 // parameters
307 unsigned int startMHz_;
308 unsigned int endMHz_;
309 unsigned int stepMHz_;
310
311 /// name of the ic decoder plugin for idf
312 std::string icDec_;
313 /// name of the hdb used by ic decoder
314 std::string icDecHDB_;
315 /// Superirity percentage for the GrowMachine plugin
316 unsigned int superiority_;
317
318 static const std::string talo;
319
320 /**
321 * Reads the parameters given to the plugin.
322 */
334
335
336 /**
337 * Loads HDBs that are used into the registry.
338 */
339 void openHDBs() {
340 HDBRegistry& hdbRegistry = HDBRegistry::instance();
341
342 // if HDBRegistry contains no HDBManagers load from default paths
343 if (hdbRegistry.hdbCount() == 0) {
344 hdbRegistry.loadFromSearchPaths();
345 }
346 }
347
348
349 /**
350 * Check if architecture is fast enough.
351 *
352 * @param id Row id of the architecture.
353 * @param freq Frequency in MHz for testing the run time.
354 * @param dsdb Desing Space Explorer database.
355 */
356 bool fastEnough(const RowID& id, const int& freq, DSDBManager& dsdb) {
357 set<RowID>::const_iterator applicationIter;
358 set<RowID> applicationIDs = dsdb.applicationIDs();
359 DSDBManager::MachineConfiguration configuration =
360 dsdb.configuration(id);
361 for (applicationIter = applicationIDs.begin();
362 applicationIter != applicationIDs.end();
363 applicationIter++) {
364
365 ClockCycleCount cycleCount =
366 dsdb.cycleCount(
367 *applicationIter, configuration.architectureID);
368 TestApplication testApplication(
369 dsdb.applicationPath(*applicationIter));
370 // test if application max runtime is set
371 if (testApplication.maxRuntime() <= 0) {
372 continue;
373 }
374
375 if ((static_cast<double>(cycleCount) / (static_cast<double>(freq) * static_cast<double>(1000000))) >
376 testApplication.maxRuntime()) {
377 // we can skip this architecture since it won't
378 // meet the speed requirements
379 return false;
380 }
381 }
382 return true;
383 }
384
385
386 /**
387 * Calls an explorer plugin.
388 *
389 * @param plugin The plugin to be called.
390 * @param arch Row id of the architechture to be passed to the plugin.
391 * @return dsdb Design space database to be used.
392 */
395 const RowID& arch,
396 DSDBManager& dsdb) {
397
398 vector<RowID> resultConfs = plugin->explore(arch);
399
401 if (resultConfs.size() == 1) {
402 resultConf = dsdb.configuration(resultConfs.at(0));
403 } else {
404 throw InvalidData(
405 __FILE__, __LINE__, __func__,
406 (boost::format(
407 "%s failed to optimize "
408 "configuration %d. Possible bug in Optimizer,"
409 " Estimator or missing data from HDB."
410 ) % arch % plugin->name()).str());
411 }
412
413 if (Application::verboseLevel() > 2) {
414 std::ostringstream msg(std::ostringstream::out);
415 msg << plugin->name()
416 << " plugin produced config: "
417 << resultConfs.at(0) << endl;
418 verboseLog(msg.str())
419 }
420
421 return resultConf;
422 }
423};
424
425// parameter names
426const std::string FrequencySweepExplorer::startMHzPN_("start_freq_mhz");
427const std::string FrequencySweepExplorer::endMHzPN_("end_freq_mhz");
428const std::string FrequencySweepExplorer::stepMHzPN_("step_freq_mhz");
429const std::string FrequencySweepExplorer::icDecPN_("ic_dec");
430const std::string FrequencySweepExplorer::icDecHDBPN_("ic_hdb");
431const std::string FrequencySweepExplorer::superiorityPN_("superiority");
432
#define verboseLog(text)
#define __func__
#define verboseLogC(text, neededVerbosity)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
#define EXPORT_DESIGN_SPACE_EXPLORER_PLUGIN(PLUGIN_NAME__)
#define UINT(OPERAND)
Definition OSAL.hh:313
CycleCount ClockCycleCount
Alias for ClockCycleCount.
static int verboseLevel()
static std::string toString(const T &source)
ClockCycleCount cycleCount(RowID application, RowID architecture) const
std::set< RowID > applicationIDs() const
MachineConfiguration configuration(RowID id) const
std::string applicationPath(RowID id) const
void readCompulsoryParameter(const std::string paramName, T &param) const
void readOptionalParameter(const std::string paramName, T &param) const
virtual std::string name() const
void addParameter(TCEString name, ExplorerPluginParameterType type, bool compulsory=true, TCEString defaultValue="", TCEString description="")
virtual std::vector< RowID > explore(const RowID &startPointConfigurationID, const unsigned int &maxIter=0)
virtual void giveParameter(const std::string &name, const std::string &value)
RowID createImplementationAndStore(const DSDBManager::MachineConfiguration &conf, const double &frequency=0.0, const double &maxArea=0.0, const bool &createEstimates=true, const std::string &icDec="DefaultICDecoder", const std::string &icDecHDB="asic_130nm_1.5V.hdb")
virtual DSDBManager & db()
static DesignSpaceExplorerPlugin * loadExplorerPlugin(const std::string &pluginName, DSDBManager *dsdb=NULL)
virtual std::vector< RowID > explore(const RowID &startPointConfigurationID, const unsigned int &)
static const std::string icDecPN_
static const int busCountDefault_
Default value of busCount_.
std::string icDecHDB_
name of the hdb used by ic decoder
virtual bool requiresHDB() const
static const std::string superiorityPN_
DSDBManager::MachineConfiguration callPlugin(DesignSpaceExplorerPlugin *plugin, const RowID &arch, DSDBManager &dsdb)
static const int registerFileSizeDefault_
bool fastEnough(const RowID &id, const int &freq, DSDBManager &dsdb)
PLUGIN_DESCRIPTION("Frequency sweep algorithm.")
std::string icDec_
name of the ic decoder plugin for idf
static const std::string endMHzPN_
static const std::string talo
unsigned int superiority_
Superirity percentage for the GrowMachine plugin.
static const unsigned int immSlotBusIndexDefault_
ComponentImplementationSelector selector_
Selector used by the plugin.
static const std::string stepMHzPN_
virtual bool producesArchitecture() const
virtual bool requiresSimulationData() const
static const std::string startMHzPN_
virtual bool requiresStartingPointArchitecture() const
static const std::string icDecHDBPN_
static const int maxNumberOfRegisterFilesDefault_
static HDBRegistry & instance()
void loadFromSearchPaths()
Runtime maxRuntime() const