Cerata
A library to generate structural hardware designs
node.h
1 // Copyright 2018-2019 Delft University of Technology
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <utility>
18 #include <optional>
19 #include <string>
20 #include <memory>
21 #include <vector>
22 #include <unordered_map>
23 
24 #include "cerata/object.h"
25 #include "cerata/type.h"
26 #include "cerata/domain.h"
27 
28 namespace cerata {
29 
30 // Forward declarations.
31 class Edge;
32 class Graph;
33 class Port;
34 class Literal;
35 class Signal;
36 class Parameter;
37 class Expression;
38 
42 class Node : public Object, public std::enable_shared_from_this<Node> {
43  public:
45  enum class NodeID {
46  PORT,
47  SIGNAL,
48  PARAMETER,
49  LITERAL,
50  EXPRESSION,
51  };
52 
54  Node(std::string name, NodeID id, std::shared_ptr<Type> type);
55 
57  inline Type *type() const { return type_.get(); }
59  Node *SetType(const std::shared_ptr<Type> &type);
60 
62  inline NodeID node_id() const { return node_id_; }
64  inline bool Is(NodeID node_id) const { return node_id_ == node_id; }
65 
67 #ifndef NODE_CAST_DECL_FACTORY
68 #define NODE_CAST_DECL_FACTORY(NODE_TYPE, NODE_ID) \
69  inline bool Is##NODE_TYPE() const { return node_id_ == (NodeID::NODE_ID); } \
70  NODE_TYPE* As##NODE_TYPE(); \
71  const NODE_TYPE* As##NODE_TYPE() const;
72 #endif
73  NODE_CAST_DECL_FACTORY(Port, PORT)
74  NODE_CAST_DECL_FACTORY(Signal, SIGNAL)
75  NODE_CAST_DECL_FACTORY(Literal, LITERAL)
76  NODE_CAST_DECL_FACTORY(Parameter, PARAMETER)
77  NODE_CAST_DECL_FACTORY(Expression, EXPRESSION)
78 
79 
80  virtual bool AddEdge(const std::shared_ptr<Edge> &edge) = 0;
82  virtual bool RemoveEdge(Edge *edge) = 0;
84  virtual std::vector<Edge *> edges() const;
86  virtual std::vector<Edge *> sources() const { return {}; }
88  virtual std::vector<Edge *> sinks() const { return {}; }
89 
93  std::optional<NodeArray *> array() const { return array_; }
94 
96  Node *Replace(Node *replacement);
97 
114  virtual Node *CopyOnto(Graph *dst, const std::string &name, NodeMap *rebinding) const;
115 
117  void AppendReferences(std::vector<Object *> *out) const override;
118 
120  virtual std::string ToString() const;
121 
122  protected:
126  std::shared_ptr<Type> type_;
128  std::optional<NodeArray *> array_ = {};
129 };
130 
132 std::string ToString(Node::NodeID id);
133 
135 typedef std::unordered_map<const Node *, Node *> NodeMap;
136 
140 struct MultiOutputNode : public Node {
142  std::vector<std::shared_ptr<Edge>> outputs_;
143 
145  MultiOutputNode(std::string name, Node::NodeID id, std::shared_ptr<Type> type)
146  : Node(std::move(name), id, std::move(type)) {}
147 
149  std::vector<Edge *> sources() const override { return {}; }
151  std::vector<Edge *> sinks() const override { return ToRawPointers(outputs_); }
152 
154  bool RemoveEdge(Edge *edge) override;
156  bool AddEdge(const std::shared_ptr<Edge> &edge) override;
157 
159  inline std::shared_ptr<Edge> output(size_t i) const { return outputs_[i]; }
161  inline size_t num_outputs() const { return outputs_.size(); }
162 };
163 
167 struct NormalNode : public MultiOutputNode {
169  std::shared_ptr<Edge> input_;
170 
172  NormalNode(std::string name, Node::NodeID id, std::shared_ptr<Type> type)
173  : MultiOutputNode(std::move(name), id, std::move(type)) {}
174 
176  std::vector<Edge *> sources() const override;
177 
179  std::optional<Edge *> input() const;
180 
182  bool AddEdge(const std::shared_ptr<Edge> &edge) override;
183 
185  bool RemoveEdge(Edge *edge) override;
186 };
187 
193 void GetObjectReferences(const Object &obj, std::vector<Object *> *out);
194 
196 void ImplicitlyRebindNodes(Graph *dst, const std::vector<Node *> &nodes, NodeMap *rebinding);
197 
198 } // namespace cerata
cerata::Node::sinks
virtual std::vector< Edge * > sinks() const
Get the output edges of this Node.
Definition: node.h:88
cerata::MultiOutputNode::AddEdge
bool AddEdge(const std::shared_ptr< Edge > &edge) override
Add an output edge to this node.
Definition: node.cc:163
cerata::Node::SetType
Node * SetType(const std::shared_ptr< Type > &type)
Set the node Type.
Definition: node.cc:115
cerata::Node::sources
virtual std::vector< Edge * > sources() const
Get the input edges of this Node.
Definition: node.h:86
cerata::NormalNode::NormalNode
NormalNode(std::string name, Node::NodeID id, std::shared_ptr< Type > type)
NormalNode constructor.
Definition: node.h:172
cerata::NormalNode::AddEdge
bool AddEdge(const std::shared_ptr< Edge > &edge) override
Add an edge to this node.
Definition: node.cc:205
cerata::Node::NodeID::LITERAL
@ LITERAL
No-input AND multi-output node with storage type and storage value.
cerata::Literal
A Literal Node.
Definition: literal.h:36
cerata::NormalNode::input_
std::shared_ptr< Edge > input_
The incoming Edge that sources this Node.
Definition: node.h:169
cerata::NormalNode::sources
std::vector< Edge * > sources() const override
Return the incoming edges (in this case just the single input edge).
Definition: node.cc:197
cerata::MultiOutputNode::outputs_
std::vector< std::shared_ptr< Edge > > outputs_
The outgoing Edges that sink this Node.
Definition: node.h:142
cerata::Expression
A node representing a binary tree of other nodes.
Definition: expression.h:34
cerata::Graph
A graph representing a hardware structure.
Definition: graph.h:37
cerata::NodeArray
An array of nodes.
Definition: array.h:31
cerata::ToRawPointers
std::vector< T * > ToRawPointers(const std::vector< std::shared_ptr< T >> &list)
Convert a list of shared pointers to raw pointers.
Definition: utils.h:125
cerata::Node::Replace
Node * Replace(Node *replacement)
Replace some node with another node, reconnecting all original edges. Returns the replaced node.
Definition: node.cc:76
cerata::Type
A Type.
Definition: type.h:63
cerata::Signal
A Signal Node.
Definition: signal.h:30
cerata::MultiOutputNode::num_outputs
size_t num_outputs() const
Return the number of edges of this node.
Definition: node.h:161
cerata
Contains every Cerata class, function, etc...
Definition: api.h:41
cerata::Node::type_
std::shared_ptr< Type > type_
The Type of this Node.
Definition: node.h:126
cerata::Node::Is
bool Is(NodeID node_id) const
Return whether this node is of a specific node type id.
Definition: node.h:64
cerata::Node
A node.
Definition: node.h:42
cerata::Node::Node
Node(std::string name, NodeID id, std::shared_ptr< Type > type)
Node constructor.
Definition: node.cc:32
cerata::NodeMap
std::unordered_map< const Node *, Node * > NodeMap
A mapping from one object to another object, used in e.g. type generic rebinding.
Definition: node.h:135
cerata::Node::NodeID::PARAMETER
@ PARAMETER
Single-input AND multi-output node with default value.
cerata::Node::node_id
NodeID node_id() const
Return the node type ID.
Definition: node.h:62
cerata::Named::name
std::string name() const
Return the name of the object.
Definition: utils.h:45
cerata::Node::NodeID
NodeID
Node type IDs with different properties.
Definition: node.h:45
cerata::Node::RemoveEdge
virtual bool RemoveEdge(Edge *edge)=0
Remove an edge of this node.
cerata::Node::edges
virtual std::vector< Edge * > edges() const
Return all edges this Node is on.
Definition: node.cc:106
cerata::Edge
A directed edge between two nodes.
Definition: edge.h:35
cerata::NormalNode
A single-input, multiple-outputs node.
Definition: node.h:167
cerata::Node::NodeID::EXPRESSION
@ EXPRESSION
No-input AND multi-output node that forms a binary tree with operations and nodes.
cerata::GetObjectReferences
void GetObjectReferences(const Object &obj, std::vector< Object * > *out)
Get any sub-objects that are used by an object, e.g. type generic nodes or array size nodes.
Definition: node.cc:247
cerata::Node::AddEdge
virtual bool AddEdge(const std::shared_ptr< Edge > &edge)=0
Add an edge to this node.
cerata::MultiOutputNode::output
std::shared_ptr< Edge > output(size_t i) const
Return output edge i of this node.
Definition: node.h:159
cerata::Node::node_id_
NodeID node_id_
Node type ID.
Definition: node.h:124
cerata::Object
A Cerata Object on a graph.
Definition: object.h:34
cerata::Node::NodeID::SIGNAL
@ SIGNAL
Single-input AND multi-output node.
cerata::vector
std::shared_ptr< Type > vector(const std::string &name, const std::shared_ptr< Node > &width)
Create a new vector type, and return a shared pointer to it.
Definition: type.cc:193
cerata::Parameter
A Parameter node.
Definition: parameter.h:29
cerata::MultiOutputNode::sources
std::vector< Edge * > sources() const override
Return the incoming edges (in this case just the single input edge) that sources this Node.
Definition: node.h:149
cerata::Node::array_
std::optional< NodeArray * > array_
Parent if this belongs to an array.
Definition: node.h:128
cerata::MultiOutputNode::sinks
std::vector< Edge * > sinks() const override
The outgoing Edges that this Node sinks.
Definition: node.h:151
cerata::MultiOutputNode::RemoveEdge
bool RemoveEdge(Edge *edge) override
Remove an edge from this node.
Definition: node.cc:177
cerata::Node::ToString
virtual std::string ToString() const
Return a human-readable string of this node.
Definition: node.cc:35
cerata::Node::SetArray
void SetArray(NodeArray *array)
Set parent array.
Definition: node.h:91
cerata::Node::AppendReferences
void AppendReferences(std::vector< Object * > *out) const override
Return all objects referenced by this node. For default nodes, these are type generics only.
Definition: node.cc:120
cerata::MultiOutputNode::MultiOutputNode
MultiOutputNode(std::string name, Node::NodeID id, std::shared_ptr< Type > type)
MultiOutputNode constructor.
Definition: node.h:145
cerata::NormalNode::input
std::optional< Edge * > input() const
Return the single incoming edge.
Definition: node.cc:190
cerata::Node::NodeID::PORT
@ PORT
Single-input AND multi-output node with direction.
cerata::Node::CopyOnto
virtual Node * CopyOnto(Graph *dst, const std::string &name, NodeMap *rebinding) const
Copy node onto a graph, implicitly copying over and rebinding e.g. type generics of referenced nodes.
Definition: node.cc:54
cerata::Node::array
std::optional< NodeArray * > array() const
Return parent array, if any.
Definition: node.h:93
cerata::Port
A port is a terminator node on a graph.
Definition: port.h:57
cerata::Node::type
Type * type() const
Return the node Type.
Definition: node.h:57
cerata::NormalNode::RemoveEdge
bool RemoveEdge(Edge *edge) override
Remove an edge from this node.
Definition: node.cc:223
cerata::ImplicitlyRebindNodes
void ImplicitlyRebindNodes(Graph *dst, const std::vector< Node * > &nodes, NodeMap *rebinding)
Make sure that the NodeMap contains all nodes to be rebound onto the destination graph.
Definition: node.cc:39
cerata::MultiOutputNode
A no-input, multiple-outputs node.
Definition: node.h:140