OpenASIP  2.0
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"
39 IGNORE_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"
60 #include "CostDatabaseRegistry.hh"
61 
62 using std::pair;
63 using std::string;
64 using std::set;
65 using std::vector;
66 using namespace HDB;
67 using 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  */
179 void
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  */
203 void
204 CostDatabase::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++) {
210  CostFunctionPlugin* plugin = hdb_.costFunctionPluginByID(*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  */
440 void
441 CostDatabase::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++) {
447  CostFunctionPlugin* plugin = hdb_.costFunctionPluginByID(*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);
497  if (entry->architecture().hasParameterizedWidth(
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  */
641 void
642 CostDatabase::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++) {
648  CostFunctionPlugin* plugin = hdb_.costFunctionPluginByID(*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  */
757 void
758 CostDatabase::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++) {
764  CostFunctionPlugin* plugin = hdb_.costFunctionPluginByID(*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  */
907 void
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  */
944 bool
946  return registerFilesBuilt_;
947 }
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  */
954 bool
956  return functionUnitsBuilt_;
957 }
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  */
964 bool
966  return busesBuilt_;
967 }
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  */
974 bool
976  return socketsBuilt_;
977 }
978 
979 /**
980  * Replaces search strategy by taking a copy of another one.
981  *
982  * @param strategy Search strategy.
983  */
984 void
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  **/
1000 boost::smatch
1001 CostDatabase::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 }
CostDatabase
Definition: CostDatabase.hh:64
HDB::FUEntry
Definition: FUEntry.hh:49
CostDBTypes::EK_RFILE
static const std::string EK_RFILE
Entry type for register files.
Definition: CostDBTypes.hh:65
CostDBEntry::statisticsCount
int statisticsCount() const
Definition: CostDBEntry.cc:224
CostDatabase::buildSockets
void buildSockets(const std::string &socketEstimatorPluginName)
Definition: CostDatabase.cc:758
HDB::HDBEntry::costFunction
CostFunctionPlugin & costFunction() const
Definition: HDBEntry.cc:111
POP_CLANG_DIAGS
#define POP_CLANG_DIAGS
Definition: CompilerWarnings.hh:96
HDB::RFArchitecture::maxReads
int maxReads() const
Definition: RFArchitecture.cc:447
CostDBTypes::EKF_GUARD_SUPPORT
static const std::string EKF_GUARD_SUPPORT
Field type for guard support in an entry.
Definition: CostDBTypes.hh:104
SearchStrategy::copy
virtual SearchStrategy * copy() const =0
CostDBTypes::EKF_BIT_WIDTH
static const std::string EKF_BIT_WIDTH
Field type for bit width of an entry.
Definition: CostDBTypes.hh:78
CostDBTypes::MatchTypeTable
std::vector< MatchType * > MatchTypeTable
Table of types of match.
Definition: CostDBTypes.hh:114
CostDatabase::hdb_
const HDB::HDBManager & hdb_
HDB used for creating cost database.
Definition: CostDatabase.hh:107
CostEstimationData::name
std::string name() const
Definition: CostEstimationData.cc:58
HDB::FUArchitecture::hasParameterizedWidth
bool hasParameterizedWidth(const std::string &port) const
Definition: FUArchitecture.cc:86
CostDBEntryKey::type
const EntryKeyProperty * type() const
HDB
Definition: CostDatabase.hh:49
CostDatabase::searchStrategy_
SearchStrategy * searchStrategy_
Search strategy used for queries.
Definition: CostDatabase.hh:103
CostDatabaseRegistry::costDatabase
CostDatabase & costDatabase(const HDB::HDBManager &hdb)
Definition: CostDatabaseRegistry.cc:79
CostDatabase::getValues
boost::smatch getValues(const std::string &text, const std::string &regex)
Finds string matches using regular expressions.
Definition: CostDatabase.cc:1001
CostDatabase::buildRegisterFiles
void buildRegisterFiles(const std::string &rfEstimatorPluginName)
Definition: CostDatabase.cc:204
FUArchitecture.hh
HDB::RFArchitecture::latency
int latency() const
Definition: RFArchitecture.cc:497
CostDatabaseRegistry
Definition: CostDatabaseRegistry.hh:46
EntryKeyProperty::create
static EntryKeyProperty * create(std::string type)
Definition: EntryKeyProperty.cc:125
CostDBTypes::EKF_WRITE_PORTS
static const std::string EKF_WRITE_PORTS
Field type for number of write ports in an entry.
Definition: CostDBTypes.hh:88
HDB::HDBManager::costFunctionPluginIDs
std::set< RowID > costFunctionPluginIDs() const
Definition: HDBManager.cc:6553
HDB::CostFunctionPlugin::id
int id() const
Definition: CostFunctionPlugin.cc:64
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
CostDBTypes::EK_INLINE_IMM_SOCKET
static const std::string EK_INLINE_IMM_SOCKET
Entry type for immediate sockets.
Definition: CostDBTypes.hh:75
HDB::RFEntry
Definition: RFEntry.hh:47
IGNORE_CLANG_WARNING
#define IGNORE_CLANG_WARNING(X)
Definition: CompilerWarnings.hh:85
CostDBTypes::EntryTable
std::vector< CostDBEntry * > EntryTable
Table of database entries.
Definition: CostDBTypes.hh:111
HDB::FUArchitecture::architecture
TTAMachine::FunctionUnit & architecture() const
Definition: FUArchitecture.cc:131
CostDBEntry::addStatistics
void addStatistics(CostDBEntryStats *newStats)
Definition: CostDBEntry.cc:213
CostDatabase::isBusesBuilt
bool isBusesBuilt()
Definition: CostDatabase.cc:965
RowID
int RowID
Type definition of row ID in relational databases.
Definition: DBTypes.hh:37
CostEstimationData::setFUReference
void setFUReference(RowID fuEntryID)
SearchStrategy
Definition: SearchStrategy.hh:45
EntryKeyField
Definition: EntryKeyField.hh:45
CostEstimationData::setRFReference
void setRFReference(RowID rfEntryID)
CostDatabaseRegistry.hh
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
CostDatabaseRegistry::addCostDatabase
void addCostDatabase(CostDatabase *costDatabase, const HDB::HDBManager &hdb)
Definition: CostDatabaseRegistry.cc:95
CostDBTypes::EK_UNIT
static const std::string EK_UNIT
Entry type for function units.
Definition: CostDBTypes.hh:63
CostDBEntryStatsRF
Definition: CostDBEntryStatsRF.hh:45
HDB::HDBManager::costEstimationData
CostEstimationData costEstimationData(RowID id) const
Definition: HDBManager.cc:6323
HDB::HDBManager::costFunctionPluginByID
CostFunctionPlugin * costFunctionPluginByID(RowID pluginID) const
Definition: HDBManager.cc:6631
CostDatabase::buildDefaultCostDatabase
void buildDefaultCostDatabase()
Definition: CostDatabase.cc:180
CostDBEntryStats.hh
TTAMachine::FunctionUnit::maxLatency
virtual int maxLatency() const
Definition: FunctionUnit.cc:443
NotAvailable
Definition: Exception.hh:728
HDB::HDBEntry::hasCostFunction
bool hasCostFunction() const
Definition: HDBEntry.cc:99
HDB::RFArchitecture::width
int width() const
Definition: RFArchitecture.cc:343
CostDBEntryStatsFU::setEnergyOperation
virtual void setEnergyOperation(const std::string &name, double energy)
Definition: CostDBEntryStatsFU.cc:155
HDB::RFEntry::architecture
RFArchitecture & architecture() const
Definition: RFEntry.cc:145
DataObject::doubleValue
virtual double doubleValue() const
Definition: DataObject.cc:386
CostDatabaseRegistry::instance
static CostDatabaseRegistry & instance()
Definition: CostDatabaseRegistry.cc:60
CostDBTypes::EKF_NUM_REGISTERS
static const std::string EKF_NUM_REGISTERS
Field type for number of registers in an entry.
Definition: CostDBTypes.hh:84
DataObject::integerValue
virtual int integerValue() const
Definition: DataObject.cc:204
TTAMachine::FUPort
Definition: FUPort.hh:46
CostDatabase::busesBuilt_
bool busesBuilt_
Flag to note is buses built.
Definition: CostDatabase.hh:113
HDB::FUEntry::hasArchitecture
virtual bool hasArchitecture() const
Definition: FUEntry.cc:117
HWOperation.hh
CostDBEntry
Definition: CostDBEntry.hh:52
CostDBEntryStatsFU
Definition: CostDBEntryStatsFU.hh:44
CostDatabase::search
CostDBTypes::EntryTable search(const CostDBEntryKey &searchKey, const CostDBTypes::MatchTypeTable &match) const
Definition: CostDatabase.cc:888
CostEstimationData::setBusReference
void setBusReference(RowID busEntryID)
CostDBEntryKey::addField
void addField(EntryKeyField *field)
Definition: CostDBEntryKey.cc:88
HDB::RFArchitecture::maxWrites
int maxWrites() const
Definition: RFArchitecture.cc:472
Conversion.hh
HDB::HDBManager::fuEntryIDs
std::set< RowID > fuEntryIDs() const
Definition: HDBManager.cc:2035
CostDBTypes::EKF_BUS_FANIN
static const std::string EKF_BUS_FANIN
Field type for fanin of bus in an entry.
Definition: CostDBTypes.hh:96
HDB::FUEntry::architecture
FUArchitecture & architecture() const
Definition: FUEntry.cc:129
Application.hh
FUEntry.hh
CostDBEntryStats::setDelay
virtual void setDelay(const std::string &port, double delay)
Definition: CostDBEntryStats.cc:446
CostDatabase::CostDatabase
CostDatabase(const HDB::HDBManager &hdb)
CostDatabase must be created with instance() method.
Definition: CostDatabase.cc:76
CostDBTypes::EK_OUTPUT_SOCKET
static const std::string EK_OUTPUT_SOCKET
Entry type for output sockets.
Definition: CostDBTypes.hh:73
HDB::HDBManager::socketEntryIDs
std::set< RowID > socketEntryIDs() const
Definition: HDBManager.cc:2131
CostDBEntryStats::copy
virtual CostDBEntryStats * copy() const
Definition: CostDBEntryStats.cc:153
HDB::HDBManager
Definition: HDBManager.hh:82
CostDatabaseRegistry::hasCostDatabase
bool hasCostDatabase(const HDB::HDBManager &hdb)
Definition: CostDatabaseRegistry.cc:115
RFArchitecture.hh
CostDBTypes::EK_INPUT_SOCKET
static const std::string EK_INPUT_SOCKET
Entry type for input sockets.
Definition: CostDBTypes.hh:71
CostDBEntry::type
const EntryKeyProperty * type() const
Definition: CostDBEntry.cc:137
CostDBTypes::EKF_OUTPUT_SOCKET_FANOUT
static const std::string EKF_OUTPUT_SOCKET_FANOUT
Field type for fanout of output socket in an entry.
Definition: CostDBTypes.hh:102
CostDBEntryStats::setEnergyIdle
virtual void setEnergyIdle(double energy)
Definition: CostDBEntryStats.cc:338
CostDBEntry.hh
HDB::RFArchitecture::guardLatency
int guardLatency() const
Definition: RFArchitecture.cc:551
CostDBTypes::EKF_BIDIR_PORTS
static const std::string EKF_BIDIR_PORTS
Field type for number of bidirectional ports in an entry.
Definition: CostDBTypes.hh:90
EntryKeyProperty
Definition: EntryKeyProperty.hh:57
CostDBTypes::EKF_INPUT_SOCKET_FANIN
static const std::string EKF_INPUT_SOCKET_FANIN
Field type for fanin of input socket in an entry.
Definition: CostDBTypes.hh:100
CostEstimationData
Definition: CostEstimationData.hh:42
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
HDB::HDBManager::busEntryIDs
std::set< RowID > busEntryIDs() const
Definition: HDBManager.cc:2099
CostEstimationData::value
DataObject value() const
Definition: CostEstimationData.cc:73
CostDBEntryStatsRF::setEnergyReadWrite
virtual void setEnergyReadWrite(int reads, int writes, double energy)
Definition: CostDBEntryStatsRF.cc:196
EntryKeyDataFunctionUnit
Definition: EntryKeyData.hh:193
SearchStrategy.hh
HDB::HDBManager::rfEntryIDs
std::set< RowID > rfEntryIDs() const
Definition: HDBManager.cc:2067
CostDBTypes::EKF_BUS_FANOUT
static const std::string EKF_BUS_FANOUT
Field type for fanout of bus in an entry.
Definition: CostDBTypes.hh:98
CostDatabase::buildFunctionUnits
void buildFunctionUnits(const std::string &fuEstimatorPluginName)
Definition: CostDatabase.cc:441
SearchStrategy::search
virtual CostDBTypes::EntryTable search(const CostDBEntryKey &searchKey, CostDBTypes::EntryTable components, const CostDBTypes::MatchTypeTable &match)=0
CostDatabase.hh
HDB::RFArchitecture::hasGuardSupport
bool hasGuardSupport() const
Definition: RFArchitecture.cc:519
CostDBEntry::statistics
const CostDBEntryStats & statistics(int index) const
Definition: CostDBEntry.cc:236
CostDatabase::~CostDatabase
virtual ~CostDatabase()
Definition: CostDatabase.cc:137
HDB::HDBManager::costEstimationDataIDs
virtual std::set< RowID > costEstimationDataIDs(const CostEstimationData &match, bool useCompiledQueries=false, RelationalDBQueryResult *compiledQuery=NULL) const
Definition: HDBManager.cc:6778
CostDBEntryStatsRF.hh
CostDatabase::registerFilesBuilt_
bool registerFilesBuilt_
Flag to note is register files built.
Definition: CostDatabase.hh:109
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
CostDBEntryStats::setEnergyActive
virtual void setEnergyActive(double energy)
Definition: CostDBEntryStats.cc:323
CostDBTypes::EKF_MAX_WRITES
static const std::string EKF_MAX_WRITES
Field type for number of max simultaneous writes in an entry.
Definition: CostDBTypes.hh:94
CostDatabase::entries_
EntryMap entries_
Database entries.
Definition: CostDatabase.hh:105
CostEstimationData::setPluginID
void setPluginID(RowID pluginID)
ObjectAlreadyExists
Definition: Exception.hh:1002
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
CostDatabase::isSocketsBuilt
bool isSocketsBuilt()
Definition: CostDatabase.cc:975
CostDBTypes::EKF_FUNCTION_UNIT
static const std::string EKF_FUNCTION_UNIT
Field type for function unit entry;.
Definition: CostDBTypes.hh:108
FUPort.hh
HDB::RFArchitecture::readPortCount
int readPortCount() const
Definition: RFArchitecture.cc:372
EntryKeyDataInt
Definition: EntryKeyData.hh:83
HDB::RFArchitecture::size
int size() const
Definition: RFArchitecture.cc:326
CostDatabase::socketsBuilt_
bool socketsBuilt_
Flag to note is sockets built.
Definition: CostDatabase.hh:115
CostEstimationData::setSocketReference
void setSocketReference(RowID socketEntryID)
CostDBTypes::EKF_READ_PORTS
static const std::string EKF_READ_PORTS
Field type for number of read ports in an entry.
Definition: CostDBTypes.hh:86
CostDBEntryStatsFU.hh
CostDatabase::functionUnitsBuilt_
bool functionUnitsBuilt_
Flag to note is function units built.
Definition: CostDatabase.hh:111
CostDBTypes::EKF_MAX_READS
static const std::string EKF_MAX_READS
Field type for number of max simultaneous reads in an entry.
Definition: CostDBTypes.hh:92
CostFunctionPlugin.hh
CostDBEntryKey
Definition: CostDBEntryKey.hh:52
RFEntry.hh
KeyNotFound
Definition: Exception.hh:285
Conversion::toInt
static int toInt(const T &source)
CostDatabase::isRegisterFilesBuilt
bool isRegisterFilesBuilt()
Definition: CostDatabase.cc:945
EntryKeyProperty::find
static EntryKeyProperty * find(std::string type)
Definition: EntryKeyProperty.cc:150
HDB::RFArchitecture::bidirPortCount
int bidirPortCount() const
Definition: RFArchitecture.cc:422
CostDBEntryStats
Definition: CostDBEntryStats.hh:46
TTAMachine
Definition: Assembler.hh:48
EntryKeyDataBool
Definition: EntryKeyData.hh:166
CostDBTypes::EKF_GUARD_LATENCY
static const std::string EKF_GUARD_LATENCY
Field type for guard latency in an entry.
Definition: CostDBTypes.hh:106
HDBManager.hh
CostDBTypes::EK_MBUS
static const std::string EK_MBUS
Entry type for move bus.
Definition: CostDBTypes.hh:67
CostDatabase::setSearchStrategy
void setSearchStrategy(SearchStrategy *strategy)
Definition: CostDatabase.cc:985
HDB::HDBManager::deleteCostEstimationDataIDsQueries
virtual void deleteCostEstimationDataIDsQueries() const =0
CostDBTypes::EKF_LATENCY
static const std::string EKF_LATENCY
Field type for latency of an entry.
Definition: CostDBTypes.hh:82
EntryKeyProperty::createFieldProperty
EntryKeyFieldProperty * createFieldProperty(std::string field)
Definition: EntryKeyProperty.cc:79
HDB::HDBManager::fuByEntryID
FUEntry * fuByEntryID(RowID id) const
Definition: HDBManager.cc:2828
CostDatabase::insertEntry
void insertEntry(CostDBEntry *entry)
Definition: CostDatabase.cc:908
CostDBTypes::EK_SOCKET
static const std::string EK_SOCKET
Entry type for sockets.
Definition: CostDBTypes.hh:69
EntryKeyProperty::fieldProperty
EntryKeyFieldProperty * fieldProperty(std::string field) const
Definition: EntryKeyProperty.cc:104
HDB::CostFunctionPlugin::name
std::string name() const
Definition: CostFunctionPlugin.cc:84
CostDatabase::buildBuses
void buildBuses(const std::string &busEstimatorPluginName)
Definition: CostDatabase.cc:642
HDB::RFEntry::hasArchitecture
virtual bool hasArchitecture() const
Definition: RFEntry.cc:117
HDB::CostFunctionPlugin
Definition: CostFunctionPlugin.hh:43
CompilerWarnings.hh
TTAMachine::BaseFUPort::width
virtual int width() const
Definition: BaseFUPort.cc:109
HDB::RFArchitecture::writePortCount
int writePortCount() const
Definition: RFArchitecture.cc:397
FunctionUnit.hh
HDB::HDBManager::rfByEntryID
RFEntry * rfByEntryID(RowID id) const
Definition: HDBManager.cc:2885
CostDatabase::instance_
static CostDatabase * instance_
Unique instance of the class.
Definition: CostDatabase.hh:118
CostDatabase::isFunctionUnitsBuilt
bool isFunctionUnitsBuilt()
Definition: CostDatabase.cc:955
CostDatabase::instance
static CostDatabase & instance(const HDB::HDBManager &hdb)
Definition: CostDatabase.cc:166