OpenASIP 2.2
Loading...
Searching...
No Matches
InterpolatingFUEstimator.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 InterpolatingFUEstimator.cc
26 *
27 * Declaration of InterpolatingFUEstimator. A FU estimation plugin that
28 * estimates data generating cost database from the cost data stored in HDB.
29 * Estimate is interpolated if possible if no exact data values are found.
30 *
31 * @author Jari Mäntyneva 2006 (jari.mantyneva-no.spam-tut.fi)
32 * @note rating: red
33 */
35#include "Application.hh"
36#include "DataObject.hh"
37#include "Exception.hh"
38#include "HDBManager.hh"
39#include "FunctionUnit.hh"
40#include "ExecutionTrace.hh"
41#include "CostDatabase.hh"
42#include "EntryKeyProperty.hh"
43#include "CostDBTypes.hh"
44#include "MatchType.hh"
45#include "FilterSearch.hh"
46#include "HWOperation.hh"
47#include "FUPort.hh"
48#include "FUEntry.hh"
49#include "FUImplementation.hh"
50#include "FUArchitecture.hh"
51#include "BaseFUPort.hh"
53#include "StringTools.hh"
54
55using namespace CostEstimator;
56using namespace HDB;
57using namespace TTAMachine;
58using std::string;
59using std::set;
60using std::vector;
61
63public:
68
70 }
71
73 "FU cost estimator plugin that estimates costs of FUs by generating"
74 "cost database from cost values of HDB and uses interpolation to "
75 "estimate the costs. In case there's no cost data available for the "
76 "given FU the plugin interpolates the estimate if possible.");
77
78public:
79
80 /**
81 * Estimates the function unit's area by fetching cost data named 'area'
82 * from HDB.
83 */
86 const IDF::FUImplementationLocation& /*implementation*/,
87 AreaInGates& area,
88 HDB::HDBManager& hdb) {
89
90//#define DEBUG_AREA_ESTIMATION
91 try {
94 CostDBTypes::EntryTable::const_iterator i = results.begin();
95 area = 0.0;
96 // worst case area is returned
97 for (;i < results.end(); i++) {
98 for (int n = 0; n < (*i)->statisticsCount(); n++) {
99 if (area < (*i)->statistics(n).area()) {
100 area = (*i)->statistics(n).area();
101 }
102 }
103 }
104 } catch (Exception& e) {
105 return false;
106 }
107#ifdef DEBUG_AREA_ESTIMATION
109 << fu.name() << " area " << area << std::endl;
110#endif
111 return true;
112 }
113
114 /**
115 * Estimates the function unit port write delay by fetching cost data
116 * named 'input_delay' from HDB.
117 *
118 * Assumes that all ports have the same input delay, that is, there is
119 * only one 'input_delay' entry for a FU in HDB.
120 */
121 bool
123 const TTAMachine::FUPort& port,
124 const IDF::FUImplementationLocation& /*implementation*/,
125 DelayInNanoSeconds& delay,
126 HDB::HDBManager& hdb) {
127
128//#define DEBUG_DELAY_ESTIMATION
129
130 try {
133
134 CostDBTypes::EntryTable::const_iterator i = results.begin();
135 delay = 0.0;
136 // worst case delay is returned
137 for (;i < results.end(); i++) {
138 for (int n = 0; n < (*i)->statisticsCount(); n++) {
139#ifndef UNIQUE_PORT_DELAY
140 if (delay < (*i)->statistics(n).delayPort("input_delay")) {
141 delay = (*i)->statistics(n).delayPort("input_delay");
142 }
143#endif // UNIQUE_PORT_DELAY
144#ifdef UNIQUE_PORT_DELAY
145 // this one is used if defferent ports of an unit
146 // can have different delays
147 if (delay < (*i)->statistics(n).delayPort(port.name())) {
148 delay = (*i)->statistics(n).delayPort(port.name());
149 }
150#endif // UNIQUE_PORT_DELAY
151 }
152 }
153 } catch (Exception& e) {
154#ifdef DEBUG_DELAY_ESTIMATION
155 Application::logStream() << "No input_delay data for function "
156 << "unit "
157 << port.parentUnit()->name()
158 << " found in HDB." << std::endl;
159#endif // DEBUG_DELAY_ESTIMATION
160 return false;
161 }
162#ifdef DEBUG_DELAY_ESTIMATION
164 << port.name() << " (port) delay " << delay << std::endl;
165#endif
166 return true;
167 }
168
169 /**
170 * Estimates the function unit port read delay by fetching cost data
171 * named 'output_delay' from HDB.
172 *
173 * Assumes that all ports have the same output delay, that is, there is
174 * only one 'output_delay' entry for a FU in HDB.
175 */
176 bool
178 const TTAMachine::FUPort& port,
179 const IDF::FUImplementationLocation& /*implementation*/,
180 DelayInNanoSeconds& delay,
181 HDB::HDBManager& hdb) {
182
183//#define DEBUG_DELAY_ESTIMATION
184 try {
187 CostDBTypes::EntryTable::const_iterator i = results.begin();
188 delay = 0.0;
189 // worst case delay is returned
190 for (;i < results.end(); i++) {
191 for (int n = 0; n < (*i)->statisticsCount(); n++) {
192#ifndef UNIQUE_PORT_DELAY
193 if (delay < (*i)->statistics(n).delayPort("output_delay")) {
194 delay = (*i)->statistics(n).delayPort("output_delay");
195 }
196#endif // UNIQUE_PORT_DELAY
197#ifdef UNIQUE_PORT_DELAY
198 // this one is used if defferent ports of an unit
199 // can have different delays
200 if (delay < (*i)->statistics(n).delayPort(port.name())) {
201 delay = (*i)->statistics(n).delayPort(port.name());
202 }
203#endif // UNIQUE_PORT_DELAY
204 }
205 }
206 } catch (Exception& e) {
207#ifdef DEBUG_DELAY_ESTIMATION
208 Application::logStream() << "No input_delay data for function "
209 << "unit "
210 << port.parentUnit()->name()
211 << " found in HDB." << std::endl;
212#endif // DEBUG_DELAY_ESTIMATION
213 return false;
214 }
215#ifdef DEBUG_DELAY_ESTIMATION
217 << port.name() << " (port) delay " << delay << std::endl;
218#endif // DEBUG_DELAY_ESTIMATION
219 return true;
220 }
221
222 /**
223 * Estimates the function unit maximum computation delay by fetching
224 * cost data named 'computation_delay' from HDB.
225 */
227 const TTAMachine::FunctionUnit& fu,
228 const IDF::FUImplementationLocation& /*implementation*/,
229 DelayInNanoSeconds& delay,
230 HDB::HDBManager& hdb) {
231
232//#define DEBUG_DELAY_ESTIMATION
233 try {
236 CostDBTypes::EntryTable::const_iterator i = results.begin();
237 delay = 0.0;
238 // the worst case is returned if found multiple results
239 for (;i < results.end(); i++) {
240 for (int n = 0; n < (*i)->statisticsCount(); n++) {
241 if (delay < (*i)->statistics(n).delay()) {
242 delay = (*i)->statistics(n).delay();
243 }
244 }
245 }
246 } catch (Exception& e) {
247 return false;
248 }
249#ifdef DEBUG_DELAY_ESTIMATION
251 << fu.name() << " computation delay " << delay << std::endl;
252#endif // DEBUG_DELAY_ESTIMATION
253 return true;
254 }
255 /**
256 * Estimates the energy consumed by given FU.
257 *
258 * Estimate is done by computing the sum of all operation execution
259 * energies and FU idle energy. Operation execution energies are stored
260 * with entries named 'operation_execution_energy operation_name'. The
261 * idle energy is in entry named 'fu_idle_energy'.
262 */
263 virtual bool estimateEnergy(
264 const TTAMachine::FunctionUnit& fu,
266 const TTAProgram::Program& /*program*/,
267 const ExecutionTrace& trace,
268 EnergyInMilliJoules& energy,
269 HDB::HDBManager& hdb) {
270
271//#define DEBUG_ENERGY_ESTIMATION
272 try {
275
276 energy = 0.0;
277 ClockCycleCount cyclesWithFUAccess = 0;
278#ifdef DEBUG_ENERGY_ESTIMATION
280 << "## function unit " << fu.name() << ": " << std::endl;
281#endif
285 const_iterator i = operationTriggers->begin();
286 i != operationTriggers->end(); ++i) {
287
288 const ExecutionTrace::FUOperationTriggerCount& triggerCount =
289 *i;
290
291 const ExecutionTrace::OperationID operation =
292 StringTools::stringToLower(triggerCount.get<0>());
293
295 triggerCount.get<1>();
296
297 const std::string dataName =
298 std::string("operation_execution_energy ") + operation;
299
300 try {
301 CostDBTypes::EntryTable::const_iterator i = results.begin();
302 for (;i < results.end(); i++) {
303
304 // in case there are multiple operation execution
305 // energies, select the worst case in the result
306 // @todo ensure that multiple results is not a bug
307 EnergyInMilliJoules tempEnergy = 0.0;
308 for (int n = 0; n < (*i)->statisticsCount(); n++) {
309 if (((*i)->statistics(n).energyOperation(
310 operation) * count) > tempEnergy) {
311
312 tempEnergy +=
313 (*i)->statistics(n).energyOperation(
314 operation) * count;
315 }
316#ifdef DEBUG_ENERGY_ESTIMATION
317 if (n > 0) {
319 << " NOTE: Multiple fu execution energy"
320 << " results found!"
321 << " operation: " << operation
322 << " "
323 << (*i)->statistics(n).energyOperation(
324 operation)
325 << std::endl;
326 }
327#endif
328 }
329 energy += tempEnergy;
330 }
331 cyclesWithFUAccess += count;
332 } catch (const KeyNotFound&) {
333 // if no data found, don't even try to estimate the area
334 delete operationTriggers;
335 operationTriggers = NULL;
337 << "Cost estimation data '" << dataName
338 << "' not found in HDB." << std::endl;
339 return false;
340 } catch (const Exception& e) {
341 delete operationTriggers;
342 operationTriggers = NULL;
344 return false;
345 }
346
347 }
348 delete operationTriggers;
349 operationTriggers = NULL;
350
351 // add the cost of FU idling
352 const ClockCycleCount idleCycles =
353 trace.simulatedCycleCount() - cyclesWithFUAccess;
354 const std::string dataName = std::string("fu_idle_energy");
355
356 try {
357 CostDBTypes::EntryTable::const_iterator i = results.begin();
358 for (;i < results.end(); i++) {
359
360 // in case there are multiple fu idle energies,
361 // select the worst case in the result
362 // @todo ensure that multiple results is not a bug
363 EnergyInMilliJoules tempEnergy = 0.0;
364 for (int n = 0; n < (*i)->statisticsCount(); n++) {
365 if (((*i)->statistics(n).energyIdle() * idleCycles) >
366 tempEnergy) {
367
368 tempEnergy =
369 (*i)->statistics(n).energyIdle() * idleCycles;
370 }
371#ifdef DEBUG_ENERGY_ESTIMATION
372 if (n > 0) {
374 << " NOTE: Multiple fu idle energy results found!"
375 << (*i)->statistics(n).energyIdle()
376 << std::endl;
377 }
378#endif
379 }
380 energy += tempEnergy;
381 }
382 } catch (const KeyNotFound&) {
383 // if no data found, don't even try to estimate the area
385 << "Cost estimation data '" << dataName
386 << "' for FU with id " << implementation.id()
387 << " not found in HDB." << std::endl;
388 return false;
389 }
390 } catch (const Exception& e) {
392 return false;
393 }
394
395 return true;
396 }
397private:
398 /// Registry of cost databases.
400 /// Cost database being used.
402 /// Search strategy to be used with the cost database.
404 /// Entry key property of function unit.
406 /// Search type for each entry type.
407 typedef std::map<
409 /// Types of matches used for searching entries from the cost database.
411 /// Table of types of match.
413
414/**
415 * Initializes the plugin.
416 *
417 * @param hdb The HDB to be used in searching entries. Cost database is created
418 * in basis of this HDB.
419 */
420void
429
430/**
431 * Creates types of matches used for searching cost database
432 * entries.
433 */
445
446/**
447 * Creates a search to cost database to find entries matching the given
448 * function unit.
449 *
450 * @param fu Function unit which matches are searched.
451 * @return Returns entries that matched the function unit.
452 */
454
456 int ports = fu.operationPortCount();
457 int width = 0;
458 for (int n = 0; n < ports; n++) {
459 BaseFUPort* port = fu.port(n);
460 if (dynamic_cast<FUPort*>(port) != NULL) {
461 FUPort* fuPort = dynamic_cast<FUPort*>(port);
462 if (width == 0) {
463 width = fuPort->width();
464 } else if (width != fuPort->width()) {
465 return results;
466 }
467 }
468 }
470 searchKey->addField(
471 new EntryKeyField(
472 new EntryKeyDataInt(width),
474 searchKey->addField(
475 new EntryKeyField(
478 // Perform a database query.
479 try {
480 results = costdb_->search(*searchKey, unitMatchType_);
481 } catch (Exception& e) {
482 // no results
483 delete searchKey;
484 searchKey = 0;
485 throw e;
486 }
487 delete searchKey;
488 searchKey = 0;
489
490 return results;
491}
492
493};
494
#define debugLog(text)
ExecutionTrace * trace
the execution trace database
IDF::MachineImplementation * implementation
the implementation definition of the estimated processor
#define EXPORT_FU_COST_ESTIMATOR_PLUGIN(PLUGIN_NAME__)
CycleCount ClockCycleCount
Alias for ClockCycleCount.
static std::ostream & logStream()
void addField(EntryKeyField *field)
static const std::string EK_UNIT
Entry type for function units.
std::vector< MatchType * > MatchTypeTable
Table of types of match.
static const std::string EKF_FUNCTION_UNIT
Field type for function unit entry;.
std::vector< CostDBEntry * > EntryTable
Table of database entries.
static const std::string EKF_BIT_WIDTH
Field type for bit width of an entry.
static CostDatabaseRegistry & instance()
CostDatabase & costDatabase(const HDB::HDBManager &hdb)
void setSearchStrategy(SearchStrategy *strategy)
CostDBTypes::EntryTable search(const CostDBEntryKey &searchKey, const CostDBTypes::MatchTypeTable &match) const
static EntryKeyProperty * find(std::string type)
EntryKeyFieldProperty * fieldProperty(std::string field) const
std::string errorMessage() const
Definition Exception.cc:123
std::string OperationID
a type for storing operation identifiers
ClockCycleCount OperationTriggerCount
a type for operation trigger counts
ClockCycleCount simulatedCycleCount() const
std::list< FUOperationTriggerCount > FUOperationTriggerCountList
type to be used for lists of function operation execution counts
FUOperationTriggerCountList * functionUnitOperationTriggerCounts(FunctionUnitID functionUnit) const
boost::tuple< OperationID, OperationTriggerCount > FUOperationTriggerCount
type to be used as a key for storing function unit operation execution counts
void initializeEstimator(const HDBManager &hdb)
virtual bool estimateEnergy(const TTAMachine::FunctionUnit &fu, const IDF::FUImplementationLocation &implementation, const TTAProgram::Program &, const ExecutionTrace &trace, EnergyInMilliJoules &energy, HDB::HDBManager &hdb)
bool estimateArea(const TTAMachine::FunctionUnit &fu, const IDF::FUImplementationLocation &, AreaInGates &area, HDB::HDBManager &hdb)
DESCRIPTION("FU cost estimator plugin that estimates costs of FUs by generating" "cost database from cost values of HDB and uses interpolation to " "estimate the costs. In case there's no cost data available for the " "given FU the plugin interpolates the estimate if possible.")
MatchTypeMap searchTypes_
Types of matches used for searching entries from the cost database.
CostDatabase * costdb_
Cost database being used.
bool estimatePortReadDelay(const TTAMachine::FUPort &port, const IDF::FUImplementationLocation &, DelayInNanoSeconds &delay, HDB::HDBManager &hdb)
EntryKeyProperty * unitProperty_
Entry key property of function unit.
bool estimateMaximumComputationDelay(const TTAMachine::FunctionUnit &fu, const IDF::FUImplementationLocation &, DelayInNanoSeconds &delay, HDB::HDBManager &hdb)
std::map< const EntryKeyProperty *, CostDBTypes::MatchTypeTable > MatchTypeMap
Search type for each entry type.
bool estimatePortWriteDelay(const TTAMachine::FUPort &port, const IDF::FUImplementationLocation &, DelayInNanoSeconds &delay, HDB::HDBManager &hdb)
SearchStrategy * strategy_
Search strategy to be used with the cost database.
CostDatabaseRegistry * costDatabaseRegistry_
Registry of cost databases.
CostDBTypes::EntryTable createSearch(const FunctionUnit &fu) const
CostDBTypes::MatchTypeTable unitMatchType_
Table of types of match.
InterpolatingFUEstimator(const std::string &name)
static std::string stringToLower(const std::string &source)
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual int width() const
virtual TCEString name() const
virtual int operationPortCount() const
virtual BaseFUPort * port(const std::string &name) const
virtual std::string name() const
Definition Port.cc:141
double AreaInGates
type for area values in equivalent gates
double DelayInNanoSeconds
type for propagation delays in nano seconds
double EnergyInMilliJoules
type for consumed energy in milli joules