CGRA-ME
Pathfinder.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * The software programs comprising "CGRA-ME" and the documentation provided
3  * with them are copyright by its authors and the University of Toronto. Only
4  * non-commercial, not-for-profit use of this software is permitted without ex-
5  * plicit permission. This software is provided "as is" with no warranties or
6  * guarantees of support. See the LICENCE for more details. You should have re-
7  * ceived a copy of the full licence along with this software. If not, see
8  * <http://cgra-me.ece.utoronto.ca/license/>.
9  ******************************************************************************/
10 
11 #include <CGRA/ClusteredMapper.h>
12 #include <CGRA/Exception.h>
13 #include <CGRA/GraphAlgorithms.h>
14 #include <CGRA/MRRGProcedures.h>
17 #include <CGRA/dotparse.h>
18 
19 
20 #include <algorithm>
21 #include <utility>
22 #include <functional>
23 #include <cmath>
24 #include <fstream>
25 
26 using std::cout;
27 using std::endl;
28 
30  const OpGraph& opgraph,
31  const MRRG& mrrg,
32  bool isElastic,
33  const std::string placement_filename)
34  : ClusteredMapperDriver(driver)
35  , l_mrrg(mrrg)
36  , l_isElastic(isElastic)
37  , l_placement_filename(placement_filename)
38  , l_opgraph(opgraph)
39  , l_routing_nodes() {
40  const auto classes = computeNodeClassLists(mrrg);
41 
42  for (const auto& mrrg_node : classes.routing_nodes) {
43  // Assinging a base cost of 1.0 to reg based connections
44  // and 2.0 to combinatational based connections
45  double baseCost = 1.0;
46  l_routing_nodes.emplace(mrrg_node, NodeAttributes());
47  l_routing_nodes[mrrg_node].baseCost = baseCost;
48  }
49 }
50 
52  Mapping mapping_result = placed;
53  if (l_verbosity > 0) std::cout << "Options = " << l_mapper_args << '\n';
54 
55  // Read in the placement file
56  if (l_placement_filename.empty()) {
58  for (auto& op : l_opgraph.opNodes()) {
59  MRRG::NodeDescriptor mrrg_node = placed.getSingleMapping(op);
60  l_placement[op] = mrrg_node;
62  l_used_rounting_function_nodes.emplace(mrrg_node);
63  }
64  }
65  } else {
67  }
68 
69  // store cost in priority queue so we can have duplicates
70  struct NetInfo {
71  OpGraph::ValDescriptor val_node;
72  bool overuse = false;
73  Latency max_cycles;
74  unsigned fanout = 0;
75 
76  bool operator<(const NetInfo& rhs) const {
77  return fanout > rhs.fanout && max_cycles > rhs.max_cycles;
78  }
79  };
80  bool routed = false;
81  std::vector<NetInfo> nets;
82  // Do initial routing for every value node
83  // If the node can't be routed then give up.
84  for (OpGraph::ValDescriptor val_node : l_opgraph.valNodes()) {
85  routed = routeVal(val_node);
86  if (!routed) break;
87 
88  Latency max_cycles = 0;
89  auto& src_op = val_node->input;
90  int II = l_mrrg.initiationInterval();
91  for (auto& sink_op : val_node->output) {
92  Latency cycles_to_sink = getCyclesToSink(src_op, sink_op);
93  }
94  nets.push_back({val_node, false, max_cycles, (unsigned)val_node->output.size()});
95  }
96  std::sort(nets.begin(), nets.end());
97  // Check if the opgraph mapped
98  bool mapped = isOpgraphCovered() && checkOveruse();
99  int i = 0;
100  while (!mapped && i < 70 && routed) {
101  i++;
102  // If the mapping does not occur keep ripping out
103  // values and re-routing them.
104  for (auto& net : nets) {
105  auto& val_node = net.val_node;
106  if (l_verbosity > 0) std::cout << "Ripping out node: " << val_node->getName() << std::endl;
107 
108  ripUpOpVal(val_node);
109 
110  if (l_verbosity > 0) std::cout << "Routing node: " << val_node->getName() << std::endl;
111 
112  routed = routeVal(val_node);
113 
114  if (!routed && i > 1) {
115  throw cgrame_error("ERR: net: " + val_node->getName() + " could not be routed");
116  } else
117  if (!routed) {
118  break;
119  }
120 
121  bool mrrg_overuse = checkOveruse();
122  bool opgraph_covered = isOpgraphCovered();
123  mapped = mrrg_overuse && opgraph_covered;
124  std::cout << "overuse_ok=" << mrrg_overuse;
125  std::cout << " opgraph_covered=" << opgraph_covered << std::endl;
126  if (mapped) break;
127  }
128  if (!routed) break;
131  }
132  std::cout<< "GRAPH COVERED: " << isOpgraphCovered() << " " << checkOveruse() <<std::endl;
133  if (isOpgraphCovered() && checkOveruse()) {
135  setMappingInto(mapping_result);
136  mapping_result.setStatus(MappingStatus::success);
137  } else {
138  for (auto& valNode : l_opgraph.valNodes()) {
139  ripUpOpVal(valNode);
140  }
141  for (auto& mrrg_node : l_routing_nodes) {
142  mrrg_node.second.hCost = 0;
143  }
147  }
148 
149  return mapping_result;
150 }
151 
153  bool is_covered = true;
154  for (const auto& val : l_opgraph.valNodes()) {
155  auto lookup = l_mapping.find(val);
156  if (lookup == l_mapping.end() || lookup->second.empty()) {
157  is_covered = false;
158  }
159  }
160  return is_covered;
161 }
162 
164  int num_of_resources_used = 0;
165  for (const auto& nodelist : l_routing_nodes) {
166  int occupancy = nodelist.second.occupancy;
167  const MRRGNode* node = nodelist.first;
168  if (occupancy > 0) {
169  num_of_resources_used++;
170  }
171  }
172  std::cout << "Number of routing resoucres used: " << num_of_resources_used << std::endl;
173  return;
174 }
175 
177  bool result = true;
178  int num_of_overuse = 0;
179  for (const auto& nodelist : l_routing_nodes) {
180  int occupancy = nodelist.second.occupancy;
181  const MRRGNode* node = nodelist.first;
182  bool overuse = occupancy > node->capacity;
183  if (overuse && l_verbosity > 1) {
184  //std::cout << node << " is overused by: ";
185  num_of_overuse++;
186  for (auto& value : nodelist.second.mapped_values) {
187  //std::cout << " " << value->getName();
188  }
189  //std::cout << std::endl;
190  }
191  result &= !overuse;
192  }
193  //std::cout << "Number of overuse: " << num_of_overuse << " PFACTOR: " << l_p_factor << " HFACTOR: " << l_h_factor << std::endl;
194  return result;
195 }
196 
197 
198 
200  // unmap all nodes
201  for (auto& n : l_mapping[val]) {
202  // update history cost by adding the number of extra occupacny that
203  // occured on the node
204  l_routing_nodes[n].hCost += (l_routing_nodes[n].occupancy > n->capacity) ?
205  (l_routing_nodes[n].occupancy - n->capacity) : 0;
206 
207  // TODO(raghebom): do we still need to keep track of the mapped values
208  auto it = find(l_routing_nodes[n].mapped_values.begin(), l_routing_nodes[n].mapped_values.end(), val);
209  if (it == l_routing_nodes[n].mapped_values.end()) {
210  throw cgrame_error("Cannot find value (" + val->getName() + ") mapped to the mrrg node (" + n->getFullName() + ")\n");
211  }
212 
213  // Updating the number of values mapped to this node
214  l_routing_nodes[n].mapped_values.erase(it);
215  if (l_routing_nodes[n].occupancy-- <= 0) {
216  throw cgrame_error("occupancy was already zero or less" + std::to_string(l_routing_nodes[n].occupancy) + " " + n->getFullName());
217  }
218  }
219 
220  l_mapping[val].clear();
221 
222  return;
223 }
224 
225 double PathFinder::getCost(const MRRGNode* n) {
226  int oc = l_routing_nodes[n].occupancy;
227  int cap = n->capacity;
228  double history_cost = l_routing_nodes[n].hCost;
229  double base_cost = l_routing_nodes[n].baseCost;
230  // return (base_cost+ history_cost) * (oc <= cap ? 1 : (oc - cap));
231  double h_cost = (l_h_factor*history_cost);
232  double oc_cost = (l_p_factor*(oc <= cap ? 1 : (oc - cap)));
233  return base_cost + h_cost + oc_cost;
234 }
235 
236 void PathFinder::mapMRRGNode(const OpGraphVal* val, const MRRGNode* node) {
237  l_mapping[val].push_back(node);
238  l_routing_nodes[node].occupancy++;
239  l_routing_nodes[node].mapped_values.push_back(val);
240 }
241 
243  if (l_mapping[val].size()) return true; // already routed!
244 
245  // store cost in priority queue so we can have duplicates
246  struct SinkAndLatency {
247  const MRRGNode* sink_node;
248  const OpGraphOp* sink_op;
249  Latency cycles;
250 
251  bool operator<(const SinkAndLatency& rhs) const {
252  if (cycles == rhs.cycles) {
253  return sink_op < rhs.sink_op;
254  }
255  return cycles > rhs.cycles; // && cycles > rhs.cycles;
256  }
257  };
258  int II = l_mrrg.initiationInterval();
259  // Assuming each val has a single op node
260  // that is mapped to a single mrrgnode
261  const OpGraphOp* src_op = val->input;
262  const auto& src = l_placement.at(val->input);
263  int latency_of_src = (l_isElastic) ? kUndefLatency : src->latency;
264  const auto& the_single_fanout = l_mrrg.fanout(src).at(0);
265 
266  // collect routing destinations with the operand tags wanted for each sink
267  std::priority_queue<SinkAndLatency> sinks;
268  std::map<SinkAndLatency, std::vector<OperandTag>> sink_tags;
269  for (int isink_op = 0; isink_op != val->output.size(); ++isink_op) {
270  const auto& sink_op = val->output.at(isink_op);
271  Latency cycles_to_sink = getCyclesToSink(src_op, sink_op);
272  const auto& op_tag = l_opgraph.getOperandTag(OpGraph::EdgeDescriptor{val, isink_op});
273  SinkAndLatency sl = {l_placement.at(sink_op), sink_op, cycles_to_sink};
274  if (sink_tags.find(sl) == sink_tags.end()) {
275  sinks.push(sl);
276  }
277  if (std::find(sink_tags[sl].begin(), sink_tags[sl].end(), op_tag) != sink_tags[sl].end() && op_tag != Operands::BINARY_ANY) {
278  throw cgrame_error("Operation: " + sink_op->getName() + " have two similar tags: " + op_tag +
279  " from operation: " + src_op->getName());
280  }
281  sink_tags[sl].push_back(op_tag);
282  }
283 
284  std::cout << "MAPPING From: "<< val->input->getName() << " ";
285  for (auto op : val->output) {
286  std::cout << op->getName() << " ";
287  }
288  std::cout << sinks.size() << " " << sink_tags.size() << std::endl;
289  std::set<const MRRGNode*> routes;
290  // Do the routing. Find one sink at a time
291  while (!sinks.empty()) {
292  auto sink = sinks.top();
293  sinks.pop();
294  std::cout << *sink.sink_node << std::endl;
295  for (auto tag : sink_tags[sink]) {
296  std::cout << src_op->getName() << " " << sink.sink_op->getName() << " " << sink.cycles << tag << std::endl;
297  std::vector<const MRRGNode*> route = dijkstraVisit(the_single_fanout, sink.sink_node, tag,
298  val, routes, sink.cycles, latency_of_src);
299  if (route.empty()) return false;
300  std::copy(route.begin(), route.end(), std::inserter(routes, routes.end()));
301  }
302  }
303 
304  for (const auto& node : routes) {
305  if (node->type == MRRG_NODE_ROUTING || node->type == MRRG_NODE_ROUTING_FUNCTION) {
306  mapMRRGNode(val, node);
307  }
308  }
309  return true;
310 }
311 
317 std::vector<const MRRGNode*> PathFinder::dijkstraVisit(const MRRGNode* source,
318  const MRRGNode* sink, OperandTag tag_to_find, const OpGraphVal* val,
319  std::set<const MRRGNode*> routes, int cycles_to_sink, int latency_of_src) {
320  using Cost = double;
321 
322  // Stores the current node cost and the path to this node
323  struct VertexData {
324  std::vector<const MRRGNode*> fanin;
325  Cost lowest_known_cost;
326  Latency num_of_cycles;
327  bool tag_found;
328  bool operator==(const VertexData& rhs) const {
329  return this->lowest_known_cost == rhs.lowest_known_cost && this->fanin == rhs.fanin
330  && num_of_cycles == rhs.num_of_cycles && tag_found == rhs.tag_found;
331  }
332  };
333 
334  // store cost in priority queue so we can have duplicates
335  struct VertexAndCost {
336  const MRRGNode* vid;
337  Cost cost_to_here;
338  Latency cycles;
339 
340  bool operator<(const VertexAndCost& rhs) const {
341  return cost_to_here > rhs.cost_to_here; // && cycles > rhs.cycles;
342  }
343  };
344 
345  // Data stores the current mrrgnode and its vertex data
346  auto data = std::unordered_map<std::pair<MRRGNodeDesc, Latency>, VertexData, pair_hash>();
347  // Stores the nodes and the visited ones
348  std::priority_queue<VertexAndCost> to_visit;
349  // Stores the node and if it is visited
350  std::set<std::pair<MRRGNodeDesc, Latency>> visited;
351 
352  // Initialize the visit and data to the source
353  to_visit.push({source, 0, latency_of_src});
354  data.insert({{source, latency_of_src}, {{source}, 0, latency_of_src, false}});
355  MRRGNodeDesc found = NULL;
356  bool tag_found = false;
357  while (!to_visit.empty() && !found) {
358  // Get the first element from the queue
359  const auto queue_top = to_visit.top();
360  MRRGNodeDesc explore_curr = queue_top.vid;
361  Latency cycles_to_curr = queue_top.cycles;
362  to_visit.pop();
363 
364  // Check if this node has been explored and check if it is the lowest known cost
365  if (visited.find({explore_curr, cycles_to_curr}) != visited.end()) continue;
366 
367  // Reached the sink need to check if the tag is correct otherwise go to the
368  // next element
369  if (!found && sink == explore_curr) {
370  if (cycles_to_sink == cycles_to_curr || cycles_to_sink == kUndefLatency) {
371  found = explore_curr;
372  } else {
373  visited.emplace(explore_curr, cycles_to_curr);
374  data.erase({explore_curr, cycles_to_curr});
375  }
376  continue;
377  }
378 
379  for (const auto fanout : l_mrrg.fanout(explore_curr)) {
380  tag_found = false; // Tricky variable so double checking that it is always is set to false
381  // Ignore if the node is the source node
382  if (fanout == source) continue;
383 
384  // if this is an mrrg_node_function that is not the sink we are looking for then skip it
385  if (fanout->type == MRRGNode_Type::MRRG_NODE_FUNCTION && fanout != sink) continue;
386  if (l_routing_nodes[explore_curr].mapped_values.size() != 0 && fanout == sink) continue;
387 
388  // If this mrrg_node_routing_function and is used as a function node then skip it
389  // if it is not the sink
390  if (fanout->type == MRRGNode_Type::MRRG_NODE_ROUTING_FUNCTION) {
391  if (l_used_rounting_function_nodes.count(fanout) != 0 && fanout != sink) continue;
392  }
393  if (fanout->bitwidth < val->bitwidth) continue;
394 
395  // Since we are mapping multiple sinks we do not want the path
396  // of different nodes creating shorts
397  if (!routes.count(explore_curr) && routes.count(fanout)) continue;
398 
399  // Checking if the current data is better than the next data
400  auto data_curr = data[{explore_curr, cycles_to_curr}];
401  // if we found the tag that we are looking for but the sink this operand_pin
402  // is not the sink we are looking for then skip it
403  if (data_curr.tag_found && fanout != sink) continue;
404 
405  // get the cost and the cycles
406  Cost cost = queue_top.cost_to_here + getCost(fanout);
407  Latency cycles = data_curr.num_of_cycles;
408  // Avoiding loop back
409  if (std::find(data_curr.fanin.begin(), data_curr.fanin.end(), fanout)
410  != data_curr.fanin.end()) continue;
411 
412  // Set the num of cycles for this path
413  if (fanout->type != MRRGNode_Type::MRRG_NODE_FUNCTION) {
414  cycles = (l_isElastic) ? kUndefLatency : cycles + explore_curr->latency; // et == HW_REG ? 1 : 0;
415  }
416 
417  // checking if the cost and cycles is better for this route or no
418  if (cycles > cycles_to_sink && cycles_to_sink != kUndefLatency) continue;
419 
420  if (data.find({fanout, cycles}) != data.end()) {
421  if (data[{fanout, cycles}].lowest_known_cost <= cost) {
422  continue;
423  } else {
424  data.erase({fanout, cycles});
425  }
426  }
427 
428  // Looking for the correct tag
429  if (!fanout->supported_operand_tags.empty() && tag_to_find != Operands::UNTAGGED) {
430  if (fanout->type != MRRG_NODE_ROUTING_FUNCTION) {
431  if (fanout->supported_operand_tags.find(tag_to_find) == fanout->supported_operand_tags.end()) {
432  continue;
433  } else {
434  if (l_routing_nodes[fanout].mapped_values.size() == 0 && routes.count(fanout) == 0)
435  tag_found = true;
436  }
437  } else if (tag_to_find == Operands::PREDICATE) {
438  if (fanout->supported_operand_tags.find(tag_to_find) == fanout->supported_operand_tags.end()) {
439  continue;
440  } else {
441  if (l_routing_nodes[fanout].mapped_values.size() == 0 && routes.count(fanout) == 0)
442  tag_found = true;
443  }
444  }
445  if (!tag_found) continue;
446  }
447 
448  // Update data and queue
449  data[{fanout, cycles}] = {data[{explore_curr, cycles_to_curr}].fanin, cost, cycles};
450  data[{fanout, cycles}].fanin.push_back(explore_curr);
451  data[{fanout, cycles}].tag_found = tag_found;
452  to_visit.push({fanout, cost, cycles});
453  tag_found = false;
454  }
455  // Update the visited and clean up the data such
456  // that we do not save all the paths
457  visited.emplace(explore_curr, cycles_to_curr);
458  data.erase({explore_curr, cycles_to_curr});
459  }
460  // TODO(raghebom) : remove currently there for debugging purposes
461  if (!found) {
462  std::cout << to_visit.empty() << std::endl;
463  std::cout << "NOT FOUND" << std::endl;
464  std::cout << source << " " << sink->getFullName() << " " << data.size() << std::endl;
465  }
466  std::cout << "cost " << data[{sink, cycles_to_sink}].lowest_known_cost << std::endl;
467  for (auto data_i : data[{sink, cycles_to_sink}].fanin) {
468  std::cout << data_i->getFullName() << std::endl;
469  }
470  return data[{sink, cycles_to_sink}].fanin;
471 }
472 
473 
475  ConfigGraph parsed_placement_dot;
476  std::cout << "[INFO] Getting placement information from DOT file: " << l_placement_filename<< std::endl;
477  auto placement_ifstream = std::ifstream(l_placement_filename);
478  parsed_placement_dot = parseDot(placement_ifstream, l_placement_filename);
479 
480  // Parse opnodes and the mrrg nodes that they corrsponed to
481  // Then place them in a map from op to mrrg node
482  for (const auto& v : parsed_placement_dot.allNodes()) {
483  const auto& v_attrs = parsed_placement_dot.attributes(v);
484  const bool isOp = v_attrs.hasKey("maps_to_op");
485 
486  if (!isOp) {
487  throw make_from_stream<cgrame_error>([&](auto&& s) {
488  s << "mrrg node: " << parsed_placement_dot.name(v) << " is not mapped to anything";
489  });
490  }
491 
492  std::string mrrg_node_name = parsed_placement_dot.name(v);
493  std::string op_name;
494  op_name = v_attrs.getString("maps_to_op");
495 
496  const MRRGNode* mrrg_ndesc = l_mrrg.getNode(v_attrs.getInt("cycle"), v_attrs.getString("name"));
497  if (mrrg_ndesc == nullptr) {
498  throw make_from_stream<cgrame_error>([&](auto&& s) {
499  s << "[ERROR]: mrrg node: " << v_attrs.getInt("cycle") << ":" <<
500  v_attrs.getString("name") << " is not part of specified architecture";
501  });
502  }
503 
504  const OpGraphNode* op_ndesc = l_opgraph.getOp(op_name);
505  if (op_ndesc == nullptr) {
506  throw make_from_stream<cgrame_error>([&](auto&& s) {
507  s << "[ERROR]: op node: "<< op_name << " is not part of specified dfg graph";
508  });
509  }
510  l_placement.emplace(op_ndesc, mrrg_ndesc);
511  }
512  return;
513 }
MRRGNode::getFullName
std::string getFullName() const
Definition: MRRG.cpp:569
OpGraphVal::output
std::vector< OpGraphOp * > output
Definition: OpGraph.h:196
MRRG_NODE_ROUTING_FUNCTION
@ MRRG_NODE_ROUTING_FUNCTION
Definition: MRRG.h:47
CodeProfiling.h
ConfigGraph::allNodes
auto allNodes() const
Definition: ConfigGraph.h:142
ConfigGraph::attributes
const ConfigStore & attributes(const VertexID &v) const
Definition: ConfigGraph.h:128
OperandTag
std::string OperandTag
Definition: OpGraph.h:81
PathFinder::routeVal
bool routeVal(OpGraphValDesc)
Definition: Pathfinder.cpp:242
PathFinder::l_p_factor
double l_p_factor
Definition: ClusteredMapper.h:158
MRRG
Definition: MRRG.h:216
dotparse.h
GraphAlgorithms.h
ClusteredMapperDriver
Proxy class that makes a new instance of the for ever call. Holds constant configuration info,...
Definition: ClusteredMapper.h:41
PathFinder::routeOpGraph
Mapping routeOpGraph(Mapping placement)
Definition: Pathfinder.cpp:51
MRRGNode::type
MRRGNode_Type type
Definition: MRRG.h:107
Mapping::getSingleMapping
MRRG::NodeDescriptor getSingleMapping(OpGraph::NodeDescriptor key) const
Definition: Mapping.h:56
PathFinder::printNumberOfResourcesUsed
void printNumberOfResourcesUsed()
Definition: Pathfinder.cpp:163
Latency
int Latency
Definition: ClusteredMapper.h:35
PathFinder::isOpgraphCovered
bool isOpgraphCovered()
Definition: Pathfinder.cpp:152
MRRGNode::capacity
int capacity
Definition: MRRG.h:136
begin
auto begin(const SingleItemImmutableSet< VertexID > &siis)
Definition: Collections.h:137
OpGraph::getOp
OpDescriptor getOp(const std::string &name) const
Definition: OpGraph.h:386
PathFinder::setMappingInto
void setMappingInto(Mapping &m) const
Definition: ClusteredMapper.h:149
PathFinder::ripUpOpVal
void ripUpOpVal(OpGraphValDesc)
Definition: Pathfinder.cpp:199
OpGraph::valNodes
auto & valNodes() const
Definition: OpGraph.h:314
ConfigGraph
Definition: ConfigGraph.h:72
OpGraph::getOperandTag
const OperandTag & getOperandTag(EdgeDescriptor edge) const
Definition: OpGraph.cpp:509
pair_hash
Definition: Util.h:24
PathFinder::dijkstraVisit
std::vector< const MRRGNode * > dijkstraVisit(const MRRGNode *, const MRRGNode *, OperandTag, OpGraphValDesc, std::set< const MRRGNode * >, int, int)
Definition: Pathfinder.cpp:317
ClusteredMapperDriver::l_initial_hfactor
const double l_initial_hfactor
Definition: ClusteredMapper.h:74
Operands::UNTAGGED
static constexpr auto & UNTAGGED
Definition: OpGraph.h:87
to_string
const std::string & to_string(const OpGraphOpCode &opcode)
Definition: OpGraph.cpp:111
ConfigGraph::name
const std::string & name(const VertexID &v) const
Definition: ConfigGraph.h:123
PathFinder::mapMRRGNode
void mapMRRGNode(OpGraphValDesc, const MRRGNode *)
Definition: Pathfinder.cpp:236
Mapping
Definition: Mapping.h:31
Exception.h
ConfigStore::hasKey
bool hasKey(const std::string &key) const
Definition: ConfigStore.h:209
operator==
bool operator==(const OpGraph &lhs, const OpGraph &rhs)
Definition: OpGraph.cpp:1159
MRRG::fanout
auto & fanout(NodeDescriptor ndesc) const
Definition: MRRG.h:288
PathFinder::checkOveruse
bool checkOveruse()
Definition: Pathfinder.cpp:176
PathFinder::l_h_factor
double l_h_factor
Definition: ClusteredMapper.h:159
OpGraph::opNodes
auto & opNodes() const
Definition: OpGraph.h:313
operator<
bool operator<(const OpGraph::EdgeDescriptor &lhs, const OpGraph::EdgeDescriptor &rhs)
Definition: OpGraph.h:533
MRRG_NODE_FUNCTION
@ MRRG_NODE_FUNCTION
Definition: MRRG.h:46
PathFinder::getCost
double getCost(const MRRGNode *)
Definition: Pathfinder.cpp:225
PathFinder::PathFinder
PathFinder(ClusteredMapperDriver driver, const OpGraph &opgraph, const MRRG &mrrg, bool isElastic=false, const std::string placement_filename="")
Definition: Pathfinder.cpp:29
UserModules.h
ClusteredMapperDriver::getCyclesToSink
const Latency getCyclesToSink(OpGraphOpDesc source, OpGraphOpDesc sink)
Definition: ClusteredMapper.cpp:217
PathFinder::l_placement
std::map< const OpGraphNode *, const MRRGNode * > l_placement
Definition: ClusteredMapper.h:165
OpGraphNode
Definition: OpGraph.h:113
ClusteredMapperDriver::l_h_factor_factor
const double l_h_factor_factor
Definition: ClusteredMapper.h:75
parseDot
ConfigGraph parseDot(std::istream &input, std::string file_name)
MRRG_NODE_ROUTING
@ MRRG_NODE_ROUTING
Definition: MRRG.h:45
ClusteredMapperDriver::l_p_factor_factor
const double l_p_factor_factor
Definition: ClusteredMapper.h:72
ClusteredMapperDriver::l_mapper_args
const ConfigStore l_mapper_args
Definition: ClusteredMapper.h:84
PathFinder::parsePlacementFile
void parsePlacementFile()
Definition: Pathfinder.cpp:474
OpGraphVal
Definition: OpGraph.h:178
end
auto end(const SingleItemImmutableSet< VertexID > &siis)
Definition: Collections.h:138
OpGraphOp
Definition: OpGraph.h:131
MRRGNode
Definition: MRRG.h:60
PathFinder::l_placement_filename
std::string l_placement_filename
Definition: ClusteredMapper.h:162
PathFinder::l_mapping
std::map< OpGraphValDesc, std::vector< const MRRGNode * > > l_mapping
Definition: ClusteredMapper.h:167
ClusteredMapperDriver::l_initial_pfactor
const double l_initial_pfactor
Definition: ClusteredMapper.h:73
OpGraph::EdgeDescriptor
Definition: OpGraph.h:224
MRRG::getNode
NodeDescriptor getNode(int cycle, const std::string &name) const
Definition: MRRG.cpp:142
ClusteredMapperDriver::l_verbosity
const int l_verbosity
Definition: ClusteredMapper.h:79
MappingStatus::success
@ success
NodeAttributes
Definition: ClusteredMapper.h:95
OpGraphVal::input
OpGraphOp * input
Definition: OpGraph.h:190
MRRG::initiationInterval
int initiationInterval() const
Definition: MRRG.h:346
MRRGProcedures.h
PathFinder::l_routing_nodes
std::unordered_map< const MRRGNode *, NodeAttributes > l_routing_nodes
Definition: ClusteredMapper.h:166
OpGraphVal::bitwidth
int bitwidth
Definition: OpGraph.h:200
Operands::BINARY_ANY
static constexpr auto & BINARY_ANY
Definition: OpGraph.h:91
PathFinder::l_opgraph
const OpGraph & l_opgraph
Definition: ClusteredMapper.h:161
PathFinder::l_used_rounting_function_nodes
std::set< MRRGNodeDesc > l_used_rounting_function_nodes
Definition: ClusteredMapper.h:164
MRRGNode::latency
int latency
Definition: MRRG.h:132
PathFinder::l_isElastic
bool l_isElastic
Definition: ClusteredMapper.h:157
Operands::PREDICATE
static constexpr auto & PREDICATE
Definition: OpGraph.h:88
ClusteredMapper.h
OpGraph
Definition: OpGraph.h:215
cgrame_error
Definition: Exception.h:20
Mapping::setStatus
void setStatus(MappingStatus new_status)
Definition: Mapping.h:40
computeNodeClassLists
MRRGNodeClassLists computeNodeClassLists(const MRRG &mrrg)
Definition: MRRGProcedures.cpp:169
PathFinder::kUndefLatency
static constexpr Latency kUndefLatency
Definition: ClusteredMapper.h:121
OpGraphNode::getName
const std::string & getName() const
Definition: OpGraph.h:121
PathFinder::l_mrrg
const MRRG & l_mrrg
Definition: ClusteredMapper.h:160