nndeploy C++ API  0.2.0
nndeploy C++ API
composite_node.h
Go to the documentation of this file.
1 #ifndef _NNDEPLOY_DAG_COMPOSITE_NODE_H_
2 #define _NNDEPLOY_DAG_COMPOSITE_NODE_H_
3 
4 #include "nndeploy/dag/edge.h"
5 #include "nndeploy/dag/graph.h"
6 #include "nndeploy/dag/node.h"
7 #include "nndeploy/dag/util.h"
8 
9 namespace nndeploy {
10 namespace dag {
11 
19  public:
20  CompositeNode(const std::string &name) : dag::Node(name) {
21  key_ = "nndeploy::dag::CompositeNode";
22  is_composite_node_ = true;
23  }
24  CompositeNode(const std::string &name, const std::vector<Edge *> &inputs,
25  const std::vector<Edge *> &outputs)
26  : dag::Node(name, inputs, outputs) {
27  key_ = "nndeploy::dag::CompositeNode";
28  for (auto input : inputs) {
29  if (nullptr == addEdge(input)) {
30  constructed_ = false;
31  return;
32  }
33  }
34  for (auto output : outputs) {
35  if (nullptr == addEdge(output)) {
36  constructed_ = false;
37  return;
38  }
39  }
40  constructed_ = true;
41  is_composite_node_ = true;
42  }
43  virtual ~CompositeNode();
44 
45  virtual base::Status setInput(Edge *input, int index = -1);
46  virtual base::Status setOutput(Edge *output, int index = -1);
47 
48  virtual base::Status setInputs(std::vector<Edge *> inputs);
49  virtual base::Status setOutputs(std::vector<Edge *> outputs);
50 
51  virtual base::Status setInputSharedPtr(std::shared_ptr<Edge> input,
52  int index = -1);
53  virtual base::Status setOutputSharedPtr(std::shared_ptr<Edge> output,
54  int index = -1);
55 
57  std::vector<std::shared_ptr<Edge>> inputs);
59  std::vector<std::shared_ptr<Edge>> outputs);
60 
61  // create edge
62  Edge *createEdge(const std::string &name);
63  std::shared_ptr<Edge> createEdgeSharedPtr(const std::string &name);
64 
65  // add edge
66  EdgeWrapper *addEdge(Edge *edge, bool is_external = true);
67  EdgeWrapper *addEdgeSharedPtr(std::shared_ptr<Edge> edge);
68 
69  // get edge
70  Edge *getEdge(const std::string &name);
71  std::shared_ptr<Edge> getEdgeSharedPtr(const std::string &name);
72 
73  // update edge
74  base::Status updteEdge(EdgeWrapper *edge_wrapper, Edge *edge,
75  bool is_external = true);
76 
77  // create node
78  Node *createNode(const NodeDesc &desc);
79 
80  template <typename T, typename... Args,
81  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
82  Node *createNode(const std::string &name, Args &...args);
83 
84  template <typename T, typename... Args,
85  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
86  Node *createNode(const NodeDesc &desc, Args &...args);
87 
88  template <typename T, typename... Args,
89  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
90  Node *createInfer(const NodeDesc &desc, base::InferenceType type);
91 
92  base::Status setNodeDesc(Node *node, const NodeDesc &desc);
93 
94  // add node
95  base::Status addNode(Node *node, bool is_external = true);
96  base::Status addNodeSharedPtr(std::shared_ptr<Node> node);
97 
98  // update node io
99  base::Status updateNodeIO(Node *node, std::vector<Edge *> inputs,
100  std::vector<Edge *> outputs);
101  base::Status markInputEdge(std::vector<Edge *> inputs);
102  base::Status markOutputEdge(std::vector<Edge *> outputs);
103 
104  // get node
105  Node *getNode(const std::string &name);
106  std::shared_ptr<Node> getNodeSharedPtr(const std::string &name);
107  Node *getNodeByKey(const std::string &key);
108  std::vector<Node *> getNodesByKey(const std::string &key);
109 
110  // set node param
111  base::Status setNodeParam(const std::string &node_name, base::Param *param);
112  base::Param *getNodeParam(const std::string &node_name);
113  base::Status setNodeParamSharedPtr(const std::string &node_name,
114  std::shared_ptr<base::Param> param);
115  std::shared_ptr<base::Param> getNodeParamSharedPtr(
116  const std::string &node_name);
117 
119 
120  virtual base::Status init();
121  virtual base::Status deinit();
122 
123  virtual base::Status run() = 0;
124 
126  EdgeWrapper *getEdgeWrapper(const std::string &name);
127 
129  NodeWrapper *getNodeWrapper(const std::string &name);
130 
131  Node *createNode4Py(const NodeDesc &desc);
132 
133  // to json
134  virtual base::Status serialize(rapidjson::Value &json,
135  rapidjson::Document::AllocatorType &allocator);
136  virtual std::string serialize();
137  // from json
138  virtual base::Status deserialize(rapidjson::Value &json);
139  virtual base::Status deserialize(const std::string &json_str);
140 
141  std::vector<NodeWrapper *> sortDFS();
142 
143  protected:
145 
146  protected:
147  std::vector<EdgeWrapper *> edge_repository_;
148  std::vector<NodeWrapper *> node_repository_;
149  std::vector<std::shared_ptr<Edge>> shared_edge_repository_;
150  std::vector<std::shared_ptr<Node>> shared_node_repository_;
151  std::set<std::string> used_node_names_;
152  std::set<std::string> used_edge_names_;
153 };
154 
155 template <typename T, typename... Args,
156  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
157 Node *CompositeNode::createNode(const std::string &name, Args &...args) {
158  if (used_node_names_.find(name) != used_node_names_.end()) {
159  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
160  return nullptr;
161  }
162  std::vector<Edge *> inputs;
163  std::vector<Edge *> outputs;
164  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
165  NodeWrapper *node_wrapper = new NodeWrapper();
166  node_wrapper->is_external_ = false;
167  node_wrapper->node_ = node;
168  node_wrapper->name_ = name;
169  node_repository_.emplace_back(node_wrapper);
170  used_node_names_.insert(name);
171 
172  node->setCompositeNode(this);
173  return node;
174 }
175 
176 template <typename T, typename... Args,
177  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
178 Node *CompositeNode::createNode(const NodeDesc &desc, Args &...args) {
179  const std::string &name = desc.getName();
180  // const std::string &node_key = desc.getKey();
181  std::vector<std::string> input_names = desc.getInputs();
182  std::vector<std::string> output_names = desc.getOutputs();
183 
184  if (used_node_names_.find(name) != used_node_names_.end()) {
185  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
186  return nullptr;
187  }
188  std::vector<Edge *> inputs;
189  for (auto input_name : input_names) {
190  Edge *input = getEdge(input_name);
191  if (input == nullptr) {
192  input = createEdge(input_name);
193  }
194  inputs.emplace_back(input);
195  }
196  std::vector<Edge *> outputs;
197  for (auto output_name : output_names) {
198  Edge *output = getEdge(output_name);
199  if (output == nullptr) {
200  output = createEdge(output_name);
201  }
202  outputs.emplace_back(output);
203  }
204  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
205  if (node == nullptr) {
206  NNDEPLOY_LOGE("create node[%s] failed!\n", name.c_str());
207  return nullptr;
208  }
209  NodeWrapper *node_wrapper = new NodeWrapper();
210  node_wrapper->is_external_ = false;
211  node_wrapper->node_ = node;
212  node_wrapper->name_ = name;
213  for (auto input : inputs) {
214  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
215  if (input_wrapper == nullptr) {
216  input_wrapper = this->addEdge(input);
217  }
218  input_wrapper->consumers_.emplace_back(node_wrapper);
219  }
220  for (auto output : outputs) {
221  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
222  if (output_wrapper == nullptr) {
223  output_wrapper = this->addEdge(output);
224  }
225  output_wrapper->producers_.emplace_back(node_wrapper);
226  }
227 
228  node_repository_.emplace_back(node_wrapper);
229  used_node_names_.insert(name);
230 
231  node->setCompositeNode(this);
232 
233  return node;
234 }
235 
236 template <typename T, typename... Args,
237  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
239  base::InferenceType type) {
240  const std::string &name = desc.getName();
241  // const std::string &node_key = desc.getKey();
242  std::vector<std::string> input_names = desc.getInputs();
243  std::vector<std::string> output_names = desc.getOutputs();
244 
245  if (used_node_names_.find(name) != used_node_names_.end()) {
246  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
247  return nullptr;
248  }
249  std::vector<Edge *> inputs;
250  for (auto input_name : input_names) {
251  Edge *input = getEdge(input_name);
252  if (input == nullptr) {
253  input = createEdge(input_name);
254  }
255  inputs.emplace_back(input);
256  }
257  std::vector<Edge *> outputs;
258  for (auto output_name : output_names) {
259  Edge *output = getEdge(output_name);
260  if (output == nullptr) {
261  output = createEdge(output_name);
262  }
263  outputs.emplace_back(output);
264  }
265  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
266  if (node == nullptr) {
267  NNDEPLOY_LOGE("create node[%s] failed!\n", name.c_str());
268  return nullptr;
269  }
270  NodeWrapper *node_wrapper = new NodeWrapper();
271  node_wrapper->is_external_ = false;
272  node_wrapper->node_ = node;
273  node_wrapper->name_ = name;
274  for (auto input : inputs) {
275  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
276  if (input_wrapper == nullptr) {
277  input_wrapper = this->addEdge(input);
278  }
279  input_wrapper->consumers_.emplace_back(node_wrapper);
280  }
281  for (auto output : outputs) {
282  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
283  if (output_wrapper == nullptr) {
284  output_wrapper = this->addEdge(output);
285  }
286  output_wrapper->producers_.emplace_back(node_wrapper);
287  }
288 
289  node_repository_.emplace_back(node_wrapper);
290  used_node_names_.insert(name);
291 
292  node->setCompositeNode(this);
293 
294  return node;
295 }
296 
297 } // namespace dag
298 } // namespace nndeploy
299 
300 #endif /* _NNDEPLOY_DAG_COMPOSITE_NODE_H_ */
Composite node Composite node is a special type of node in nndeploy that enhances the capabilities of...
EdgeWrapper * addEdgeSharedPtr(std::shared_ptr< Edge > edge)
Node * createInfer(const NodeDesc &desc, base::InferenceType type)
base::Status setNodeDesc(Node *node, const NodeDesc &desc)
EdgeWrapper * getEdgeWrapper(Edge *edge)
std::shared_ptr< Node > getNodeSharedPtr(const std::string &name)
Edge * createEdge(const std::string &name)
base::Status markInputEdge(std::vector< Edge * > inputs)
virtual base::Status setInputSharedPtr(std::shared_ptr< Edge > input, int index=-1)
Set input edge (shared pointer)
std::set< std::string > used_edge_names_
std::shared_ptr< base::Param > getNodeParamSharedPtr(const std::string &node_name)
virtual base::Status deserialize(rapidjson::Value &json)
Deserialize from JSON.
Node * getNodeByKey(const std::string &key)
base::Status addNodeSharedPtr(std::shared_ptr< Node > node)
NodeWrapper * getNodeWrapper(const std::string &name)
virtual base::Status init()
Initialize node.
virtual base::Status setOutputSharedPtr(std::shared_ptr< Edge > output, int index=-1)
Set output edge (shared pointer)
std::vector< NodeWrapper * > sortDFS()
EdgeWrapper * getEdgeWrapper(const std::string &name)
std::set< std::string > used_node_names_
std::vector< std::shared_ptr< Node > > shared_node_repository_
NodeWrapper * getNodeWrapper(Node *node)
virtual base::Status construct()
base::Status setNodeParam(const std::string &node_name, base::Param *param)
Node * createNode(const NodeDesc &desc)
virtual base::Status setInputsSharedPtr(std::vector< std::shared_ptr< Edge >> inputs)
Set all input edges (shared pointer)
base::Status addNode(Node *node, bool is_external=true)
std::vector< Node * > getNodesByKey(const std::string &key)
virtual base::Status run()=0
Run node (pure virtual function)
virtual base::Status setOutputsSharedPtr(std::vector< std::shared_ptr< Edge >> outputs)
Set all output edges (shared pointer)
virtual base::Status deinit()
Deinitialize node.
base::Status updteEdge(EdgeWrapper *edge_wrapper, Edge *edge, bool is_external=true)
CompositeNode(const std::string &name, const std::vector< Edge * > &inputs, const std::vector< Edge * > &outputs)
std::shared_ptr< Edge > createEdgeSharedPtr(const std::string &name)
CompositeNode(const std::string &name)
Edge * getEdge(const std::string &name)
Node * createNode4Py(const NodeDesc &desc)
Node * getNode(const std::string &name)
virtual base::Status setInput(Edge *input, int index=-1)
Set input edge.
EdgeWrapper * addEdge(Edge *edge, bool is_external=true)
base::Status updateNodeIO(Node *node, std::vector< Edge * > inputs, std::vector< Edge * > outputs)
base::Param * getNodeParam(const std::string &node_name)
virtual base::Status defaultParam()
Configure default parameters.
std::vector< std::shared_ptr< Edge > > shared_edge_repository_
virtual base::Status deserialize(const std::string &json_str)
Deserialize from JSON string.
std::vector< EdgeWrapper * > edge_repository_
virtual std::string serialize()
Serialize to JSON string.
std::vector< NodeWrapper * > node_repository_
std::shared_ptr< Edge > getEdgeSharedPtr(const std::string &name)
virtual base::Status setOutput(Edge *output, int index=-1)
Set output edge.
virtual base::Status serialize(rapidjson::Value &json, rapidjson::Document::AllocatorType &allocator)
Serialize to JSON.
virtual base::Status setInputs(std::vector< Edge * > inputs)
Set all input edges.
base::Status markOutputEdge(std::vector< Edge * > outputs)
virtual base::Status setOutputs(std::vector< Edge * > outputs)
Set all output edges.
base::Status setNodeParamSharedPtr(const std::string &node_name, std::shared_ptr< base::Param > param)
std::vector< NodeWrapper * > producers_
Definition: util.h:32
std::vector< NodeWrapper * > consumers_
Definition: util.h:33
Edge class in DAG graph for connecting nodes and transferring data.
Definition: edge.h:35
Node description class.
Definition: node.h:35
std::vector< std::string > getInputs() const
Get input edge name list.
Definition: node.h:107
std::string getName() const
Get node name.
Definition: node.h:101
std::vector< std::string > getOutputs() const
Get output edge name list.
Definition: node.h:113
std::string name_
Definition: util.h:21
Node base class.
Definition: node.h:171
base::Status setCompositeNode(CompositeNode *composite_node)
Set parent composite node.
#define NNDEPLOY_LOGE(fmt,...)
Definition: log.h:59
#define NNDEPLOY_CC_API
api
Definition: macro.h:29
EdgeWrapper * findEdgeWrapper(std::vector< EdgeWrapper * > &edge_repository, const std::string &edge_name)
Node * createNode(const std::string &node_key, const std::string &node_name)
Create node.