CGRA-ME
MRRG.h
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 
18 #ifndef MRRG__H_
19 #define MRRG__H_
20 
21 #include <CGRA/ConfigStore.h>
22 #include <CGRA/Exception.h>
23 #include <CGRA/OpGraph.h>
24 #include <CGRA/Util.h>
25 
26 #include <algorithm>
27 #include <array>
28 #include <iostream>
29 #include <map>
30 #include <memory>
31 #include <set>
32 #include <string>
33 #include <unordered_map>
34 #include <vector>
35 
40 };
41 
46 };
47 
49  HW_WIRE, //note: buffer/tristate-buffer included
52  HW_COMB, //note: memory units included
54 };
55 
56 class OpGraph;
57 class OpGraphOp;
58 class Module;
59 
60 class MRRGNode
61 {
62  public:
63  using SupportedOpTags = std::set<std::string>; // Operand ids that can use this node
64  template<typename SupportedOps = std::vector<OpGraphOpCode>>
66  Module* parent,
67  int cycle,
68  std::string name,
70  int latency,
71  int bitwidth,
72  SupportedOps&& supported_ops,
75  int max_cap = 1
76  )
77  : name(name)
78  , type(type)
79  , et(et)
80  , supported_ops(std::forward<SupportedOps>(supported_ops))
81  , fanout()
82  , fanin()
84  , parent(parent)
85  , cycle(cycle)
87  , latency(latency)
88  , capacity(max_cap)
89  {
90  if (latency < 0) {
91  cgrame_model_error("Illegal latency value specified!");
92  }
93  }
94 
95  private:
96  // the MRRG is a doubly linked graph, so don't copy nodes!
97  // these are needed for implementation reasons, though.
98  MRRGNode(const MRRGNode&) = default;
99  MRRGNode& operator=(const MRRGNode&) = default;
100 
101  public:
102  MRRGNode(MRRGNode&&) = default;
103  MRRGNode& operator=(MRRGNode&&) = default;
104 
105  // is this node in a MRRG? consider `MRRG::renameNode` if changing this
106  std::string name;
108  HWEntityType et = HW_UNSPECIFIED; // this is a helper flag for generating timing graph
109 
110  bool canMapOp(OpGraphOp const* op) const;
111  std::vector<OpGraphOpCode> supported_ops;
112 
113  std::vector<MRRGNode*> fanout;
114  std::vector<MRRGNode*> fanin;
115 
116  // Possible tags include: any2input, any3input, pred, LHS, RHS, etc. see OpGraph.h
118 
120 
121  std::string getFullName() const;
122  const std::string& getHierarchyQualifiedName() const { return name; }
123 
124  auto getContextNum() const { return cycle; }
125  auto getLatency() const { return latency; }
126 
127  unsigned int cycle;
128  unsigned int delay = 0; // Delay in picoseconds
129  unsigned int bitwidth = 32;
130 
131  // Latency in cycles through the node min, max if latency is programmable
132  int latency;
133 
134  // the following two variables may be used during mapping
135  // the capacity of the node, how many things can be mapped to it
136  int capacity = 1;
137 
138 /*
139  // fixed mapper data
140  float base_cost;
141  int occupancy;
142 
143  float getCost(float penalty_factor = 1);
144 
145 
146  //find which op node that the MRRG node corresponds to
147  OpGraphOp* getOpNodePtr (const OpGraph& graph);
148 */
149 
150  template<typename STR>
151  static MRRGNode make_routing(Module* parent, int bitwidth, int cycle, STR&& name, int latency = 0, int max_cap = 1) {
152  auto type = MRRG_NODE_ROUTING;
154  if (latency == 0) {
155  et = HW_WIRE;
156  } else if (latency >= 1) {
157  et = HW_REG;
158  }
159  int capacity = 1;
160  return {parent, cycle, std::forward<STR>(name), type, latency, bitwidth, std::vector<OpGraphOpCode>(), et, SupportedOpTags(), capacity};
161  }
162 
163  template<typename STR>
164  static MRRGNode make_operand_pin(Module* parent, int bitwidth, int cycle, STR&& name, SupportedOpTags operand_tags, int latency = 0, int max_cap = 1) {
165  auto type = MRRG_NODE_ROUTING;
167  if (latency == 0) {
168  et = HW_WIRE;
169  } else if (latency >= 1) {
170  et = HW_REG;
171  }
172  int capacity = 1;
173  return {parent, cycle, std::forward<STR>(name), type, latency, bitwidth, std::vector<OpGraphOpCode>(), et, operand_tags, capacity};
174  }
175 
176  template<typename STR, typename SupportedOps = std::vector<OpGraphOpCode>>
177  static MRRGNode make_routing_function (Module* parent, int bitwidth, int cycle, STR&& name, int latency, SupportedOpTags operand_tags, SupportedOps supported_ops, int max_cap = 1) {
180  if (latency == 0) {
181  et = HW_WIRE;
182  } else {
183  et = HW_REG;
184  }
185  int capacity = max_cap;
186  return {parent, cycle, std::forward<STR>(name), type, latency, bitwidth, supported_ops, et, SupportedOpTags(), capacity};
187  }
188  friend std::ostream& operator<< (std::ostream& out, const MRRGNode& node);
189 
190  template<typename STR, typename SupportedOps = std::vector<OpGraphOpCode>>
191  static MRRGNode make_function(Module* parent, int bitwidth, int cycle, STR&& name, int latency, SupportedOps supported_ops, int max_cap = 1, bool is_const_unit = false) {
192  auto type = MRRG_NODE_FUNCTION;
194  if (is_const_unit) {
195  et = HW_REG;
196  } else if (latency == 0) {
197  et = HW_COMB;
198  } else {
199  et = HW_REG;
200  }
201  int capacity = max_cap;
202  return {parent, cycle, std::forward<STR>(name), type, latency, bitwidth, supported_ops, et, SupportedOpTags(), capacity};
203  }
204 
205  friend std::ostream& operator<< (std::ostream& out, const MRRGNode& node);
206 
207  private:
208  friend class MRRG;
213  void applyReferenceRename(const std::unordered_map<const MRRGNode*, MRRGNode*>& rename_map);
214 };
215 
216 class MRRG
217 {
218  public:
219  using NodeDescriptor = const MRRGNode*;
220 
221  MRRG(int II)
222  : nodes(II)
223  { }
224 
225  MRRG(const MRRG& src)
226  : nodes()
227  { *this = src; }
228 
229  MRRG(MRRG&&) = default;
230  MRRG& operator=(const MRRG& rhs);
231  MRRG& operator=(MRRG&&) = default;
232 
238  std::pair<NodeDescriptor,bool> insert(MRRGNode node);
239  std::pair<NodeDescriptor,bool> insert(NodeDescriptor fanin, MRRGNode node) { return insertMultiFanin(std::array<NodeDescriptor,1>{{fanin}}, std::move(node)); }
240 
241  template<typename NodeDescList = std::vector<NodeDescriptor>>
242  std::pair<NodeDescriptor,bool> insertMultiFanin(NodeDescList fanins, MRRGNode node) {
243  auto ir = insert(std::move(node));
244  if (ir.second) for (auto& fanin : fanins) link(fanin, ir.first);
245  return ir;
246  }
247 
256 
260  void erase(MRRG::NodeDescriptor n);
261 
265  NodeDescriptor getNode(int cycle, const std::string& name) const;
266  NodeDescriptor getNodeByPropertiesOf(const MRRGNode& node) const { return getNode(node.cycle, node.name); }
267 
273  MRRGNode& getNodeRef(NodeDescriptor ndesc) { return *const_cast<MRRGNode*>(ndesc); }
274  const MRRGNode& getNodeRef(NodeDescriptor ndesc) const { return *ndesc; }
275 
279  MRRGNode& getNodeRef(int cycle, const std::string& name) { return getNodeRef(getNode(cycle, name)); }
280  const MRRGNode& getNodeRef(int cycle, const std::string& name) const { return getNodeRef(getNode(cycle, name)); }
282  const MRRGNode& getNodeRefByPropertiesOf(const MRRGNode& node) const { return getNodeRef(getNodeByPropertiesOf(node)); }
283 
288  auto& fanout(NodeDescriptor ndesc) const { return getNodeRef(ndesc).fanout; }
289 
293  auto& fanin(NodeDescriptor ndesc) const { return getNodeRef(ndesc).fanin; }
294 
303  struct VerifyMessage {
304  enum class Type : char { Info, Warning, Error, };
306  std::string message;
307  };
308  std::vector<VerifyMessage> verify(const ConfigStore& options = {}) const;
309 
314  void printDot(std::ostream& os, Module*, const ConfigStore& archAttrs) const;
315 
320  void printSubmoduleDot(std::ostream& os, Module*) const;
321 
326  void printDot(std::ostream& os) const;
327 
331  void printDotClustered(std::ostream& os) const;
332 
336  void printSupportedOps(std::ostream& os) const;
337 
341  void printBasicStats(std::ostream& os) const;
342 
346  int initiationInterval() const { return nodes.size(); }
347 
351  std::ptrdiff_t size() const;
352 
357  const auto& allNodesByCycle() const { return nodes; }
358 
363  void renameNode(NodeDescriptor ndesc, std::string new_name);
364 private:
365  std::vector<std::map<std::string, std::unique_ptr<MRRGNode>>> nodes;
366  std::map<std::string, std::unique_ptr<MRRG>> subMRRGs;
367 
368  // Module::createMRRG needs to do some wizardry when merging MRRGs
369  friend Module;
370 };
371 
372 struct MrrgNodeSpan {
374  std::size_t _size;
375  std::size_t size() const { return _size; }
376  MRRG::NodeDescriptor const* data() const { return _data; }
377  MRRG::NodeDescriptor const* begin() const { return data(); }
378  MRRG::NodeDescriptor const* end() const { return data() + size(); }
379  MRRG::NodeDescriptor const& front() const { return *data(); }
380  MRRG::NodeDescriptor const& back() const { return *(data() + size() - 1); }
381 };
382 
383 inline std::ostream& operator<<(std::ostream& os, const MRRG::NodeDescriptor& ndesc) {
384  os << (void*)ndesc << ':';
385  if (ndesc) {
386  os << *ndesc;
387  } else {
388  os << "nullptr";
389  }
390  return os;
391 }
392 
400 template<typename M> // so we can capture const and mutable versions
401 auto makeNodeGetterForCycle(M& mrrg, int cycle) {
402  return [&mrrg, cycle](const std::string& name) {
403  return &mrrg.getNodeRef(cycle, name);
404  };
405 }
406 
414 bool verifyAndPrintReport(const MRRG& mrrg, std::ostream& os,
415  bool silent_on_no_errors, bool throw_if_errors, const ConfigStore& extra_opts = {});
416 
417 /*********************
418  * ################# *
419  * ################# *
420  *********************/
421 
422 inline char operator+(const MRRG::VerifyMessage::Type& vm_type) { return (char)vm_type; }
423 
424 inline std::ostream& operator<<(std::ostream& os, const MRRG::VerifyMessage::Type& vm_type) {
425  using Type = MRRG::VerifyMessage::Type;
426  switch (vm_type) {
427  case Type::Info: os << "Info"; break;
428  case Type::Warning: os << "Warning"; break;
429  case Type::Error: os << "Error"; break;
430  default: os << "MRRGVMTNotImplementedByPrinter" << +vm_type; break;
431  }
432  return os;
433 }
434 
435 #endif
436 
MRRG::link
void link(MRRG::NodeDescriptor driver, MRRG::NodeDescriptor fanout)
Definition: MRRG.cpp:849
MRRGNode::getFullName
std::string getFullName() const
Definition: MRRG.cpp:569
MRRG::getNodeRef
const MRRGNode & getNodeRef(NodeDescriptor ndesc) const
Definition: MRRG.h:274
MRRG_NODE_ROUTING_FUNCTION
@ MRRG_NODE_ROUTING_FUNCTION
Definition: MRRG.h:47
Util.h
MRRGNode::et
HWEntityType et
Definition: MRRG.h:108
MRRG::VerifyMessage::Type::Warning
@ Warning
MRRG::insertMultiFanin
std::pair< NodeDescriptor, bool > insertMultiFanin(NodeDescList fanins, MRRGNode node)
Definition: MRRG.h:242
HW_WIRE
@ HW_WIRE
Definition: MRRG.h:49
MRRG::getNodeRefByPropertiesOf
MRRGNode & getNodeRefByPropertiesOf(const MRRGNode &node)
Definition: MRRG.h:281
OpGraph.h
MRRG::allNodesByCycle
const auto & allNodesByCycle() const
Definition: MRRG.h:357
MRRG::getNodeRef
MRRGNode & getNodeRef(int cycle, const std::string &name)
Definition: MRRG.h:279
MRRGNode::delay
unsigned int delay
Definition: MRRG.h:128
MRRG
Definition: MRRG.h:216
MRRG::subMRRGs
std::map< std::string, std::unique_ptr< MRRG > > subMRRGs
Definition: MRRG.h:366
MRRG::NodeDescriptor
const MRRGNode * NodeDescriptor
Definition: MRRG.h:219
MRRG::VerifyMessage::message
std::string message
Definition: MRRG.h:306
MRRG::printSubmoduleDot
void printSubmoduleDot(std::ostream &os, Module *) const
Definition: MRRG.cpp:292
MRRGNode::type
MRRGNode_Type type
Definition: MRRG.h:107
MrrgNodeSpan::size
std::size_t size() const
Definition: MRRG.h:375
MRRGNode::capacity
int capacity
Definition: MRRG.h:136
MRRG::insert
std::pair< NodeDescriptor, bool > insert(NodeDescriptor fanin, MRRGNode node)
Definition: MRRG.h:239
MRRGNode::applyReferenceRename
void applyReferenceRename(const std::unordered_map< const MRRGNode *, MRRGNode * > &rename_map)
Definition: MRRG.cpp:59
verifyAndPrintReport
bool verifyAndPrintReport(const MRRG &mrrg, std::ostream &os, bool silent_on_no_errors, bool throw_if_errors, const ConfigStore &extra_opts={})
Definition: MRRG.cpp:473
MRRG::operator=
MRRG & operator=(const MRRG &rhs)
Definition: MRRG.cpp:68
MRRGNode::operator<<
friend std::ostream & operator<<(std::ostream &out, const MRRGNode &node)
Definition: MRRG.cpp:593
ConfigStore.h
MRRG::getNodeRefByPropertiesOf
const MRRGNode & getNodeRefByPropertiesOf(const MRRGNode &node) const
Definition: MRRG.h:282
makeNodeGetterForCycle
auto makeNodeGetterForCycle(M &mrrg, int cycle)
Definition: MRRG.h:401
MrrgNodeSpan::data
MRRG::NodeDescriptor const * data() const
Definition: MRRG.h:376
MRRG::erase
void erase(MRRG::NodeDescriptor n)
Definition: MRRG.cpp:109
MRRG::renameNode
void renameNode(NodeDescriptor ndesc, std::string new_name)
Definition: MRRG.cpp:799
MRRG::VerifyMessage::type
Type type
Definition: MRRG.h:305
ConfigStore
Definition: ConfigStore.h:76
MRRGNode::getContextNum
auto getContextNum() const
Definition: MRRG.h:124
MRRG::VerifyMessage::Type::Error
@ Error
MRRG::verify
std::vector< VerifyMessage > verify(const ConfigStore &options={}) const
Definition: MRRG.cpp:632
MRRG::printDot
void printDot(std::ostream &os, Module *, const ConfigStore &archAttrs) const
Definition: MRRG.cpp:151
HW_MUX
@ HW_MUX
Definition: MRRG.h:51
MRRG::getNodeByPropertiesOf
NodeDescriptor getNodeByPropertiesOf(const MRRGNode &node) const
Definition: MRRG.h:266
MRRG::insert
std::pair< NodeDescriptor, bool > insert(MRRGNode node)
Definition: MRRG.cpp:91
MRRG::VerifyMessage::Type::Info
@ Info
MRRGNode::parent
Module * parent
Definition: MRRG.h:119
MrrgNodeSpan::_data
MRRG::NodeDescriptor const * _data
Definition: MRRG.h:373
MUX_IN
@ MUX_IN
Definition: MRRG.h:45
Exception.h
MRRG::printSupportedOps
void printSupportedOps(std::ostream &os) const
Definition: MRRG.cpp:369
MRRG::unlink
void unlink(MRRG::NodeDescriptor driver, MRRG::NodeDescriptor fanout)
Definition: MRRG.cpp:850
MRRG::nodes
std::vector< std::map< std::string, std::unique_ptr< MRRGNode > > > nodes
Definition: MRRG.h:365
MrrgNodeSpan::begin
MRRG::NodeDescriptor const * begin() const
Definition: MRRG.h:377
MRRG::MRRG
MRRG(int II)
Definition: MRRG.h:221
MRRG::fanout
auto & fanout(NodeDescriptor ndesc) const
Definition: MRRG.h:288
operator<<
std::ostream & operator<<(std::ostream &os, const MRRG::NodeDescriptor &ndesc)
Definition: MRRG.h:383
MRRGNode::cycle
unsigned int cycle
Definition: MRRG.h:127
MRRGNode::canMapOp
bool canMapOp(OpGraphOp const *op) const
Definition: MRRG.cpp:581
MrrgNodeSpan::end
MRRG::NodeDescriptor const * end() const
Definition: MRRG.h:378
MRRG::getNodeRef
MRRGNode & getNodeRef(NodeDescriptor ndesc)
Definition: MRRG.h:273
MRRGNode::make_operand_pin
static MRRGNode make_operand_pin(Module *parent, int bitwidth, int cycle, STR &&name, SupportedOpTags operand_tags, int latency=0, int max_cap=1)
Definition: MRRG.h:164
cgrame_model_error
Definition: Exception.h:48
MRRGNode::fanin
std::vector< MRRGNode * > fanin
Definition: MRRG.h:114
HW_COMB
@ HW_COMB
Definition: MRRG.h:52
HW_REG
@ HW_REG
Definition: MRRG.h:50
MRRGNode::make_function
static MRRGNode make_function(Module *parent, int bitwidth, int cycle, STR &&name, int latency, SupportedOps supported_ops, int max_cap=1, bool is_const_unit=false)
Definition: MRRG.h:191
MRRG_NODE_FUNCTION
@ MRRG_NODE_FUNCTION
Definition: MRRG.h:46
HWEntityType
HWEntityType
Definition: MRRG.h:48
NodePortType
NodePortType
Definition: MRRG.h:42
Module
Definition: Module.h:163
MRRG::Module
friend Module
Definition: MRRG.h:369
MrrgNodeSpan::_size
std::size_t _size
Definition: MRRG.h:374
MRRG::printDotClustered
void printDotClustered(std::ostream &os) const
Definition: MRRG.cpp:505
MRRG::fanin
auto & fanin(NodeDescriptor ndesc) const
Definition: MRRG.h:293
HW_UNSPECIFIED
@ HW_UNSPECIFIED
Definition: MRRG.h:53
MRRG_NODE_ROUTING
@ MRRG_NODE_ROUTING
Definition: MRRG.h:45
MRRGNode::supported_ops
std::vector< OpGraphOpCode > supported_ops
Definition: MRRG.h:111
MRRGNode::getHierarchyQualifiedName
const std::string & getHierarchyQualifiedName() const
Definition: MRRG.h:122
OpGraphOp
Definition: OpGraph.h:131
MRRGNode
Definition: MRRG.h:60
MrrgNodeSpan::front
MRRG::NodeDescriptor const & front() const
Definition: MRRG.h:379
MrrgNodeSpan::back
MRRG::NodeDescriptor const & back() const
Definition: MRRG.h:380
MRRGNode::SupportedOpTags
std::set< std::string > SupportedOpTags
Definition: MRRG.h:63
MRRG::MRRG
MRRG(const MRRG &src)
Definition: MRRG.h:225
MRRGNode::fanout
std::vector< MRRGNode * > fanout
Definition: MRRG.h:113
MRRG::size
std::ptrdiff_t size() const
Definition: MRRG.cpp:558
MRRG::getNode
NodeDescriptor getNode(int cycle, const std::string &name) const
Definition: MRRG.cpp:142
MRRG::getNodeRef
const MRRGNode & getNodeRef(int cycle, const std::string &name) const
Definition: MRRG.h:280
operator+
char operator+(const MRRG::VerifyMessage::Type &vm_type)
Definition: MRRG.h:422
MRRGNode::bitwidth
unsigned int bitwidth
Definition: MRRG.h:129
MRRGNode::supported_operand_tags
SupportedOpTags supported_operand_tags
Definition: MRRG.h:117
MRRG::initiationInterval
int initiationInterval() const
Definition: MRRG.h:346
MRRGNode_Type
MRRGNode_Type
Definition: MRRG.h:36
MRRGNode::getLatency
auto getLatency() const
Definition: MRRG.h:125
MRRGNode::MRRGNode
MRRGNode(Module *parent, int cycle, std::string name, MRRGNode_Type type, int latency, int bitwidth, SupportedOps &&supported_ops, HWEntityType et, SupportedOpTags supported_operand_tags, int max_cap=1)
Definition: MRRG.h:65
MRRG::VerifyMessage
Definition: MRRG.h:303
MRRGNode::make_routing
static MRRGNode make_routing(Module *parent, int bitwidth, int cycle, STR &&name, int latency=0, int max_cap=1)
Definition: MRRG.h:151
MRRGNode::latency
int latency
Definition: MRRG.h:132
MRRGNode::make_routing_function
static MRRGNode make_routing_function(Module *parent, int bitwidth, int cycle, STR &&name, int latency, SupportedOpTags operand_tags, SupportedOps supported_ops, int max_cap=1)
Definition: MRRG.h:177
MRRGNode::operator=
MRRGNode & operator=(const MRRGNode &)=default
MRRG::VerifyMessage::Type
Type
Definition: MRRG.h:304
OpGraph
Definition: OpGraph.h:215
MRRGNode::name
std::string name
Definition: MRRG.h:106
UNSPECIFIED
@ UNSPECIFIED
Definition: MRRG.h:43
MrrgNodeSpan
Definition: MRRG.h:372
MRRG::printBasicStats
void printBasicStats(std::ostream &os) const
Definition: MRRG.cpp:541
MUX_OUT
@ MUX_OUT
Definition: MRRG.h:44