OpenASIP  2.0
MinimalOpSetCheck.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2010 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 MinimalOpSetCheck.cc
26  *
27  * Implementation of MinimalOpSetCheck class.
28  *
29  * @author Esa Määttä 2008 (esa.maatta-no.spam-tut.fi)
30  * @author Pekka Jääskeläinen 2010
31  * @note rating: red
32  */
33 
34 #include <set>
35 #include <vector>
36 #include <string>
37 
38 #include "MinimalOpSetCheck.hh"
39 #include "FunctionUnit.hh"
40 #include "Machine.hh"
41 #include "Environment.hh"
42 #include "FullyConnectedCheck.hh"
43 #include "CIStringSet.hh"
44 #include "MachineCheckResults.hh"
45 
47  MachineCheck("Common helper functionality for minimal opset checks.") {
49 }
50 
52 }
53 
54 /**
55  * Checks if machine has all operations in minimal opset.
56  *
57  * @param machine Machine to be checked against minimal opset.
58  * @return True if minimal operation set was met, false otherwise.
59  */
60 bool
65  // construct the opset list
66  for (int i = 0; i < fuNav.count(); i++) {
67  TTAMachine::FunctionUnit* fu = fuNav.item(i);
68  fu->operationNames(opSet);
69  }
70 
71  // if machines opset is smaller than required opset
72  if (opSet.size() < minimalOpSet_.size()) {
73  return false;
74  }
75 
76  TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
77  TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
78 
79  TCETools::CIStringSet::iterator first2 = opSet.begin();
80  TCETools::CIStringSet::iterator last2 = opSet.end();
81 
82  // return false if missing operation was found
83  while (first1 != last1 && first2 != last2) {
84  if (*first1 < *first2) {
85  return false;
86  } else if (*first2 < *first1) {
87  ++first2;
88  } else {
89  ++first1;
90  ++first2;
91  }
92  }
93  if (first1 != last1) {
94  return false;
95  }
96  return true;
97 }
98 
99 
100 /**
101  * Checks the machine if it misses operations from the minimal op set.
102  *
103  * @param results Results of the validation are added to the given instance.
104  */
105 bool
108  MachineCheckResults& results) const {
109 
110  // construct the opset list
113  TCETools::CIStringSet opSet;
114  for (int i = 0; i < fuNav.count(); i++) {
115  TTAMachine::FunctionUnit* fu = fuNav.item(i);
116  fu->operationNames(opSet);
117  }
118 
119  TCETools::CIStringSet::iterator first1 = minimalOpSet_.begin();
120  TCETools::CIStringSet::iterator last1 = minimalOpSet_.end();
121 
122  TCETools::CIStringSet::iterator first2 = opSet.begin();
123  TCETools::CIStringSet::iterator last2 = opSet.end();
124 
125  std::string eMsg = "Operation missing from the minimal operation set: ";
126 
127  bool errorsAdded = false;
128  // missing opset is the difference towards minimalOpSet_
129  while (first1 != last1 && first2 != last2) {
130  if (*first1 < *first2) {
131  results.addError(*this, eMsg.append(*first1++));
132  errorsAdded = true;
133  } else if (*first2 < *first1) {
134  ++first2;
135  } else {
136  ++first1;
137  ++first2;
138  }
139  }
140  while (first1 != last1) {
141  results.addError(*this, eMsg.append(*first1++));
142  errorsAdded = true;
143  }
144  return !errorsAdded;
145 }
146 
147 
148 /**
149  * Checks if machine has all operations in minimal opset.
150  *
151  * Ignores fus with specified names from the check. This is useful with
152  * testing if minimal opset requirement breaks if a certain FUs are removed.
153  *
154  * @param machine Machine to be checked against minimal opset.
155  * @param ignoreFUs Names of the fus to be ignored regarding the check.
156  * @return True if minimal operation set was met, false otherwise.
157  */
158 bool
161  const std::set<std::string>& ignoreFUName) const {
162 
165  TCETools::CIStringSet opSet;
166  // construct the opset list
167  for (int i = 0; i < fuNav.count(); i++) {
168  TTAMachine::FunctionUnit* fu = fuNav.item(i);
169  if (ignoreFUName.find(fu->name()) == ignoreFUName.end()) {
170  fu->operationNames(opSet);
171  }
172  }
173 
174  // if machines opset is smaller than required opset
175  if (opSet.size() < minimalOpSet_.size()) {
176  return false;
177  }
178 
179  TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
180  TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
181 
182  TCETools::CIStringSet::iterator first2 = opSet.begin();
183  TCETools::CIStringSet::iterator last2 = opSet.end();
184 
185  // return false if missing operation was found
186  while (first1 != last1 && first2 != last2) {
187  if (*first1 < *first2) {
188  return false;
189  } else if (*first2 < *first1) {
190  ++first2;
191  } else {
192  ++first1;
193  ++first2;
194  }
195  }
196  if (first1 != last1) {
197  return false;
198  }
199  return true;
200 }
201 
202 
203 /**
204  * Return operations that are missing from a machine.
205  *
206  * Returns operations that are missing from a machine compared to the minimal
207  * operation set.
208  *
209  * @param machine Machine to be checked against minimal opset.
210  * @param missingOps Vector where missing operation names are to be stored.
211  */
212 void
215  std::vector<std::string>& missingOps) const {
216 
217  // construct the opset list
220  TCETools::CIStringSet opSet;
221  for (int i = 0; i < fuNav.count(); i++) {
222  TTAMachine::FunctionUnit* fu = fuNav.item(i);
223  fu->operationNames(opSet);
224  }
225 
226  TCETools::CIStringSet::const_iterator first1 = minimalOpSet_.begin();
227  TCETools::CIStringSet::const_iterator last1 = minimalOpSet_.end();
228 
229  TCETools::CIStringSet::iterator first2 = opSet.begin();
230  TCETools::CIStringSet::iterator last2 = opSet.end();
231 
232  // missing opset is the difference towards minimalOpSet_
233  while (first1 != last1 && first2 != last2) {
234  if (*first1 < *first2) {
235  missingOps.push_back(*first1++);
236  } else if (*first2 < *first1) {
237  ++first2;
238  } else {
239  ++first1;
240  ++first2;
241  }
242  }
243  while (first1 != last1) {
244  missingOps.push_back(*first1++);
245  }
246 }
247 
248 
249 /**
250  * Constructs a minimal opset from a given machine.
251  *
252  * @param machine Machine that is used as reference for minimal opset.
253  */
254 void
256  bool deleteMach = false;
257  if (machine == NULL) {
259  deleteMach = true;
260  }
261 
264  // construct the opset list
265  for (int i = 0; i < fuNav.count(); i++) {
266  TTAMachine::FunctionUnit* fu = fuNav.item(i);
268  }
269 
270  if (deleteMach) {
271  delete machine;
272  machine = NULL;
273  }
274 }
275 
276 
277 /**
278  * Returns constructed minimal opset.
279  *
280  * @return Minimal opset as strings in a set.
281  */
284  return minimalOpSet_;
285 }
286 
287 
288 /**
289  * Adds FUs to the machine so that it doesn't miss operations anymore.
290  *
291  * Check is done against minimal opset.
292  *
293  * @param machine Machine to be checked against minimal opset and where FUs
294  * are inserted so that minimal opset is fulfilled.
295  * @return A short description what was done.
296  */
297 std::string
299  std::vector<std::string> missingOps;
300  missingOperations(mach, missingOps);
301 
302  if (missingOps.size() < 1) {
303  const std::string errorMessage = "No missing operations found.";
304  throw InvalidData(
305  __FILE__, __LINE__, __func__, errorMessage);
306  }
307 
308  // go through minimal adf and add FUs that include missing ops
311 
313  minMach->functionUnitNavigator();
314  std::set<std::string> fuAdded;
316 
317  for (unsigned int moi = 0; moi < missingOps.size(); ++moi) {
318  for (int fui = 0; fui < fuNav.count(); ++fui) {
319  TTAMachine::FunctionUnit* fu = fuNav.item(fui);
320  if (fu->hasOperation(missingOps.at(moi))) {
321  if (fuAdded.end() != fuAdded.find(fu->name())) {
322  break;
323  }
324  fuAdded.insert(fu->name());
325  fu->unsetMachine();
326  mach.addFunctionUnit(*fu);
327  // connect the fu
328  for (int op = 0; op < fu->operationPortCount(); ++op) {
329  conCheck.connectFUPort(*fu->operationPort(op));
330  }
331  break;
332  }
333  }
334  }
335  delete minMach;
336  return "Operations were added to fulfill minimal opset requirements.";
337 }
338 
339 /**
340  * Returns true if the checker can automatically fix the machine to pass
341  * the check.
342  *
343  * @return True, minimal opset can be always added to the machine.
344  */
345 bool
347  return true;
348 }
MinimalOpSetCheck::checkWithIgnore
bool checkWithIgnore(const TTAMachine::Machine &machine, const std::set< std::string > &ignoreFUName) const
Definition: MinimalOpSetCheck.cc:159
MinimalOpSetCheck::MinimalOpSetCheck
MinimalOpSetCheck()
Definition: MinimalOpSetCheck.cc:46
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MinimalOpSetCheck.hh
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
MinimalOpSetCheck::fix
virtual std::string fix(TTAMachine::Machine &machine) const
Definition: MinimalOpSetCheck.cc:298
MinimalOpSetCheck::canFix
virtual bool canFix(const TTAMachine::Machine &mach) const
Definition: MinimalOpSetCheck.cc:346
MinimalOpSetCheck::~MinimalOpSetCheck
virtual ~MinimalOpSetCheck()
Definition: MinimalOpSetCheck.cc:51
TTAMachine::FunctionUnit::unsetMachine
virtual void unsetMachine()
Definition: FunctionUnit.cc:648
Environment::minimalADF
static std::string minimalADF()
Definition: Environment.cc:901
MachineCheckResults::addError
void addError(const MachineCheck &check, const std::string &errorMsg)
Definition: MachineCheckResults.cc:85
TTAMachine::Machine::Navigator::count
int count() const
FullyConnectedCheck.hh
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
CIStringSet.hh
InvalidData
Definition: Exception.hh:149
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
TCETools::CIStringSet
std::set< TCEString, CaseInsensitiveCmp > CIStringSet
Definition: CIStringSet.hh:49
Environment.hh
MachineCheckResults
Definition: MachineCheckResults.hh:46
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
MinimalOpSetCheck::check
virtual bool check(const TTAMachine::Machine &machine, MachineCheckResults &results) const
Definition: MinimalOpSetCheck.cc:106
TTAMachine::FunctionUnit::operationPortCount
virtual int operationPortCount() const
Definition: FunctionUnit.cc:182
MachineCheckResults.hh
MinimalOpSetCheck::minimalOpSet
TCETools::CIStringSet minimalOpSet() const
Definition: MinimalOpSetCheck.cc:283
MinimalOpSetCheck::minimalOpSet_
TCETools::CIStringSet minimalOpSet_
Definition: MinimalOpSetCheck.hh:80
TTAMachine::Machine::addFunctionUnit
virtual void addFunctionUnit(FunctionUnit &unit)
Definition: Machine.cc:202
FullyConnectedCheck
Definition: FullyConnectedCheck.hh:51
MinimalOpSetCheck::buildMinimalOpSet
void buildMinimalOpSet(const TTAMachine::Machine *machine=NULL)
Definition: MinimalOpSetCheck.cc:255
FullyConnectedCheck::connectFUPort
void connectFUPort(TTAMachine::FUPort &port) const
Definition: FullyConnectedCheck.cc:497
MachineCheck
Definition: MachineCheck.hh:50
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
MinimalOpSetCheck::missingOperations
void missingOperations(const TTAMachine::Machine &machine, std::vector< std::string > &missingOps) const
Definition: MinimalOpSetCheck.cc:213
TTAMachine::FunctionUnit::operationPort
virtual FUPort * operationPort(const std::string &name) const
Definition: FunctionUnit.cc:224
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::Machine
Definition: Machine.hh:73
FunctionUnit.hh
TTAMachine::Machine::loadFromADF
static Machine * loadFromADF(const std::string &adfFileName)
Definition: Machine.cc:905
TTAMachine::FunctionUnit::operationNames
virtual void operationNames(TCETools::CIStringSet &opNames) const
Definition: FunctionUnit.cc:428