OpenASIP 2.2
Loading...
Searching...
No Matches
CostDatabase.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 CostDatabase.cc
26 *
27 * Implementation of CostDatabase class.
28 *
29 * @author Tommi Rantanen 2003 (tommi.rantanen-no.spam-tut.fi)
30 * @author Jari Mäntyneva 2005 (jari.mantyneva-no.spam-tut.fi)
31 * @note rating: red
32 */
33
34#include <vector>
35#include <set>
36#include <map>
37#include <string>
38#include "CompilerWarnings.hh"
39IGNORE_CLANG_WARNING("-Wkeyword-macro")
40#include <boost/regex.hpp>
42
43#include "Application.hh"
44#include "HDBManager.hh"
45#include "CostDatabase.hh"
46#include "CostDBEntryStats.hh"
47#include "CostDBEntryStatsRF.hh"
48#include "CostDBEntryStatsFU.hh"
49#include "Conversion.hh"
50#include "SearchStrategy.hh"
51#include "CostDBEntry.hh"
52#include "RFEntry.hh"
53#include "RFArchitecture.hh"
54#include "FUEntry.hh"
55#include "FUArchitecture.hh"
56#include "FunctionUnit.hh"
57#include "FUPort.hh"
58#include "HWOperation.hh"
59#include "CostFunctionPlugin.hh"
61
62using std::pair;
63using std::string;
64using std::set;
65using std::vector;
66using namespace HDB;
67using namespace TTAMachine;
68
70
71/**
72 * Default constructor.
73 *
74 * @param hdb HDBManager to be used with the cost database.
75 */
77 searchStrategy_(NULL), hdb_(hdb), registerFilesBuilt_(false),
78 functionUnitsBuilt_(false), busesBuilt_(false), socketsBuilt_(false) {
79
80 // Creates entry and field types that the database contains.
81
82 EntryKeyProperty* rfileProperty =
94
95 EntryKeyProperty* unitProperty =
99
100 EntryKeyProperty* mbusProperty =
105
107
108 EntryKeyProperty* inputSocketProperty =
110 inputSocketProperty->createFieldProperty(
112 inputSocketProperty->createFieldProperty(
114
115 EntryKeyProperty* outputSocketProperty =
117 outputSocketProperty->createFieldProperty(
119 outputSocketProperty->createFieldProperty(
121/*
122 EntryKeyProperty* controlProperty =
123 EntryKeyProperty::create(CostDBTypes::EK_CONTROL);
124 controlProperty->createFieldProperty(
125 CostDBTypes::EKF_CONTROL_CONNECTIVITY);
126*/
128
130}
131
132/**
133 * Destructor.
134 *
135 * Deallocates memory reserved for the search strategy.
136 */
138
139 if (searchStrategy_ != NULL) {
140 delete searchStrategy_;
141 searchStrategy_ = NULL;
142 }
143
144 for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); i++) {
145
146 for (CostDBTypes::EntryTable::iterator j = i->second.begin();
147 j != i->second.end(); j++) {
148
149 if (*j != NULL) {
150 delete *j;
151 *j = NULL;
152 }
153 }
154 }
155}
156
157/**
158 * Creates and returns an instance of cost database build in base of the HDB.
159 *
160 * @param hdb HDB to use in building the CostDatabase.
161 * @return An instance of cost database.
162 * @exception Exception in case that an error occurred while creating the
163 * CostDatabase.
164 */
168 if (!registry->hasCostDatabase(hdb)) {
169 registry->addCostDatabase(new CostDatabase(hdb), hdb);
170 }
171 return registry->costDatabase(hdb);
172}
173
174/**
175 * Creates default cost database from all HDB entries.
176 *
177 * @exception Exception if an error occured during the cost database building.
178 */
179void
181 if (!isRegisterFilesBuilt()) {
182 buildRegisterFiles("StrictMatchRFEstimator");
183 }
184 if (!isFunctionUnitsBuilt()) {
185 buildFunctionUnits("StrictMatchFUEstimator");
186 }
187 if (!isBusesBuilt()) {
188 buildBuses("DefaultICEstimator");
189 }
190 if (!isSocketsBuilt()) {
191 buildSockets("DefaultICEstimator");
192 }
193}
194
195/**
196 * Reads register files from the set HDB and builds register file entries in to
197 * the cost database.
198 *
199 * @param rfEstimatorPluginName Name of the register file estimator plugin
200 * which cost data are read and used in the cost database.
201 * @exception Exception if an error occured during the cost database building.
202 */
203void
204CostDatabase::buildRegisterFiles(const std::string& rfEstimatorPluginName) {
205 // find out the register file estimator plugin id
206 std::set<RowID> pluginIDs = hdb_.costFunctionPluginIDs();
207 RowID rfEstimatorPluginID = 0;
208 std::set<RowID>::const_iterator pluginID = pluginIDs.begin();
209 for (; pluginID != pluginIDs.end(); pluginID++) {
211 if (plugin->name() == rfEstimatorPluginName) {
212 //"StrictMatchRFEstimator") {
213 rfEstimatorPluginID = *pluginID;
214 break;
215 }
216 }
217
218 bool useCompiledQueries = false;
219
220 // Registers
221 std::set<RowID> rfs = hdb_.rfEntryIDs();
222 std::set<RowID>::const_iterator id = rfs.begin();
223 for (; id != rfs.end(); id++) {
224 // fetch all data from the entry and put it to CostDB
225 int size = 0;
226 int reads = 0;
227 int writes = 0;
228 int bidirPorts = 0;
229 int maxReads = 0;
230 int maxWrites = 0;
231 int bitWidth = 0;
232 int latency = 0;
233 bool guardSupport = false;
234 int guardLatency = 0;
235 double area = 0;
236 double delay = 0;
237
238 const HDB::RFEntry* entry = hdb_.rfByEntryID(*id);
239
240 if (entry->hasCostFunction()) {
241 if (entry->costFunction().id() != rfEstimatorPluginID) {
242 // wrong type of estimation plugin
243 continue;
244 }
245 } else {
246 // no cost function plugin set.
247 continue;
248 }
249 if (entry->hasArchitecture()) {
250 try {
251 size = entry->architecture().size();
252 } catch (NotAvailable& e) {
253 // size is parametrized
254 // entry cannot be added to costDB
255 continue;
256 }
257 try {
258 bitWidth = entry->architecture().width();
259 } catch (NotAvailable& e) {
260 // bit width is parametrized
261 // entry cannot be added to costDB
262 continue;
263 }
264 writes = entry->architecture().writePortCount();
265 reads = entry->architecture().readPortCount();
266 bidirPorts = entry->architecture().bidirPortCount();
267 latency = entry->architecture().latency();
268 maxReads = entry->architecture().maxReads();
269 maxWrites = entry->architecture().maxWrites();
270 guardSupport = entry->architecture().hasGuardSupport();
271 guardLatency = entry->architecture().guardLatency();
272 } else {
273 // entry has no architecture
274 continue;
275 }
276 EntryKeyProperty* rfileProperty =
278 CostDBEntryKey* newEntryKey =
279 new CostDBEntryKey(rfileProperty);
280
281 newEntryKey->addField(
282 new EntryKeyField(
283 new EntryKeyDataInt(size),
284 rfileProperty->fieldProperty(
286 newEntryKey->addField(
287 new EntryKeyField(
288 new EntryKeyDataInt(reads),
289 rfileProperty->fieldProperty(
291 newEntryKey->addField(
292 new EntryKeyField(
293 new EntryKeyDataInt(writes),
294 rfileProperty->fieldProperty(
296 newEntryKey->addField(
297 new EntryKeyField(
298 new EntryKeyDataInt(bidirPorts),
299 rfileProperty->fieldProperty(
301 newEntryKey->addField(
302 new EntryKeyField(
303 new EntryKeyDataInt(bitWidth),
304 rfileProperty->fieldProperty(
306 newEntryKey->addField(
307 new EntryKeyField(
308 new EntryKeyDataInt(latency),
309 rfileProperty->fieldProperty(
311 newEntryKey->addField(
312 new EntryKeyField(
313 new EntryKeyDataInt(maxReads),
314 rfileProperty->fieldProperty(
316 newEntryKey->addField(
317 new EntryKeyField(
318 new EntryKeyDataInt(maxWrites),
319 rfileProperty->fieldProperty(
321 newEntryKey->addField(
322 new EntryKeyField(
323 new EntryKeyDataBool(guardSupport),
324 rfileProperty->fieldProperty(
326 newEntryKey->addField(
327 new EntryKeyField(
328 new EntryKeyDataInt(guardLatency),
329 rfileProperty->fieldProperty(
331
332 CostEstimationData query;
333 query.setRFReference(*id);
334 query.setPluginID(rfEstimatorPluginID);
335 std::set<RowID> dataIDs = hdb_.costEstimationDataIDs(query,
336 useCompiledQueries);
337 std::set<RowID>::const_iterator dataID = dataIDs.begin();
338 for (; dataID != dataIDs.end(); dataID++) {
340 if (data.name() == "area") {
341 area = data.value().doubleValue();
342 continue;
343 }
344 if (data.name() == "computation_delay") {
345 delay = data.value().doubleValue();
346 continue;
347 }
348 }
349 CostDBEntryStatsRF* newStatistics =
350 new CostDBEntryStatsRF(area, delay);
351 dataID = dataIDs.begin();
352
353 for (; dataID != dataIDs.end(); dataID++) {
355 const std::string dataName = data.name();
356 // input delays
357
358 // this case is for one delay/unit case
359 if (dataName == "input_delay") {
360 newStatistics->setDelay(
361 "input_delay", data.value().doubleValue());
362 continue;
363 }
364 boost::smatch match =
365 getValues(dataName, "input_delay[ \t]*(\\S+)");
366 if (match.size() == 2) {
367 // match[0] contains the whole string
368 // match[1] contains the port name
369 newStatistics->setDelay(
370 match[1], data.value().doubleValue());
371 continue;
372 }
373
374 // output delays
375
376 // this case is for one delay/unit case
377 if (dataName == "output_delay") {
378 newStatistics->setDelay(
379 "output_delay", data.value().doubleValue());
380 continue;
381 }
382
383 match = getValues(dataName, "output_delay[ \t]*(\\S+)");
384 if (match.size() == 2) {
385 // match[0] contains the whole string
386 // match[1] contains the port name
387 newStatistics->setDelay(
388 match[1], data.value().doubleValue());
389 continue;
390 }
391
392 if (dataName == "output_delay") {
393 // match[0] contains the whole string
394 // match[1] contains the name of the port
395 newStatistics->setDelay(
396 match[1], data.value().doubleValue());
397 continue;
398 }
399
400 // access energies
401 match =
402 getValues(dataName, "rf_access_energy ([0-9])* ([0-9])*");
403 if (match.size() == 3) {
404 // match[0] contains the whole string
405 // match[1] contains the number of reads
406 // match[2] contains the number of writes
407 newStatistics->setEnergyReadWrite(
409 match[1]), Conversion::toInt(match[2]),
410 data.value().doubleValue());
411 continue;
412 }
413
414 // idle energy
415 if (dataName == "rf_idle_energy") {
416 newStatistics->setEnergyIdle(data.value().doubleValue());
417 continue;
418 }
419 }
420
421 CostDBEntry* newEntry =
422 new CostDBEntry(newEntryKey);
423 newEntry->addStatistics(newStatistics);
424 insertEntry(newEntry);
425 }
426 registerFilesBuilt_ = true;
427 if (useCompiledQueries) {
429 }
430}
431
432/**
433 * Reads function units from the set HDB and builds function unit entries in to
434 * the cost database.
435 *
436 * @param fuEstimatorPluginName Name of the function unit estimator plugin
437 * which cost data are read and used in the cost database.
438 * @exception Exception if an error occured during the cost database building.
439 */
440void
441CostDatabase::buildFunctionUnits(const std::string& fuEstimatorPluginName) {
442 // find out the function unit estimator plugin id
443 std::set<RowID> pluginIDs = hdb_.costFunctionPluginIDs();
444 RowID fuEstimatorPluginID = 0;
445 std::set<RowID>::const_iterator pluginID = pluginIDs.begin();
446 for (; pluginID != pluginIDs.end(); pluginID++) {
448 if (plugin->name() == fuEstimatorPluginName) {
449 fuEstimatorPluginID = *pluginID;
450 break;
451 }
452 }
453
454 bool useCompiledQueries = false;
455
456 // Function units
457 std::set<RowID> fus = hdb_.fuEntryIDs();
458 std::set<RowID>::const_iterator id = fus.begin();
459 for (; id != fus.end(); id++) {
460 // fetch all data from the entry and put it to CostDB
461 set<string> operations;
462 set<vector<string> > parameters;
463 vector<string> portSet;
464#ifdef CAUSE_COMPILER_WARNING_AND_NOT_USED_REMOVE_IF_NOT_EVER_NEEDED
465 int operationCount = 0;
466 int latency = 0;
467#endif
468 double area = 0;
469 double delay = 0;
470 int width = 0;
471
472 const HDB::FUEntry* entry = hdb_.fuByEntryID(*id);
473
474 if (entry->hasCostFunction()) {
475 if (entry->costFunction().id() != fuEstimatorPluginID) {
476 // wrong type of estimation plugin
477 continue;
478 }
479 } else {
480 // no cost function plugin set.
481 continue;
482 }
483
484 if (entry->hasArchitecture()) {
485#ifdef CAUSE_COMPILER_WARNING_AND_NOT_USED_REMOVE_IF_NOT_EVER_NEEDED
486 operationCount = entry->architecture().architecture().
487 operationCount();
488 latency = entry->architecture().architecture().maxLatency();
489#endif
490 int ports = entry->architecture().architecture().portCount();
491 int i;
492 for (i = 0; i < ports; i++) {
493 BaseFUPort* port =
494 entry->architecture().architecture().port(i);
495 if (dynamic_cast<FUPort*>(port) != NULL) {
496 FUPort* fuPort = dynamic_cast<FUPort*>(port);
498 fuPort->name())) {
499 // parameterized port
500 break;
501 } else {
502 if (width == 0) {
503 width = fuPort->width();
504 } else if (width != fuPort->width()) {
505 break;
506 }
507 }
508 }
509 }
510 if (i != ports) {
511 // Some port has parameterized width or
512 // port widths are not equal and entry cannot be used.
513 continue;
514 }
515 } else {
516 continue;
517 }
518 EntryKeyProperty* unitProperty =
520 CostDBEntryKey* newEntryKey =
521 new CostDBEntryKey(unitProperty);
522 newEntryKey->addField(
523 new EntryKeyField(
524 new EntryKeyDataInt(width),
525 unitProperty->fieldProperty(
527 newEntryKey->addField(
528 new EntryKeyField(
530 &(entry->architecture().architecture())),
531 unitProperty->fieldProperty(
533 CostEstimationData query;
534 query.setFUReference(*id);
535 query.setPluginID(fuEstimatorPluginID);
536 std::set<RowID> dataIDs = hdb_.costEstimationDataIDs(query,
537 useCompiledQueries);
538 std::set<RowID>::const_iterator dataID = dataIDs.begin();
539 for (; dataID != dataIDs.end(); dataID++) {
541 if (data.name() == "area") {
542 area = data.value().doubleValue();
543 continue;
544 }
545 if (data.name() == "computation_delay") {
546 delay = data.value().doubleValue();
547 continue;
548 }
549 }
550
551 CostDBEntryStatsFU* newStatistics =
552 new CostDBEntryStatsFU(area, delay);
553
554 dataID = dataIDs.begin();
555 for (; dataID != dataIDs.end(); dataID++) {
557 const std::string dataName = data.name();
558 // input delays
559
560 // this case is for one delay/unit case
561 if (dataName == "input_delay") {
562 newStatistics->setDelay("input_delay",
563 data.value().doubleValue());
564 continue;
565 }
566
567 boost::smatch match =
568 getValues(dataName, "input_delay[ \t]*(\\S+)");
569 if (match.size() == 2) {
570 // match[0] contains the whole string
571 // match[1] contains the name of the port
572 newStatistics->setDelay(
573 match[1], data.value().doubleValue());
574 continue;
575 }
576
577 // output delays
578
579 // this case is for one delay/unit case
580 if (dataName == "output_delay") {
581 newStatistics->setDelay(
582 "output_delay", data.value().doubleValue());
583 continue;
584 }
585
586 match = getValues(
587 dataName, "output_delay[ \t]*(\\S+)");
588 if (match.size() == 2) {
589 // match[0] contains the whole string
590 // match[1] contains the name of the port
591 newStatistics->setDelay(
592 match[1], data.value().doubleValue());
593 continue;
594 }
595 match = getValues(
596 dataName, "(output_delay)");
597 if (match.size() == 2) {
598 // match[0] contains the whole string
599 // match[1] contains the name of the port
600 newStatistics->setDelay(
601 match[1], data.value().doubleValue());
602 continue;
603 }
604
605 // operation energies
606 match = getValues(
607 dataName, "operation_execution_energy (\\S+)");
608 if (match.size() == 2) {
609 // match[0] contains the whole string
610 // match[1] contains the operation name
611 newStatistics->setEnergyOperation(
612 match[1], data.value().doubleValue());
613 continue;
614 }
615
616 // idle energy
617 if (dataName == "fu_idle_energy") {
618 newStatistics->setEnergyIdle(data.value().doubleValue());
619 continue;
620 }
621 }
622 CostDBEntry* newEntry =
623 new CostDBEntry(newEntryKey);
624 newEntry->addStatistics(newStatistics);
625
626 insertEntry(newEntry);
627 }
628 functionUnitsBuilt_ = true;
629 if (useCompiledQueries) {
631 }
632}
633
634/**
635 * Reads buses from the set HDB and builds bus entries in to the cost database.
636 *
637 * @param busEstimatorPluginName Name of the bus estimator plugin
638 * which cost data are read and used in the cost database.
639 * @exception Exception if an error occured during the cost database building.
640 */
641void
642CostDatabase::buildBuses(const std::string& busEstimatorPluginName) {
643 // find out the plugin id that estimates buses
644 std::set<RowID> pluginIDs = hdb_.costFunctionPluginIDs();
645 RowID busEstimatorPluginID = 0;
646 std::set<RowID>::const_iterator pluginID = pluginIDs.begin();
647 for (; pluginID != pluginIDs.end(); pluginID++) {
649 if (plugin->name() == busEstimatorPluginName) {
650 busEstimatorPluginID = *pluginID;
651 break;
652 }
653 }
654
655 // bus part
656 std::set<RowID> buses = hdb_.busEntryIDs();
657 std::set<RowID>::const_iterator id = buses.begin();
658 for (; id != buses.end(); id++) {
659 // fetch all data from the entry and put it to CostDB
660 int bitWidth = 0;
661 int fanin = 0;
662 int fanout = 0;
663#ifdef CAUSE_COMPILER_WARNING_AND_NOT_USED_REMOVE_IF_NOT_EVER_NEEDED
664 int cntrlDelay = 0;
665#endif
666 double area = 0.0;
667 double delay = 0.0;
668 double activeEnergy = 0.0;
669 double idleEnergy = 0.0;
670
671 CostEstimationData query;
672 query.setBusReference(*id);
673 query.setPluginID(busEstimatorPluginID);
674 std::set<RowID> dataIDs = hdb_.costEstimationDataIDs(query);
675 std::set<RowID>::const_iterator dataID = dataIDs.begin();
676 for (; dataID != dataIDs.end(); dataID++) {
678 if (data.name() == "area") {
679 area = data.value().doubleValue();
680 continue;
681 }
682 if (data.name() == "computation_delay") {
683 delay = data.value().doubleValue();
684 continue;
685 }
686 if (data.name() == "fanin") {
687 fanin = data.value().integerValue();
688 continue;
689 }
690 if (data.name() == "fanout") {
691 fanout = data.value().integerValue();
692 continue;
693 }
694 if (data.name() == "dataw") {
695 bitWidth = data.value().integerValue();
696 continue;
697 }
698 if (data.name() == "cntrl_delay") {
699#ifdef CAUSE_COMPILER_WARNING_AND_NOT_USED_REMOVE_IF_NOT_EVER_NEEDED
700 cntrlDelay = data.value().integerValue();
701#endif
702 continue;
703 }
704 if (data.name() == "energy") {
705 activeEnergy = data.value().doubleValue();
706 continue;
707 }
708 if (data.name() == "idle_energy") {
709 idleEnergy = data.value().doubleValue();
710 continue;
711 }
712 }
713
714 CostDBEntryStats* newStatistics =
715 new CostDBEntryStats(area, delay);
716 newStatistics->setEnergyActive(activeEnergy);
717 newStatistics->setEnergyIdle(idleEnergy);
718
719 EntryKeyProperty* busProperty =
721 CostDBEntryKey* newEntryKey =
722 new CostDBEntryKey(busProperty);
723
724 newEntryKey->addField(
725 new EntryKeyField(
726 new EntryKeyDataInt(fanin),
727 busProperty->fieldProperty(
729 newEntryKey->addField(
730 new EntryKeyField(
731 new EntryKeyDataInt(fanout),
732 busProperty->fieldProperty(
734 newEntryKey->addField(
735 new EntryKeyField(
736 new EntryKeyDataInt(bitWidth),
737 busProperty->fieldProperty(
739
740 CostDBEntry* newEntry =
741 new CostDBEntry(newEntryKey);
742 newEntry->addStatistics(newStatistics);
743
744 insertEntry(newEntry);
745 }
746 busesBuilt_ = true;
747}
748
749/**
750 * Reads sockets from the set HDB and builds socket entries in to the cost
751 * database.
752 *
753 * @param socketEstimatorPluginName Name of the socket estimator plugin
754 * which cost data are read and used in the cost database.
755 * @exception Exception if an error occured during the cost database building.
756 */
757void
758CostDatabase::buildSockets(const std::string& socketEstimatorPluginName) {
759 // find out the plugin id that estimates sockets
760 std::set<RowID> pluginIDs = hdb_.costFunctionPluginIDs();
761 RowID socketEstimatorPluginID = 0;
762 std::set<RowID>::const_iterator pluginID = pluginIDs.begin();
763 for (; pluginID != pluginIDs.end(); pluginID++) {
765 if (plugin->name() == socketEstimatorPluginName) {
766 socketEstimatorPluginID = *pluginID;
767 break;
768 }
769 }
770
771 // socket part
772 std::set<RowID> sockets = hdb_.socketEntryIDs();
773 std::set<RowID>::const_iterator id = sockets.begin();
774 for (; id != sockets.end(); id++) {
775 // fetch all data from the entry and put it to CostDB
776 int bitWidth = 0;
777 int fanin = 0;
778 int fanout = 0;
779 int cntrlDelay = 0;
780 double area = 0.0;
781 double delay = 0.0;
782 double activeEnergy = 0.0;
783 double idleEnergy = 0.0;
784
785 CostEstimationData query;
786 query.setSocketReference(*id);
787 query.setPluginID(socketEstimatorPluginID);
788 std::set<RowID> dataIDs = hdb_.costEstimationDataIDs(query);
789 std::set<RowID>::const_iterator dataID = dataIDs.begin();
790 for (; dataID != dataIDs.end(); dataID++) {
792 if (data.name() == "area") {
793 area = data.value().doubleValue();
794 continue;
795 }
796 if (data.name() == "computation_delay") {
797 delay = data.value().doubleValue();
798 continue;
799 }
800 if (data.name() == "fanin") {
801 fanin = data.value().integerValue();
802 continue;
803 }
804 if (data.name() == "fanout") {
805 fanout = data.value().integerValue();
806 continue;
807 }
808 if (data.name() == "dataw") {
809 bitWidth = data.value().integerValue();
810 continue;
811 }
812 if (data.name() == "cntrl_delay") {
813 cntrlDelay = data.value().integerValue();
814 continue;
815 }
816 if (data.name() == "energy") {
817 activeEnergy = data.value().doubleValue();
818 continue;
819 }
820 if (data.name() == "idle_energy") {
821 idleEnergy = data.value().doubleValue();
822 continue;
823 }
824 }
825
826 CostDBEntryStats* newStatistics =
827 new CostDBEntryStats(area, delay);
828 // this is contol data, not real data and not really needed
829 newStatistics->setDelay("cntrl_delay", cntrlDelay);
830 newStatistics->setEnergyActive(activeEnergy);
831 newStatistics->setEnergyIdle(idleEnergy);
832
833 EntryKeyProperty* socketProperty = NULL;
834 CostDBEntryKey* newEntryKey = NULL;
835 if (fanin != 0) {
836 socketProperty =
838 newEntryKey =
839 new CostDBEntryKey(socketProperty);
840
841 // fanin needed only in input sockets
842 newEntryKey->addField(
843 new EntryKeyField(
844 new EntryKeyDataInt(fanin),
845 socketProperty->fieldProperty(
847 }
848 // else socket is output socket
849 else {
850 socketProperty =
852 newEntryKey =
853 new CostDBEntryKey(socketProperty);
854
855 // fanout only needed in output sockets
856 newEntryKey->addField(
857 new EntryKeyField(
858 new EntryKeyDataInt(fanout),
859 socketProperty->fieldProperty(
861 }
862
863 newEntryKey->addField(
864 new EntryKeyField(
865 new EntryKeyDataInt(bitWidth),
866 socketProperty->fieldProperty(
868
869 CostDBEntry* newEntry =
870 new CostDBEntry(newEntryKey);
871 newEntry->addStatistics(newStatistics);
872
873 insertEntry(newEntry);
874 }
875 socketsBuilt_ = true;
876}
877
878/**
879 * Searches entries from the database matching certain search key with
880 * specific type of matches.
881 *
882 * @param searchKey Search key.
883 * @param match Type of matches.
884 * @return Entries matching the search.
885 * @exception KeyNotFound If search key type is not found.
886 */
889 const CostDBEntryKey& searchKey,
890 const CostDBTypes::MatchTypeTable& match) const {
891 EntryMap::const_iterator i = entries_.find(searchKey.type());
892
893 // entries of searched type are in the list
894 if (i == entries_.end()) {
895 throw KeyNotFound(__FILE__, __LINE__, "CostDatabase::search");
896 }
897
898 return searchStrategy_->search(searchKey, i->second, match);
899}
900
901/**
902 * Inserts an entry into the database.
903 *
904 * @param entry Database entry.
905 * @exception ObjectAlreadyExists If inserted entry is already inserted.
906 */
907void
909 EntryMap::iterator i = entries_.find(entry->type());
910
911 if (i == entries_.end()) {
912 CostDBTypes::EntryTable newEntries;
913 newEntries.push_back(entry);
914 entries_.insert(pair<const EntryKeyProperty*, CostDBTypes::EntryTable>(
915 entry->type(), newEntries));
916 } else {
917 // if the database already contains an entry with same search
918 // key, the statistics of the new entry will be added into the
919 // existing entry
920 for (CostDBTypes::EntryTable::iterator j = i->second.begin();
921 j != i->second.end(); j++) {
922
923 if ((*j)->isEqualKey(*entry)) {
924 if (*j == entry) {
925 throw ObjectAlreadyExists(__FILE__, __LINE__,
926 "CostDatabase::insertEntry");
927 }
928 for (int k = 0; k < entry->statisticsCount(); k++) {
929 CostDBEntryStats* newStats = entry->statistics(k).copy();
930 (*j)->addStatistics(newStats);
931 }
932 return;
933 }
934 }
935 i->second.push_back(entry);
936 }
937}
938
939/**
940 * Returns true if register files are built in the cost database.
941 *
942 * @return True if register files are built in the cost database.
943 */
944bool
948
949/**
950 * Returns true if function units are built in the cost database.
951 *
952 * @return True if function units are built in the cost database.
953 */
954bool
958
959/**
960 * Returns true if buses are built in the cost database.
961 *
962 * @return True if buses are built in the cost database.
963 */
964bool
968
969/**
970 * Returns true if sockets are built in the cost database.
971 *
972 * @return True if sockets are built in the cost database.
973 */
974bool
978
979/**
980 * Replaces search strategy by taking a copy of another one.
981 *
982 * @param strategy Search strategy.
983 */
984void
986 if (searchStrategy_ != NULL) {
987 delete searchStrategy_;
988 }
989 searchStrategy_ = strategy->copy();
990}
991
992/**
993 * Returns the matching strings out of the text using regexp.
994 *
995 * @param text String the regular expression is used for.
996 * @param regex Regular expression to be matched with the text.
997 * @return Returns the matched string patterns from the text or empty smatch
998 * if matching failed.
999 **/
1000boost::smatch
1001CostDatabase::getValues(const string& text, const string& regex) {
1002 boost::regex regx(regex + ".*");
1003 boost::smatch what;
1004 if (boost::regex_match(text, what, regx, boost::match_extra)) {
1005 return what;
1006 }
1007 boost::smatch empty;
1008 return empty;
1009}
#define POP_CLANG_DIAGS
#define IGNORE_CLANG_WARNING(X)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
find Finds info of the inner loops in the false
static int toInt(const T &source)
void addField(EntryKeyField *field)
const EntryKeyProperty * type() const
virtual void setEnergyOperation(const std::string &name, double energy)
virtual void setEnergyReadWrite(int reads, int writes, double energy)
virtual CostDBEntryStats * copy() const
virtual void setEnergyIdle(double energy)
virtual void setEnergyActive(double energy)
virtual void setDelay(const std::string &port, double delay)
const EntryKeyProperty * type() const
void addStatistics(CostDBEntryStats *newStats)
const CostDBEntryStats & statistics(int index) const
int statisticsCount() const
static const std::string EKF_READ_PORTS
Field type for number of read ports in an entry.
static const std::string EK_INPUT_SOCKET
Entry type for input sockets.
static const std::string EKF_INPUT_SOCKET_FANIN
Field type for fanin of input socket in an entry.
static const std::string EKF_OUTPUT_SOCKET_FANOUT
Field type for fanout of output socket in an entry.
static const std::string EKF_MAX_WRITES
Field type for number of max simultaneous writes in an entry.
static const std::string EK_SOCKET
Entry type for sockets.
static const std::string EK_UNIT
Entry type for function units.
static const std::string EKF_BIDIR_PORTS
Field type for number of bidirectional ports in an entry.
static const std::string EK_INLINE_IMM_SOCKET
Entry type for immediate sockets.
static const std::string EKF_GUARD_SUPPORT
Field type for guard support in an entry.
std::vector< MatchType * > MatchTypeTable
Table of types of match.
static const std::string EKF_BUS_FANOUT
Field type for fanout of bus in an entry.
static const std::string EKF_LATENCY
Field type for latency of an entry.
static const std::string EK_OUTPUT_SOCKET
Entry type for output sockets.
static const std::string EKF_GUARD_LATENCY
Field type for guard latency in an entry.
static const std::string EKF_FUNCTION_UNIT
Field type for function unit entry;.
static const std::string EKF_MAX_READS
Field type for number of max simultaneous reads in an entry.
static const std::string EKF_WRITE_PORTS
Field type for number of write ports in an entry.
static const std::string EK_RFILE
Entry type for register files.
static const std::string EK_MBUS
Entry type for move bus.
static const std::string EKF_BUS_FANIN
Field type for fanin of bus in an entry.
static const std::string EKF_NUM_REGISTERS
Field type for number of registers in an entry.
std::vector< CostDBEntry * > EntryTable
Table of database entries.
static const std::string EKF_BIT_WIDTH
Field type for bit width of an entry.
bool hasCostDatabase(const HDB::HDBManager &hdb)
static CostDatabaseRegistry & instance()
CostDatabase & costDatabase(const HDB::HDBManager &hdb)
void addCostDatabase(CostDatabase *costDatabase, const HDB::HDBManager &hdb)
boost::smatch getValues(const std::string &text, const std::string &regex)
Finds string matches using regular expressions.
void buildBuses(const std::string &busEstimatorPluginName)
static CostDatabase & instance(const HDB::HDBManager &hdb)
void buildSockets(const std::string &socketEstimatorPluginName)
void setSearchStrategy(SearchStrategy *strategy)
void buildRegisterFiles(const std::string &rfEstimatorPluginName)
void buildFunctionUnits(const std::string &fuEstimatorPluginName)
void buildDefaultCostDatabase()
static CostDatabase * instance_
Unique instance of the class.
bool busesBuilt_
Flag to note is buses built.
bool isSocketsBuilt()
bool isRegisterFilesBuilt()
virtual ~CostDatabase()
bool socketsBuilt_
Flag to note is sockets built.
bool functionUnitsBuilt_
Flag to note is function units built.
CostDatabase(const HDB::HDBManager &hdb)
CostDatabase must be created with instance() method.
void insertEntry(CostDBEntry *entry)
bool registerFilesBuilt_
Flag to note is register files built.
bool isBusesBuilt()
const HDB::HDBManager & hdb_
HDB used for creating cost database.
EntryMap entries_
Database entries.
CostDBTypes::EntryTable search(const CostDBEntryKey &searchKey, const CostDBTypes::MatchTypeTable &match) const
bool isFunctionUnitsBuilt()
SearchStrategy * searchStrategy_
Search strategy used for queries.
DataObject value() const
void setBusReference(RowID busEntryID)
std::string name() const
void setPluginID(RowID pluginID)
void setRFReference(RowID rfEntryID)
void setSocketReference(RowID socketEntryID)
void setFUReference(RowID fuEntryID)
virtual double doubleValue() const
virtual int integerValue() const
static EntryKeyProperty * find(std::string type)
static EntryKeyProperty * create(std::string type)
EntryKeyFieldProperty * createFieldProperty(std::string field)
EntryKeyFieldProperty * fieldProperty(std::string field) const
bool hasParameterizedWidth(const std::string &port) const
TTAMachine::FunctionUnit & architecture() const
FUArchitecture & architecture() const
Definition FUEntry.cc:129
virtual bool hasArchitecture() const
Definition FUEntry.cc:117
bool hasCostFunction() const
Definition HDBEntry.cc:99
CostFunctionPlugin & costFunction() const
Definition HDBEntry.cc:111
FUEntry * fuByEntryID(RowID id) const
CostFunctionPlugin * costFunctionPluginByID(RowID pluginID) const
virtual std::set< RowID > costEstimationDataIDs(const CostEstimationData &match, bool useCompiledQueries=false, RelationalDBQueryResult *compiledQuery=NULL) const
CostEstimationData costEstimationData(RowID id) const
std::set< RowID > socketEntryIDs() const
std::set< RowID > rfEntryIDs() const
std::set< RowID > costFunctionPluginIDs() const
std::set< RowID > busEntryIDs() const
RFEntry * rfByEntryID(RowID id) const
std::set< RowID > fuEntryIDs() const
virtual void deleteCostEstimationDataIDsQueries() const =0
bool hasGuardSupport() const
RFArchitecture & architecture() const
Definition RFEntry.cc:145
virtual bool hasArchitecture() const
Definition RFEntry.cc:117
virtual CostDBTypes::EntryTable search(const CostDBEntryKey &searchKey, CostDBTypes::EntryTable components, const CostDBTypes::MatchTypeTable &match)=0
virtual SearchStrategy * copy() const =0
virtual int width() const
virtual int maxLatency() const
virtual BaseFUPort * port(const std::string &name) const
virtual std::string name() const
Definition Port.cc:141
virtual int portCount() const
Definition Unit.cc:135