 |
Cerata
A library to generate structural hardware designs
|
15 #include "cerata/node.h"
23 #include "cerata/utils.h"
24 #include "cerata/edge.h"
25 #include "cerata/pool.h"
26 #include "cerata/graph.h"
27 #include "cerata/expression.h"
28 #include "cerata/parameter.h"
33 :
Object(std::move(name),
Object::NODE), node_id_(id), type_(std::move(type)) {}
40 for (
const auto &n : nodes) {
41 if (rebinding->count(n) > 0) {
44 }
else if (dst->
Has(n->name())) {
46 (*rebinding)[n] = dst->
Get<
Node>(n->name());
47 }
else if (!n->IsLiteral()) {
56 auto result = std::dynamic_pointer_cast<Node>(this->
Copy());
57 result->SetName(
name);
61 if (!generics.empty()) {
65 auto rebound_type = result->type()->Copy(*rebinding);
67 result->SetType(rebound_type);
70 (*rebinding)[
this] = result.get();
78 for (
const auto &e : this->
sources()) {
85 for (
const auto &e : this->
sinks()) {
93 this->
parent().value()->Remove(
this);
94 this->
parent().value()->Add(this->shared_from_this());
97 if (this->IsParameter()) {
98 auto param = this->AsParameter();
99 if (param->node_array_parent) {
100 param->node_array_parent.value()->SetSize(replacement->shared_from_this());
109 std::vector<Edge *>
edges;
110 edges.insert(
edges.end(), snk.begin(), snk.end());
111 edges.insert(
edges.end(), src.begin(), src.end());
121 for (
const auto &g :
type()->GetGenerics()) {
124 g->AppendReferences(out);
129 #ifndef NODE_CAST_IMPL_FACTORY
130 #define NODE_CAST_IMPL_FACTORY(NODENAME) \
131 NODENAME * Node::As##NODENAME() { auto result = dynamic_cast<NODENAME*>(this); \
132 if (result != nullptr) { \
135 CERATA_LOG(FATAL, "Node is not " + std::string(#NODENAME)); \
137 const NODENAME* Node::As##NODENAME() const { auto result = dynamic_cast<const NODENAME*>(this); \
138 if (result != nullptr) { \
141 CERATA_LOG(FATAL, "Node is not " + std::string(#NODENAME)); \
146 NODE_CAST_IMPL_FACTORY(
Port)
147 NODE_CAST_IMPL_FACTORY(
Signal)
149 NODE_CAST_IMPL_FACTORY(
Literal)
152 #ifndef TYPE_STRINGIFICATION_FACTORY
153 #define TYPE_STRINGIFICATION_FACTORY(NODE_TYPE) \
155 std::string ToString<NODE_TYPE>() { return #NODE_TYPE; }
157 TYPE_STRINGIFICATION_FACTORY(
Port)
158 TYPE_STRINGIFICATION_FACTORY(
Signal)
159 TYPE_STRINGIFICATION_FACTORY(
Literal)
164 bool success =
false;
166 if (edge->src() ==
this) {
170 outputs_.push_back(edge);
178 if (edge->
src() ==
this) {
181 if (i->get() == edge) {
213 if (edge->dst() ==
this) {
227 if ((edge->
dst() !=
nullptr) && !success) {
228 if ((edge->
dst() ==
this) && (
input_.get() == edge)) {
244 throw std::runtime_error(
"Corrupted node type.");
250 auto &node =
dynamic_cast<const Node &
>(obj);
253 for (
const auto &p : params) {
260 auto &array =
dynamic_cast<const NodeArray &
>(obj);
264 out->push_back(array.size());
virtual std::vector< Edge * > sinks() const
Get the output edges of this Node.
bool AddEdge(const std::shared_ptr< Edge > &edge) override
Add an output edge to this node.
Node * SetType(const std::shared_ptr< Type > &type)
Set the node Type.
virtual std::vector< Edge * > sources() const
Get the input edges of this Node.
virtual Graph & Add(const std::shared_ptr< Object > &object)
Add an object to the component.
bool AddEdge(const std::shared_ptr< Edge > &edge) override
Add an edge to this node.
@ LITERAL
No-input AND multi-output node with storage type and storage value.
Node * dst() const
Return the destination node.
bool IsNode() const
Return true if this object is a node.
Node * src() const
Return the source node.
std::shared_ptr< Edge > input_
The incoming Edge that sources this Node.
std::vector< Edge * > sources() const override
Return the incoming edges (in this case just the single input edge).
std::vector< std::shared_ptr< Edge > > outputs_
The outgoing Edges that sink this Node.
A node representing a binary tree of other nodes.
A graph representing a hardware structure.
Node * Replace(Node *replacement)
Replace some node with another node, reconnecting all original edges. Returns the replaced node.
Contains every Cerata class, function, etc...
std::shared_ptr< Type > type_
The Type of this Node.
Node(std::string name, NodeID id, std::shared_ptr< Type > type)
Node constructor.
std::unordered_map< const Node *, Node * > NodeMap
A mapping from one object to another object, used in e.g. type generic rebinding.
bool IsArray() const
Return true if this object is an array.
virtual std::shared_ptr< Object > Copy() const =0
Deep-copy the object.
@ PARAMETER
Single-input AND multi-output node with default value.
T * Get(const std::string &name) const
Get one object of a specific type.
std::string name() const
Return the name of the object.
NodeID
Node type IDs with different properties.
std::string ToString(Expression::Op operation)
Human-readable expression operator.
virtual bool RemoveEdge(Edge *edge)=0
Remove an edge of this node.
virtual std::vector< Edge * > edges() const
Return all edges this Node is on.
A directed edge between two nodes.
@ EXPRESSION
No-input AND multi-output node that forms a binary tree with operations and nodes.
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.
A Cerata Object on a graph.
@ SIGNAL
Single-input AND multi-output node.
bool Contains(const std::vector< std::shared_ptr< T >> &list, const std::shared_ptr< T > &item)
Return true if vector contains item, false otherwise.
bool Has(const std::string &name)
Return true if object with name already exists on graph.
bool RemoveEdge(Edge *edge) override
Remove an edge from this node.
virtual std::string ToString() const
Return a human-readable string of this node.
virtual std::vector< Node * > GetGenerics() const
Obtain any nodes that this type uses as generics.
void AppendReferences(std::vector< Object * > *out) const override
Return all objects referenced by this node. For default nodes, these are type generics only.
std::optional< Edge * > input() const
Return the single incoming edge.
@ PORT
Single-input AND multi-output node with direction.
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.
virtual std::optional< Graph * > parent() const
Return the parent graph of this object, if any. Returns empty option otherwise.
A port is a terminator node on a graph.
Type * type() const
Return the node Type.
bool RemoveEdge(Edge *edge) override
Remove an edge from this node.
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.
A no-input, multiple-outputs node.
std::shared_ptr< Edge > Connect(Node *dst, Node *src)
Connect two nodes, returns the corresponding edge.