nndeploy C++ API  0.2.0
nndeploy C++ API
graph.h
Go to the documentation of this file.
1 
2 #ifndef _NNDEPLOY_DAG_GRAPH_H_
3 #define _NNDEPLOY_DAG_GRAPH_H_
4 
5 #include "nndeploy/base/any.h"
6 #include "nndeploy/base/common.h"
8 #include "nndeploy/base/log.h"
9 #include "nndeploy/base/macro.h"
10 #include "nndeploy/base/object.h"
11 #include "nndeploy/base/status.h"
12 #include "nndeploy/base/string.h"
13 #include "nndeploy/dag/edge.h"
14 #include "nndeploy/dag/executor.h"
15 #include "nndeploy/dag/node.h"
16 #include "nndeploy/dag/util.h"
17 #include "nndeploy/device/buffer.h"
18 #include "nndeploy/device/device.h"
20 #include "nndeploy/device/tensor.h"
22 
23 namespace nndeploy {
24 namespace dag {
25 
31 class NNDEPLOY_CC_API Graph : public Node {
32  public:
37  Graph(const std::string &name);
38 
45  Graph(const std::string &name, std::vector<Edge *> inputs,
46  std::vector<Edge *> outputs);
47 
51  virtual ~Graph();
52 
58  base::Status addImageUrl(const std::string &url);
59 
65  base::Status removeImageUrl(const std::string &url);
66 
72  base::Status addVideoUrl(const std::string &url);
73 
79  base::Status removeVideoUrl(const std::string &url);
80 
86  base::Status addAudioUrl(const std::string &url);
87 
93  base::Status removeAudioUrl(const std::string &url);
94 
100  base::Status addModelUrl(const std::string &url);
101 
107  base::Status removeModelUrl(const std::string &url);
108 
114  base::Status addOtherUrl(const std::string &url);
115 
121  base::Status removeOtherUrl(const std::string &url);
122 
127  std::vector<std::string> getImageUrl() const;
128 
133  std::vector<std::string> getVideoUrl() const;
134 
139  std::vector<std::string> getAudioUrl() const;
140 
145  std::vector<std::string> getModelUrl() const;
146 
151  std::vector<std::string> getOtherUrl() const;
152 
158  base::Status setEdgeQueueMaxSize(int queue_max_size);
159 
165 
173  int drop_count = 1);
174 
180 
186 
193  virtual base::Status setInput(Edge *input, int index = -1);
194 
201  virtual base::Status setOutput(Edge *output, int index = -1);
202 
208  virtual base::Status setInputs(std::vector<Edge *> inputs);
209 
215  virtual base::Status setOutputs(std::vector<Edge *> outputs);
216 
223  virtual base::Status setInputSharedPtr(std::shared_ptr<Edge> input,
224  int index = -1);
225 
232  virtual base::Status setOutputSharedPtr(std::shared_ptr<Edge> output,
233  int index = -1);
234 
241  std::vector<std::shared_ptr<Edge>> inputs);
242 
249  std::vector<std::shared_ptr<Edge>> outputs);
250 
251  // Edge creation related methods
257  Edge *createEdge(const std::string &name);
258 
264  std::shared_ptr<Edge> createEdgeSharedPtr(const std::string &name);
265 
266  // Edge addition related methods
273  EdgeWrapper *addEdge(Edge *edge, bool is_external = true);
274 
280  EdgeWrapper *addEdgeSharedPtr(std::shared_ptr<Edge> edge);
281 
282  // Edge deletion related methods
289 
290  // Edge retrieval related methods
296  Edge *getEdge(const std::string &name);
297 
303  std::shared_ptr<Edge> getEdgeSharedPtr(const std::string &name);
304 
305  // Edge update related methods
313  base::Status updteEdge(EdgeWrapper *edge_wrapper, Edge *edge,
314  bool is_external = true);
315 
316  // Node creation related methods
323  Node *createNode(const std::string &key, const std::string &name = "");
324 
330  Node *createNode(const NodeDesc &desc);
331 
340  template <typename T, typename... Args,
341  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
342  Node *createNode(const std::string &name = "", Args &...args);
343 
352  template <typename T, typename... Args,
353  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
354  Node *createNode(const NodeDesc &desc, Args &...args);
355 
362  base::Status setNodeDesc(Node *node, const NodeDesc &desc);
363 
364  // Node addition related methods
371  base::Status addNode(Node *node, bool is_external = true);
372 
378  base::Status addNodeSharedPtr(std::shared_ptr<Node> node);
379 
380  // Node deletion related methods
387 
388  // Node retrieval related methods
394  Node *getNode(const std::string &name);
395 
401  Node *getNode(int index);
402 
408  std::shared_ptr<Node> getNodeSharedPtr(const std::string &name);
409 
415  Node *getNodeByKey(const std::string &key);
416 
422  std::vector<Node *> getNodesByKey(const std::string &key);
423 
429 
434  std::vector<Node *> getNodes();
435 
440  std::vector<Node *> getNodesRecursive();
441 
446  std::vector<std::string> getNodesName();
447 
452  std::vector<std::string> getNodesNameRecursive();
453 
459  Node *getInputNode(int index);
460 
466  Node *getOutputNode(int index);
467 
473  Node *getInferNode(int index);
474 
475  // Node connection related methods
484  base::Status connect(Node *predecessor, Node *successor,
485  int predecessor_port = 0, int successor_port = 0);
486 
495  base::Status disconnect(Node *predecessor, Node *successor,
496  int predecessor_port = 0, int successor_port = 0);
497 
498  // Node run status related methods
503  std::map<std::string, std::shared_ptr<RunStatus>> getNodesRunStatus();
504 
509  std::map<std::string, std::shared_ptr<RunStatus>>
511 
512  // Node parameter setting related methods
519  base::Status setNodeParam(const std::string &node_name, base::Param *param);
520 
526  base::Param *getNodeParam(const std::string &node_name);
527 
534  base::Status setNodeParamSharedPtr(const std::string &node_name,
535  std::shared_ptr<base::Param> param);
536 
542  std::shared_ptr<base::Param> getNodeParamSharedPtr(
543  const std::string &node_name);
544 
551  base::Status setExternalParam(const std::string &key,
552  std::shared_ptr<base::Param> param);
553 
559  std::shared_ptr<base::Param> getExternalParam(const std::string &key);
560 
567  base::Status setNodeParallelType(const std::string &node_name,
568  base::ParallelType parallel_type);
569 
570  // Graph node shared stream related methods
575  void setGraphNodeShareStream(bool flag);
576 
582 
583  // Graph loop count related methods
588  virtual void setLoopMaxFlag(bool is_loop_max_flag);
589 
594  virtual bool getLoopMaxFlag();
595 
600  virtual void setLoopCount(int loop_count);
601 
606  virtual int getLoopCount();
607 
612  virtual std::map<std::string, int> getLoopCountMap();
613 
614  // Node IO update related methods
622  base::Status updateNodeIO(Node *node, std::vector<Edge *> inputs,
623  std::vector<Edge *> outputs);
624 
630  base::Status markInputEdge(std::vector<Edge *> inputs);
631 
637  base::Status markOutputEdge(std::vector<Edge *> outputs);
638 
644 
649  virtual base::Status init();
650 
655  virtual base::Status deinit();
656 
661  virtual base::Status run();
662 
667  virtual bool synchronize();
668 
673  virtual bool interrupt();
674 
675  // Forward propagation related methods
676  // These methods must be implemented by subclasses
677  // Subclasses should override these methods to define their own operator() implementation
683  virtual std::vector<Edge *> forward(std::vector<Edge *> inputs);
684 
690  virtual std::vector<Edge *> operator()(std::vector<Edge *> inputs);
691 
696  virtual std::vector<Edge *> forward();
697 
702  virtual std::vector<Edge *> operator()();
703 
709  virtual std::vector<Edge *> forward(Edge *input);
710 
716  virtual std::vector<Edge *> operator()(Edge *input);
717 
723  base::Status dump(std::ostream &oss = std::cout);
724 
729  virtual void setTraceFlag(bool flag);
730 
736  std::vector<Edge *> trace(std::vector<Edge *> inputs);
737 
742  std::vector<Edge *> trace();
743 
749  std::vector<Edge *> trace(Edge *input);
750 
756 
762 
763  // Global resource related methods
770  virtual base::Status addResourceWithoutState(const std::string &key,
771  const base::Any &value);
772 
778  virtual base::Any &getResourceWithoutState(const std::string &key);
779 
786  virtual base::Status addResourceWithState(const std::string &key, Edge *edge);
787 
793  virtual Edge *getResourceWithState(const std::string &key);
794 
795  // Helper functions
804  std::vector<Edge *> inputs,
805  std::vector<Edge *> outputs);
806 
813 
819  EdgeWrapper *getEdgeWrapper(const std::string &name);
820 
827 
833  NodeWrapper *getNodeWrapper(const std::string &name);
834 
835  // JSON serialization related methods
836  // using Node::serialize;
843  virtual base::Status serialize(rapidjson::Value &json,
844  rapidjson::Document::AllocatorType &allocator);
845 
850  virtual std::string serialize();
851 
852  // using Node::deserialize;
858  virtual base::Status deserialize(rapidjson::Value &json);
859 
865  virtual base::Status deserialize(const std::string &json_str);
866 
871  virtual void setUnusedNodeNames(const std::string &node_name);
872 
877  virtual void setUnusedNodeNames(const std::set<std::string> &node_names);
878 
883  virtual void removeUnusedNodeNames(const std::string &node_name);
884 
889  virtual void removeUnusedNodeNames(const std::set<std::string> &node_names);
890 
895  virtual std::set<std::string> getUnusedNodeNames();
896 
900  virtual void removeInOutNode();
901 
902  // Node value related methods
903  // node_name:key:value
908  virtual void setNodeValue(const std::string &node_value_str);
909 
916  virtual void setNodeValue(const std::string &node_name,
917  const std::string &key, const std::string &value);
918 
923  virtual void setNodeValue(
924  std::map<std::string, std::map<std::string, std::string>> node_value_map);
925 
930  virtual std::map<std::string, std::map<std::string, std::string>>
932 
933  // Create node (deprecated API)
944  template <typename T, typename... Args,
945  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
946  Node *createNode(const std::string &name, Edge *input, Edge *output,
947  Args &...args);
948 
959  template <typename T, typename... Args,
960  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
961  Node *createNode(const std::string &name, const std::string &input_name,
962  const std::string &output_name, Args &...args);
963 
974  template <typename T, typename... Args,
975  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
976  Node *createNode(const std::string &name, Edge *input,
977  const std::string &output_name, Args &...args);
978 
989  template <typename T, typename... Args,
990  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
991  Node *createNode(const std::string &name, const std::string &input_name,
992  Edge *output, Args &...args);
993 
1004  template <typename T, typename... Args,
1005  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1006  Node *createNode(const std::string &name, std::vector<Edge *> inputs,
1007  std::vector<Edge *> outputs, Args &...args);
1008 
1019  template <typename T, typename... Args,
1020  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1021  Node *createNode(const std::string &name,
1022  std::vector<std::string> input_names,
1023  std::vector<std::string> output_names, Args &...args);
1024 
1035  template <typename T, typename... Args,
1036  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1037  Node *createNode(const std::string &name,
1038  std::vector<std::string> input_names,
1039  std::vector<Edge *> outputs, Args &...args);
1040 
1051  template <typename T, typename... Args,
1052  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1053  Node *createNode(const std::string &name, std::vector<Edge *> inputs,
1054  std::vector<std::string> output_names, Args &...args);
1055 
1066  template <typename T, typename... Args,
1067  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1068  Node *createNode(const std::string &name,
1069  std::initializer_list<Edge *> inputs,
1070  std::initializer_list<Edge *> outputs, Args &...args);
1071 
1082  template <typename T, typename... Args,
1083  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1084  Node *createNode(const std::string &name,
1085  std::initializer_list<std::string> input_names,
1086  std::initializer_list<std::string> output_names,
1087  Args &...args);
1088 
1099  template <typename T, typename... Args,
1100  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1101  Node *createNode(const std::string &name,
1102  std::initializer_list<Edge *> inputs,
1103  std::initializer_list<std::string> output_names,
1104  Args &...args);
1105 
1116  template <typename T, typename... Args,
1117  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1118  Node *createNode(const std::string &name,
1119  std::initializer_list<std::string> input_names,
1120  std::initializer_list<Edge *> outputs, Args &...args);
1121 
1132  template <typename T, typename... Args,
1133  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1134  Node *createInfer(const std::string &name, base::InferenceType type,
1135  Edge *input, Edge *output);
1136 
1147  template <typename T, typename... Args,
1148  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1149  Node *createInfer(const std::string &name, base::InferenceType type,
1150  const std::string &input_name,
1151  const std::string &output_name);
1152 
1163  template <typename T, typename... Args,
1164  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1165  Node *createInfer(const std::string &name, base::InferenceType type,
1166  Edge *input, const std::string &output_name);
1167 
1178  template <typename T, typename... Args,
1179  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1180  Node *createInfer(const std::string &name, base::InferenceType type,
1181  const std::string &input_name, Edge *output);
1182 
1193  template <typename T, typename... Args,
1194  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1195  Node *createInfer(const std::string &name, base::InferenceType type,
1196  std::vector<Edge *> inputs, std::vector<Edge *> outputs);
1197 
1208  template <typename T, typename... Args,
1209  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1210  Node *createInfer(const std::string &name, base::InferenceType type,
1211  std::vector<std::string> input_names,
1212  std::vector<std::string> output_names);
1213 
1224  template <typename T, typename... Args,
1225  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1226  Node *createInfer(const std::string &name, base::InferenceType type,
1227  std::vector<Edge *> inputs,
1228  std::vector<std::string> output_names);
1229 
1240  template <typename T, typename... Args,
1241  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1242  Node *createInfer(const std::string &name, base::InferenceType type,
1243  std::vector<std::string> input_names,
1244  std::vector<Edge *> outputs);
1245 
1256  template <typename T, typename... Args,
1257  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1258  Node *createInfer(const std::string &name, base::InferenceType type,
1259  std::initializer_list<Edge *> inputs,
1260  std::initializer_list<Edge *> outputs);
1261 
1272  template <typename T, typename... Args,
1273  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1274  Node *createInfer(const std::string &name, base::InferenceType type,
1275  std::initializer_list<std::string> input_names,
1276  std::initializer_list<std::string> output_names);
1277 
1288  template <typename T, typename... Args,
1289  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1290  Node *createInfer(const std::string &name, base::InferenceType type,
1291  std::initializer_list<Edge *> inputs,
1292  std::initializer_list<std::string> output_names);
1293 
1304  template <typename T, typename... Args,
1305  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1306  Node *createInfer(const std::string &name, base::InferenceType type,
1307  std::initializer_list<std::string> input_names,
1308  std::initializer_list<Edge *> outputs);
1309 
1318  template <typename T, typename... Args,
1319  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
1320  Node *createInfer(const NodeDesc &desc, base::InferenceType type);
1321 
1328  Node *createNode4Py(const std::string &key, const std::string &name = "");
1329 
1335  Node *createNode4Py(const NodeDesc &desc);
1336 
1337  protected:
1343 
1349 
1355 
1356  protected:
1357  // URL storage related member variables
1358  std::vector<std::string> image_url_;
1359  std::vector<std::string> video_url_;
1360  std::vector<std::string> audio_url_;
1361  std::vector<std::string> model_url_;
1362  std::vector<std::string> other_url_;
1363 
1364  bool is_graph_node_share_stream_ = true;
1365  std::vector<EdgeWrapper *> edge_repository_;
1366  std::vector<NodeWrapper *> node_repository_;
1367  std::vector<NodeWrapper *> run_node_repository_;
1368  std::vector<std::shared_ptr<Edge>> shared_edge_repository_;
1369  std::vector<std::shared_ptr<Node>> shared_node_repository_;
1370  std::set<std::string> used_node_names_;
1371  std::set<std::string> used_edge_names_;
1372  std::shared_ptr<Executor> executor_;
1373  int queue_max_size_ = 16;
1374  base::QueueOverflowPolicy queue_overflow_policy_ =
1376  int queue_drop_count_ = 1;
1377  std::map<std::string, std::shared_ptr<base::Param>>
1379  bool is_loop_max_flag_ = true;
1380  bool is_forward_api_ok_ = true;
1381 
1382  bool is_remove_in_out_node_ = false;
1383  std::set<std::string> unused_node_names_;
1384  /*
1385  * @brief Node values
1386  * @details
1387  * Used to store node values
1388  * Format: {node_name: {key: value}}
1389  * Note: node_name is the node name
1390  * Note: key is the key of the node value
1391  * Note: value is the value of the node value
1392  */
1393  std::map<std::string, std::map<std::string, std::string>> node_value_map_;
1400  std::map<std::string, base::Any> resource_without_state_;
1407  std::map<std::string, Edge *> resource_with_state_;
1408 };
1409 
1418 template <typename T, typename... Args,
1419  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1420 Node *Graph::createNode(const std::string &name, Args &...args) {
1421  if (used_node_names_.find(name) != used_node_names_.end()) {
1422  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1423  return nullptr;
1424  }
1425  std::vector<Edge *> inputs;
1426  std::vector<Edge *> outputs;
1427  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1428  NodeWrapper *node_wrapper = new NodeWrapper();
1429  node_wrapper->is_external_ = false;
1430  node_wrapper->node_ = node;
1431  node_wrapper->name_ = name;
1432  node_repository_.emplace_back(node_wrapper);
1433  used_node_names_.insert(name);
1434  node->setGraph(this);
1435  return node;
1436 }
1437 
1441 template <typename T, typename... Args,
1442  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1443 Node *Graph::createNode(const std::string &name, Edge *input, Edge *output,
1444  Args &...args) {
1445  if (used_node_names_.find(name) != used_node_names_.end()) {
1446  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1447  return nullptr;
1448  }
1449  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, args...));
1450  NodeWrapper *node_wrapper = new NodeWrapper();
1451  node_wrapper->is_external_ = false;
1452  node_wrapper->node_ = node;
1453  node_wrapper->name_ = name;
1454  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1455  if (input_wrapper == nullptr) {
1456  input_wrapper = this->addEdge(input);
1457  }
1458  input_wrapper->consumers_.emplace_back(node_wrapper);
1459  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1460  if (output_wrapper == nullptr) {
1461  output_wrapper = this->addEdge(output);
1462  }
1463  output_wrapper->producers_.emplace_back(node_wrapper);
1464 
1465  node_repository_.emplace_back(node_wrapper);
1466  used_node_names_.insert(name);
1467  node->setGraph(this);
1468  ;
1469  return node;
1470 }
1471 
1475 template <typename T, typename... Args,
1476  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1477 Node *Graph::createNode(const std::string &name, const std::string &input_name,
1478  const std::string &output_name, Args &...args) {
1479  if (used_node_names_.find(name) != used_node_names_.end()) {
1480  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1481  return nullptr;
1482  }
1483  Edge *input = getEdge(input_name);
1484  if (input == nullptr) {
1485  input = createEdge(input_name);
1486  }
1487  Edge *output = getEdge(output_name);
1488  if (output == nullptr) {
1489  output = createEdge(output_name);
1490  }
1491  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, args...));
1492  NodeWrapper *node_wrapper = new NodeWrapper();
1493  node_wrapper->is_external_ = false;
1494  node_wrapper->node_ = node;
1495  node_wrapper->name_ = name;
1496  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1497  if (input_wrapper == nullptr) {
1498  input_wrapper = this->addEdge(input);
1499  }
1500  input_wrapper->consumers_.emplace_back(node_wrapper);
1501  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1502  if (output_wrapper == nullptr) {
1503  output_wrapper = this->addEdge(output);
1504  }
1505  output_wrapper->producers_.emplace_back(node_wrapper);
1506 
1507  node_repository_.emplace_back(node_wrapper);
1508  used_node_names_.insert(name);
1509  node->setGraph(this);
1510  return node;
1511 }
1512 
1516 template <typename T, typename... Args,
1517  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1518 Node *Graph::createNode(const std::string &name, Edge *input,
1519  const std::string &output_name, Args &...args) {
1520  if (used_node_names_.find(name) != used_node_names_.end()) {
1521  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1522  return nullptr;
1523  }
1524  Edge *output = getEdge(output_name);
1525  if (output == nullptr) {
1526  output = createEdge(output_name);
1527  }
1528  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, args...));
1529  NodeWrapper *node_wrapper = new NodeWrapper();
1530  node_wrapper->is_external_ = false;
1531  node_wrapper->node_ = node;
1532  node_wrapper->name_ = name;
1533  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1534  if (input_wrapper == nullptr) {
1535  input_wrapper = this->addEdge(input);
1536  }
1537  input_wrapper->consumers_.emplace_back(node_wrapper);
1538  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1539  if (output_wrapper == nullptr) {
1540  output_wrapper = this->addEdge(output);
1541  }
1542  output_wrapper->producers_.emplace_back(node_wrapper);
1543 
1544  node_repository_.emplace_back(node_wrapper);
1545  used_node_names_.insert(name);
1546  node->setGraph(this);
1547  ;
1548  return node;
1549 }
1550 
1554 template <typename T, typename... Args,
1555  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1556 Node *Graph::createNode(const std::string &name, const std::string &input_name,
1557  Edge *output, Args &...args) {
1558  if (used_node_names_.find(name) != used_node_names_.end()) {
1559  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1560  return nullptr;
1561  }
1562  Edge *input = getEdge(input_name);
1563  if (input == nullptr) {
1564  input = createEdge(input_name);
1565  }
1566  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, args...));
1567  NodeWrapper *node_wrapper = new NodeWrapper();
1568  node_wrapper->is_external_ = false;
1569  node_wrapper->node_ = node;
1570  node_wrapper->name_ = name;
1571  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1572  if (input_wrapper == nullptr) {
1573  input_wrapper = this->addEdge(input);
1574  }
1575  input_wrapper->consumers_.emplace_back(node_wrapper);
1576  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1577  if (output_wrapper == nullptr) {
1578  output_wrapper = this->addEdge(output);
1579  }
1580  output_wrapper->producers_.emplace_back(node_wrapper);
1581 
1582  node_repository_.emplace_back(node_wrapper);
1583  used_node_names_.insert(name);
1584  node->setGraph(this);
1585  ;
1586  return node;
1587 }
1588 
1592 template <typename T, typename... Args,
1593  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1594 Node *Graph::createNode(const std::string &name, std::vector<Edge *> inputs,
1595  std::vector<Edge *> outputs, Args &...args) {
1596  if (used_node_names_.find(name) != used_node_names_.end()) {
1597  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1598  return nullptr;
1599  }
1600  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1601  NodeWrapper *node_wrapper = new NodeWrapper();
1602  node_wrapper->is_external_ = false;
1603  node_wrapper->node_ = node;
1604  node_wrapper->name_ = name;
1605  for (auto input : inputs) {
1606  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1607  if (input_wrapper == nullptr) {
1608  input_wrapper = this->addEdge(input);
1609  }
1610  input_wrapper->consumers_.emplace_back(node_wrapper);
1611  }
1612  for (auto output : outputs) {
1613  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1614  if (output_wrapper == nullptr) {
1615  output_wrapper = this->addEdge(output);
1616  }
1617  output_wrapper->producers_.emplace_back(node_wrapper);
1618  }
1619 
1620  node_repository_.emplace_back(node_wrapper);
1621  used_node_names_.insert(name);
1622  node->setGraph(this);
1623  ;
1624  return node;
1625 }
1626 
1630 template <typename T, typename... Args,
1631  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1632 Node *Graph::createNode(const std::string &name,
1633  std::vector<std::string> input_names,
1634  std::vector<std::string> output_names, Args &...args) {
1635  if (used_node_names_.find(name) != used_node_names_.end()) {
1636  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1637  return nullptr;
1638  }
1639  std::vector<Edge *> inputs;
1640  for (auto input_name : input_names) {
1641  Edge *input = getEdge(input_name);
1642  if (input == nullptr) {
1643  input = createEdge(input_name);
1644  }
1645  inputs.emplace_back(input);
1646  }
1647  std::vector<Edge *> outputs;
1648  for (auto output_name : output_names) {
1649  Edge *output = getEdge(output_name);
1650  if (output == nullptr) {
1651  output = createEdge(output_name);
1652  }
1653  outputs.emplace_back(output);
1654  }
1655  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1656  NodeWrapper *node_wrapper = new NodeWrapper();
1657  node_wrapper->is_external_ = false;
1658  node_wrapper->node_ = node;
1659  node_wrapper->name_ = name;
1660  for (auto input : inputs) {
1661  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1662  if (input_wrapper == nullptr) {
1663  input_wrapper = this->addEdge(input);
1664  }
1665  input_wrapper->consumers_.emplace_back(node_wrapper);
1666  }
1667  for (auto output : outputs) {
1668  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1669  if (output_wrapper == nullptr) {
1670  output_wrapper = this->addEdge(output);
1671  }
1672  output_wrapper->producers_.emplace_back(node_wrapper);
1673  }
1674 
1675  node_repository_.emplace_back(node_wrapper);
1676  used_node_names_.insert(name);
1677  node->setGraph(this);
1678  return node;
1679 }
1680 
1684 template <typename T, typename... Args,
1685  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1686 Node *Graph::createNode(const std::string &name,
1687  std::vector<std::string> input_names,
1688  std::vector<Edge *> outputs, Args &...args) {
1689  if (used_node_names_.find(name) != used_node_names_.end()) {
1690  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1691  return nullptr;
1692  }
1693  std::vector<Edge *> inputs;
1694  for (auto input_name : input_names) {
1695  Edge *input = getEdge(input_name);
1696  if (input == nullptr) {
1697  input = createEdge(input_name);
1698  }
1699  inputs.emplace_back(input);
1700  }
1701  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1702  NodeWrapper *node_wrapper = new NodeWrapper();
1703  node_wrapper->is_external_ = false;
1704  node_wrapper->node_ = node;
1705  node_wrapper->name_ = name;
1706  for (auto input : inputs) {
1707  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1708  if (input_wrapper == nullptr) {
1709  input_wrapper = this->addEdge(input);
1710  }
1711  input_wrapper->consumers_.emplace_back(node_wrapper);
1712  }
1713  for (auto output : outputs) {
1714  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1715  if (output_wrapper == nullptr) {
1716  output_wrapper = this->addEdge(output);
1717  }
1718  output_wrapper->producers_.emplace_back(node_wrapper);
1719  }
1720 
1721  node_repository_.emplace_back(node_wrapper);
1722  used_node_names_.insert(name);
1723  node->setGraph(this);
1724  return node;
1725 }
1726 
1730 template <typename T, typename... Args,
1731  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1732 Node *Graph::createNode(const std::string &name, std::vector<Edge *> inputs,
1733  std::vector<std::string> output_names, Args &...args) {
1734  if (used_node_names_.find(name) != used_node_names_.end()) {
1735  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1736  return nullptr;
1737  }
1738  std::vector<Edge *> outputs;
1739  for (auto output_name : output_names) {
1740  Edge *output = getEdge(output_name);
1741  if (output == nullptr) {
1742  output = createEdge(output_name);
1743  }
1744  outputs.emplace_back(output);
1745  }
1746  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1747  NodeWrapper *node_wrapper = new NodeWrapper();
1748  node_wrapper->is_external_ = false;
1749  node_wrapper->node_ = node;
1750  node_wrapper->name_ = name;
1751  for (auto input : inputs) {
1752  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1753  if (input_wrapper == nullptr) {
1754  input_wrapper = this->addEdge(input);
1755  }
1756  input_wrapper->consumers_.emplace_back(node_wrapper);
1757  }
1758  for (auto output : outputs) {
1759  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1760  if (output_wrapper == nullptr) {
1761  output_wrapper = this->addEdge(output);
1762  }
1763  output_wrapper->producers_.emplace_back(node_wrapper);
1764  }
1765 
1766  node_repository_.emplace_back(node_wrapper);
1767  used_node_names_.insert(name);
1768  node->setGraph(this);
1769  ;
1770  return node;
1771 }
1772 
1776 template <typename T, typename... Args,
1777  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1778 Node *Graph::createNode(const std::string &name,
1779  std::initializer_list<Edge *> inputs,
1780  std::initializer_list<Edge *> outputs, Args &...args) {
1781  if (used_node_names_.find(name) != used_node_names_.end()) {
1782  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1783  return nullptr;
1784  }
1785  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1786  NodeWrapper *node_wrapper = new NodeWrapper();
1787  node_wrapper->is_external_ = false;
1788  node_wrapper->node_ = node;
1789  node_wrapper->name_ = name;
1790  for (auto input : inputs) {
1791  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1792  if (input_wrapper == nullptr) {
1793  input_wrapper = this->addEdge(input);
1794  }
1795  input_wrapper->consumers_.emplace_back(node_wrapper);
1796  }
1797  for (auto output : outputs) {
1798  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1799  if (output_wrapper == nullptr) {
1800  output_wrapper = this->addEdge(output);
1801  }
1802  output_wrapper->producers_.emplace_back(node_wrapper);
1803  }
1804 
1805  node_repository_.emplace_back(node_wrapper);
1806  used_node_names_.insert(name);
1807  node->setGraph(this);
1808  return node;
1809 }
1810 
1814 template <typename T, typename... Args,
1815  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1816 Node *Graph::createNode(const std::string &name,
1817  std::initializer_list<std::string> input_names,
1818  std::initializer_list<std::string> output_names,
1819  Args &...args) {
1820  if (used_node_names_.find(name) != used_node_names_.end()) {
1821  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1822  return nullptr;
1823  }
1824  std::vector<Edge *> inputs;
1825  for (auto input_name : input_names) {
1826  Edge *input = getEdge(input_name);
1827  if (input == nullptr) {
1828  input = createEdge(input_name);
1829  }
1830  inputs.emplace_back(input);
1831  }
1832  std::vector<Edge *> outputs;
1833  for (auto output_name : output_names) {
1834  Edge *output = getEdge(output_name);
1835  if (output == nullptr) {
1836  output = createEdge(output_name);
1837  }
1838  outputs.emplace_back(output);
1839  }
1840  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1841  NodeWrapper *node_wrapper = new NodeWrapper();
1842  node_wrapper->is_external_ = false;
1843  node_wrapper->node_ = node;
1844  node_wrapper->name_ = name;
1845  for (auto input : inputs) {
1846  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1847  if (input_wrapper == nullptr) {
1848  input_wrapper = this->addEdge(input);
1849  }
1850  input_wrapper->consumers_.emplace_back(node_wrapper);
1851  }
1852  for (auto output : outputs) {
1853  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1854  if (output_wrapper == nullptr) {
1855  output_wrapper = this->addEdge(output);
1856  }
1857  output_wrapper->producers_.emplace_back(node_wrapper);
1858  }
1859 
1860  node_repository_.emplace_back(node_wrapper);
1861  used_node_names_.insert(name);
1862  node->setGraph(this);
1863  ;
1864  return node;
1865 }
1866 
1870 template <typename T, typename... Args,
1871  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1872 Node *Graph::createNode(const std::string &name,
1873  std::initializer_list<Edge *> inputs,
1874  std::initializer_list<std::string> output_names,
1875  Args &...args) {
1876  if (used_node_names_.find(name) != used_node_names_.end()) {
1877  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1878  return nullptr;
1879  }
1880  std::vector<Edge *> outputs;
1881  for (auto output_name : output_names) {
1882  Edge *output = getEdge(output_name);
1883  if (output == nullptr) {
1884  output = createEdge(output_name);
1885  }
1886  outputs.emplace_back(output);
1887  }
1888  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1889  NodeWrapper *node_wrapper = new NodeWrapper();
1890  node_wrapper->is_external_ = false;
1891  node_wrapper->node_ = node;
1892  node_wrapper->name_ = name;
1893  for (auto input : inputs) {
1894  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1895  if (input_wrapper == nullptr) {
1896  input_wrapper = this->addEdge(input);
1897  }
1898  input_wrapper->consumers_.emplace_back(node_wrapper);
1899  }
1900  for (auto output : outputs) {
1901  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1902  if (output_wrapper == nullptr) {
1903  output_wrapper = this->addEdge(output);
1904  }
1905  output_wrapper->producers_.emplace_back(node_wrapper);
1906  }
1907 
1908  node_repository_.emplace_back(node_wrapper);
1909  used_node_names_.insert(name);
1910  node->setGraph(this);
1911  ;
1912  return node;
1913 }
1914 
1918 template <typename T, typename... Args,
1919  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1920 Node *Graph::createNode(const std::string &name,
1921  std::initializer_list<std::string> input_names,
1922  std::initializer_list<Edge *> outputs, Args &...args) {
1923  if (used_node_names_.find(name) != used_node_names_.end()) {
1924  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1925  return nullptr;
1926  }
1927  std::vector<Edge *> inputs;
1928  for (auto input_name : input_names) {
1929  Edge *input = getEdge(input_name);
1930  if (input == nullptr) {
1931  input = createEdge(input_name);
1932  }
1933  inputs.emplace_back(input);
1934  }
1935  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, args...));
1936  NodeWrapper *node_wrapper = new NodeWrapper();
1937  node_wrapper->is_external_ = false;
1938  node_wrapper->node_ = node;
1939  node_wrapper->name_ = name;
1940  for (auto input : inputs) {
1941  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1942  if (input_wrapper == nullptr) {
1943  input_wrapper = this->addEdge(input);
1944  }
1945  input_wrapper->consumers_.emplace_back(node_wrapper);
1946  }
1947  for (auto output : outputs) {
1948  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1949  if (output_wrapper == nullptr) {
1950  output_wrapper = this->addEdge(output);
1951  }
1952  output_wrapper->producers_.emplace_back(node_wrapper);
1953  }
1954 
1955  node_repository_.emplace_back(node_wrapper);
1956  used_node_names_.insert(name);
1957  node->setGraph(this);
1958  ;
1959  return node;
1960 }
1961 
1965 template <typename T, typename... Args,
1966  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
1967 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
1968  Edge *input, Edge *output) {
1969  if (used_node_names_.find(name) != used_node_names_.end()) {
1970  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
1971  return nullptr;
1972  }
1973  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, type));
1974  NodeWrapper *node_wrapper = new NodeWrapper();
1975  node_wrapper->is_external_ = false;
1976  node_wrapper->node_ = node;
1977  node_wrapper->name_ = name;
1978  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
1979  if (input_wrapper == nullptr) {
1980  input_wrapper = this->addEdge(input);
1981  }
1982  input_wrapper->consumers_.emplace_back(node_wrapper);
1983  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
1984  if (output_wrapper == nullptr) {
1985  output_wrapper = this->addEdge(output);
1986  }
1987  output_wrapper->producers_.emplace_back(node_wrapper);
1988 
1989  node_repository_.emplace_back(node_wrapper);
1990  used_node_names_.insert(name);
1991  node->setGraph(this);
1992  ;
1993  return node;
1994 }
1995 
1999 template <typename T, typename... Args,
2000  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2001 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2002  const std::string &input_name,
2003  const std::string &output_name) {
2004  if (used_node_names_.find(name) != used_node_names_.end()) {
2005  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2006  return nullptr;
2007  }
2008  Edge *input = getEdge(input_name);
2009  if (input == nullptr) {
2010  input = createEdge(input_name);
2011  }
2012  Edge *output = getEdge(output_name);
2013  if (output == nullptr) {
2014  output = createEdge(output_name);
2015  }
2016  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, type));
2017  NodeWrapper *node_wrapper = new NodeWrapper();
2018  node_wrapper->is_external_ = false;
2019  node_wrapper->node_ = node;
2020  node_wrapper->name_ = name;
2021  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2022  if (input_wrapper == nullptr) {
2023  input_wrapper = this->addEdge(input);
2024  }
2025  input_wrapper->consumers_.emplace_back(node_wrapper);
2026  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2027  if (output_wrapper == nullptr) {
2028  output_wrapper = this->addEdge(output);
2029  }
2030  output_wrapper->producers_.emplace_back(node_wrapper);
2031 
2032  node_repository_.emplace_back(node_wrapper);
2033  used_node_names_.insert(name);
2034  node->setGraph(this);
2035  ;
2036  return node;
2037 }
2038 
2042 template <typename T, typename... Args,
2043  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2044 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2045  Edge *input, const std::string &output_name) {
2046  if (used_node_names_.find(name) != used_node_names_.end()) {
2047  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2048  return nullptr;
2049  }
2050  Edge *output = getEdge(output_name);
2051  if (output == nullptr) {
2052  output = createEdge(output_name);
2053  }
2054  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, type));
2055  NodeWrapper *node_wrapper = new NodeWrapper();
2056  node_wrapper->is_external_ = false;
2057  node_wrapper->node_ = node;
2058  node_wrapper->name_ = name;
2059  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2060  if (input_wrapper == nullptr) {
2061  input_wrapper = this->addEdge(input);
2062  }
2063  input_wrapper->consumers_.emplace_back(node_wrapper);
2064  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2065  if (output_wrapper == nullptr) {
2066  output_wrapper = this->addEdge(output);
2067  }
2068  output_wrapper->producers_.emplace_back(node_wrapper);
2069 
2070  node_repository_.emplace_back(node_wrapper);
2071  used_node_names_.insert(name);
2072  node->setGraph(this);
2073  ;
2074  return node;
2075 }
2076 
2080 template <typename T, typename... Args,
2081  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2082 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2083  const std::string &input_name, Edge *output) {
2084  if (used_node_names_.find(name) != used_node_names_.end()) {
2085  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2086  return nullptr;
2087  }
2088  Edge *input = getEdge(input_name);
2089  if (input == nullptr) {
2090  input = createEdge(input_name);
2091  }
2092  Node *node = dynamic_cast<Node *>(new T(name, {input}, {output}, type));
2093  NodeWrapper *node_wrapper = new NodeWrapper();
2094  node_wrapper->is_external_ = false;
2095  node_wrapper->node_ = node;
2096  node_wrapper->name_ = name;
2097  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2098  if (input_wrapper == nullptr) {
2099  input_wrapper = this->addEdge(input);
2100  }
2101  input_wrapper->consumers_.emplace_back(node_wrapper);
2102  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2103  if (output_wrapper == nullptr) {
2104  output_wrapper = this->addEdge(output);
2105  }
2106  output_wrapper->producers_.emplace_back(node_wrapper);
2107 
2108  node_repository_.emplace_back(node_wrapper);
2109  used_node_names_.insert(name);
2110  node->setGraph(this);
2111  ;
2112  return node;
2113 }
2114 
2115 template <typename T, typename... Args,
2116  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2117 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2118  std::vector<Edge *> inputs,
2119  std::vector<Edge *> outputs) {
2120  if (used_node_names_.find(name) != used_node_names_.end()) {
2121  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2122  return nullptr;
2123  }
2124  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2125  NodeWrapper *node_wrapper = new NodeWrapper();
2126  node_wrapper->is_external_ = false;
2127  node_wrapper->node_ = node;
2128  node_wrapper->name_ = name;
2129  for (auto input : inputs) {
2130  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2131  if (input_wrapper == nullptr) {
2132  input_wrapper = this->addEdge(input);
2133  }
2134  input_wrapper->consumers_.emplace_back(node_wrapper);
2135  }
2136  for (auto output : outputs) {
2137  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2138  if (output_wrapper == nullptr) {
2139  output_wrapper = this->addEdge(output);
2140  }
2141  output_wrapper->producers_.emplace_back(node_wrapper);
2142  }
2143 
2144  node_repository_.emplace_back(node_wrapper);
2145  used_edge_names_.insert(name);
2146  node->setGraph(this);
2147  ;
2148  return node;
2149 }
2150 
2151 template <typename T, typename... Args,
2152  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2153 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2154  std::vector<std::string> input_names,
2155  std::vector<std::string> output_names) {
2156  if (used_node_names_.find(name) != used_node_names_.end()) {
2157  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2158  return nullptr;
2159  }
2160  std::vector<Edge *> inputs;
2161  for (auto input_name : input_names) {
2162  Edge *input = getEdge(input_name);
2163  if (input == nullptr) {
2164  input = createEdge(input_name);
2165  }
2166  inputs.emplace_back(input);
2167  }
2168  std::vector<Edge *> outputs;
2169  for (auto output_name : output_names) {
2170  Edge *output = getEdge(output_name);
2171  if (output == nullptr) {
2172  output = createEdge(output_name);
2173  }
2174  outputs.emplace_back(output);
2175  }
2176  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2177  NodeWrapper *node_wrapper = new NodeWrapper();
2178  node_wrapper->is_external_ = false;
2179  node_wrapper->node_ = node;
2180  node_wrapper->name_ = name;
2181  for (auto input : inputs) {
2182  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2183  if (input_wrapper == nullptr) {
2184  input_wrapper = this->addEdge(input);
2185  }
2186  input_wrapper->consumers_.emplace_back(node_wrapper);
2187  }
2188  for (auto output : outputs) {
2189  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2190  if (output_wrapper == nullptr) {
2191  output_wrapper = this->addEdge(output);
2192  }
2193  output_wrapper->producers_.emplace_back(node_wrapper);
2194  }
2195 
2196  node_repository_.emplace_back(node_wrapper);
2197  used_node_names_.insert(name);
2198  node->setGraph(this);
2199  ;
2200  return node;
2201 }
2202 
2203 template <typename T, typename... Args,
2204  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2205 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2206  std::vector<Edge *> inputs,
2207  std::vector<std::string> output_names) {
2208  if (used_node_names_.find(name) != used_node_names_.end()) {
2209  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2210  return nullptr;
2211  }
2212  std::vector<Edge *> outputs;
2213  for (auto output_name : output_names) {
2214  Edge *output = getEdge(output_name);
2215  if (output == nullptr) {
2216  output = createEdge(output_name);
2217  }
2218  outputs.emplace_back(output);
2219  }
2220  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2221  NodeWrapper *node_wrapper = new NodeWrapper();
2222  node_wrapper->is_external_ = false;
2223  node_wrapper->node_ = node;
2224  node_wrapper->name_ = name;
2225  for (auto input : inputs) {
2226  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2227  if (input_wrapper == nullptr) {
2228  input_wrapper = this->addEdge(input);
2229  }
2230  input_wrapper->consumers_.emplace_back(node_wrapper);
2231  }
2232  for (auto output : outputs) {
2233  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2234  if (output_wrapper == nullptr) {
2235  output_wrapper = this->addEdge(output);
2236  }
2237  output_wrapper->producers_.emplace_back(node_wrapper);
2238  }
2239 
2240  node_repository_.emplace_back(node_wrapper);
2241  used_node_names_.insert(name);
2242  node->setGraph(this);
2243  ;
2244  return node;
2245 }
2246 
2247 template <typename T, typename... Args,
2248  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2249 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2250  std::vector<std::string> input_names,
2251  std::vector<Edge *> outputs) {
2252  if (used_node_names_.find(name) != used_node_names_.end()) {
2253  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2254  return nullptr;
2255  }
2256  std::vector<Edge *> inputs;
2257  for (auto input_name : input_names) {
2258  Edge *input = getEdge(input_name);
2259  if (input == nullptr) {
2260  input = createEdge(input_name);
2261  }
2262  inputs.emplace_back(input);
2263  }
2264  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2265  NodeWrapper *node_wrapper = new NodeWrapper();
2266  node_wrapper->is_external_ = false;
2267  node_wrapper->node_ = node;
2268  node_wrapper->name_ = name;
2269  for (auto input : inputs) {
2270  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2271  if (input_wrapper == nullptr) {
2272  input_wrapper = this->addEdge(input);
2273  }
2274  input_wrapper->consumers_.emplace_back(node_wrapper);
2275  }
2276  for (auto output : outputs) {
2277  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2278  if (output_wrapper == nullptr) {
2279  output_wrapper = this->addEdge(output);
2280  }
2281  output_wrapper->producers_.emplace_back(node_wrapper);
2282  }
2283 
2284  node_repository_.emplace_back(node_wrapper);
2285  used_node_names_.insert(name);
2286  node->setGraph(this);
2287  ;
2288  return node;
2289 }
2290 
2291 template <typename T, typename... Args,
2292  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2293 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2294  std::initializer_list<Edge *> inputs,
2295  std::initializer_list<Edge *> outputs) {
2296  if (used_node_names_.find(name) != used_node_names_.end()) {
2297  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2298  return nullptr;
2299  }
2300  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2301  NodeWrapper *node_wrapper = new NodeWrapper();
2302  node_wrapper->is_external_ = false;
2303  node_wrapper->node_ = node;
2304  node_wrapper->name_ = name;
2305  for (auto input : inputs) {
2306  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2307  if (input_wrapper == nullptr) {
2308  input_wrapper = this->addEdge(input);
2309  }
2310  input_wrapper->consumers_.emplace_back(node_wrapper);
2311  }
2312  for (auto output : outputs) {
2313  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2314  if (output_wrapper == nullptr) {
2315  output_wrapper = this->addEdge(output);
2316  }
2317  output_wrapper->producers_.emplace_back(node_wrapper);
2318  }
2319 
2320  node_repository_.emplace_back(node_wrapper);
2321  used_node_names_.insert(name);
2322  node->setGraph(this);
2323  ;
2324  return node;
2325 }
2326 
2327 template <typename T, typename... Args,
2328  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2329 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2330  std::initializer_list<std::string> input_names,
2331  std::initializer_list<std::string> output_names) {
2332  if (used_node_names_.find(name) != used_node_names_.end()) {
2333  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2334  return nullptr;
2335  }
2336  std::vector<Edge *> inputs;
2337  for (auto input_name : input_names) {
2338  Edge *input = getEdge(input_name);
2339  if (input == nullptr) {
2340  input = createEdge(input_name);
2341  }
2342  inputs.emplace_back(input);
2343  }
2344  std::vector<Edge *> outputs;
2345  for (auto output_name : output_names) {
2346  Edge *output = getEdge(output_name);
2347  if (output == nullptr) {
2348  output = createEdge(output_name);
2349  }
2350  outputs.emplace_back(output);
2351  }
2352  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2353  NodeWrapper *node_wrapper = new NodeWrapper();
2354  node_wrapper->is_external_ = false;
2355  node_wrapper->node_ = node;
2356  node_wrapper->name_ = name;
2357  for (auto input : inputs) {
2358  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2359  if (input_wrapper == nullptr) {
2360  input_wrapper = this->addEdge(input);
2361  }
2362  input_wrapper->consumers_.emplace_back(node_wrapper);
2363  }
2364  for (auto output : outputs) {
2365  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2366  if (output_wrapper == nullptr) {
2367  output_wrapper = this->addEdge(output);
2368  }
2369  output_wrapper->producers_.emplace_back(node_wrapper);
2370  }
2371 
2372  node_repository_.emplace_back(node_wrapper);
2373  used_node_names_.insert(name);
2374  node->setGraph(this);
2375  ;
2376  return node;
2377 }
2378 
2379 template <typename T, typename... Args,
2380  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2381 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2382  std::initializer_list<Edge *> inputs,
2383  std::initializer_list<std::string> output_names) {
2384  if (used_node_names_.find(name) != used_node_names_.end()) {
2385  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2386  return nullptr;
2387  }
2388  std::vector<Edge *> outputs;
2389  for (auto output_name : output_names) {
2390  Edge *output = getEdge(output_name);
2391  if (output == nullptr) {
2392  output = createEdge(output_name);
2393  }
2394  outputs.emplace_back(output);
2395  }
2396  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs, type));
2397  NodeWrapper *node_wrapper = new NodeWrapper();
2398  node_wrapper->is_external_ = false;
2399  node_wrapper->node_ = node;
2400  node_wrapper->name_ = name;
2401  for (auto input : inputs) {
2402  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2403  if (input_wrapper == nullptr) {
2404  input_wrapper = this->addEdge(input);
2405  }
2406  input_wrapper->consumers_.emplace_back(node_wrapper);
2407  }
2408  for (auto output : outputs) {
2409  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2410  if (output_wrapper == nullptr) {
2411  output_wrapper = this->addEdge(output);
2412  }
2413  output_wrapper->producers_.emplace_back(node_wrapper);
2414  }
2415 
2416  node_repository_.emplace_back(node_wrapper);
2417  used_node_names_.insert(name);
2418  node->setGraph(this);
2419  ;
2420  return node;
2421 }
2422 
2423 template <typename T, typename... Args,
2424  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2425 Node *Graph::createInfer(const std::string &name, base::InferenceType type,
2426  std::initializer_list<std::string> input_names,
2427  std::initializer_list<Edge *> outputs) {
2428  if (used_node_names_.find(name) != used_node_names_.end()) {
2429  NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2430  return nullptr;
2431  }
2432  std::vector<Edge *> inputs;
2433  for (auto input_name : input_names) {
2434  Edge *input = getEdge(input_name);
2435  if (input == nullptr) {
2436  input = createEdge(input_name);
2437  }
2438  inputs.emplace_back(input);
2439  }
2440  std::vector<Edge *> outputs_vec;
2441  for (auto output : outputs) {
2442  outputs_vec.emplace_back(output);
2443  }
2444  Node *node = dynamic_cast<Node *>(new T(name, inputs, outputs_vec, type));
2445  NodeWrapper *node_wrapper = new NodeWrapper();
2446  node_wrapper->is_external_ = false;
2447  node_wrapper->node_ = node;
2448  node_wrapper->name_ = name;
2449  for (auto input : inputs) {
2450  EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2451  if (input_wrapper == nullptr) {
2452  input_wrapper = this->addEdge(input);
2453  }
2454  input_wrapper->consumers_.emplace_back(node_wrapper);
2455  }
2456  for (auto output : outputs) {
2457  EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2458  if (output_wrapper == nullptr) {
2459  output_wrapper = this->addEdge(output);
2460  }
2461  output_wrapper->producers_.emplace_back(node_wrapper);
2462  }
2463 
2464  node_repository_.emplace_back(node_wrapper);
2465  used_node_names_.insert(name);
2466  node->setGraph(this);
2467  ;
2468  return node;
2469 }
2470 
2471 template <typename T, typename... Args,
2472  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2474  return this->createInfer<T>(desc.getName(), type, desc.getInputs(),
2475  desc.getOutputs());
2476 }
2477 
2478 // template <typename... Args>
2479 // Node *Graph::createNode(const NodeDesc &desc, Args &...args) {
2480 // const std::string &name = desc.getName();
2481 // const std::string &node_key = desc.getKey();
2482 // std::vector<std::string> input_names = desc.getInputs();
2483 // std::vector<std::string> output_names = desc.getOutputs();
2484 // if (used_node_names_.find(name) != used_node_names_.end()) {
2485 // NNDEPLOY_LOGE("node name[%s] is already used!\n", name.c_str());
2486 // return nullptr;
2487 // }
2488 // std::vector<Edge *> inputs;
2489 // for (auto input_name : input_names) {
2490 // Edge *input = getEdge(input_name);
2491 // if (input == nullptr) {
2492 // input = createEdge(input_name);
2493 // }
2494 // inputs.emplace_back(input);
2495 // }
2496 // std::vector<Edge *> outputs;
2497 // for (auto output_name : output_names) {
2498 // Edge *output = getEdge(output_name);
2499 // if (output == nullptr) {
2500 // output = createEdge(output_name);
2501 // }
2502 // outputs.emplace_back(output);
2503 // }
2504 // Node *node = nndeploy::dag::createNode(node_key, name, inputs, outputs);
2505 // // Node *node =
2506 // // nndeploy::dag::createNode(node_key, name, inputs, outputs, args...);
2507 // if (node == nullptr) {
2508 // NNDEPLOY_LOGE("create infer node[%s] failed!\n", desc.getName().c_str());
2509 // return nullptr;
2510 // }
2511 // NodeWrapper *node_wrapper = new NodeWrapper();
2512 // node_wrapper->is_external_ = false;
2513 // node_wrapper->node_ = node;
2514 // node_wrapper->name_ = name;
2515 // for (auto input : inputs) {
2516 // EdgeWrapper *input_wrapper = findEdgeWrapper(edge_repository_, input);
2517 // if (input_wrapper == nullptr) {
2518 // input_wrapper = this->addEdge(input);
2519 // }
2520 // input_wrapper->consumers_.emplace_back(node_wrapper);
2521 // }
2522 // for (auto output : outputs) {
2523 // EdgeWrapper *output_wrapper = findEdgeWrapper(edge_repository_, output);
2524 // if (output_wrapper == nullptr) {
2525 // output_wrapper = this->addEdge(output);
2526 // }
2527 // output_wrapper->producers_.emplace_back(node_wrapper);
2528 // }
2529 
2530 // node_repository_.emplace_back(node_wrapper);
2531 // used_node_names_.insert(name);
2532 
2533 // node->setGraph(this);
2534 
2535 // return node;
2536 // }
2537 
2538 // template <typename T, typename... Args,
2539 // typename std::enable_if<std::is_base_of<Node, T>{}, int>::type = 0>
2540 // Node *Graph::createNode(const std::string &name = "", Args &...args) {
2541 // Node *node = this->createNode<T>(name, {}, {}, args...);
2542 // if (node == nullptr) {
2543 // NNDEPLOY_LOGE("create node[%s] failed!\n", name.c_str());
2544 // return nullptr;
2545 // }
2546 // return node;
2547 // }
2548 template <typename T, typename... Args,
2549  typename std::enable_if<std::is_base_of<Node, T>{}, int>::type>
2550 Node *Graph::createNode(const NodeDesc &desc, Args &...args) {
2551  Node *node = this->createNode<T>(desc.getName(), desc.getInputs(),
2552  desc.getOutputs(), args...);
2553  if (node == nullptr) {
2554  NNDEPLOY_LOGE("create infer node[%s] failed!\n", desc.getName().c_str());
2555  return node;
2556  }
2557  return node;
2558 }
2559 
2560 // Not recommended api
2561 using createGraphFunc = std::function<Graph *(
2562  const std::string &name, base::InferenceType inference_type,
2563  base::DeviceType device_type, Edge *input, Edge *output,
2564  base::ModelType model_type, bool is_path,
2565  std::vector<std::string> model_value)>;
2566 
2567 extern NNDEPLOY_CC_API std::map<std::string, createGraphFunc> &
2569 
2571  const std::string &name,
2572  createGraphFunc func){getGlobalGraphCreatorMap()[name] = func;
2573 } // namespace dag
2574 }; // namespace nndeploy
2575 
2576 extern NNDEPLOY_CC_API Graph *createGraph(const std::string &name,
2577  base::InferenceType inference_type,
2578  base::DeviceType device_type,
2579  Edge *input, Edge *output,
2580  base::ModelType model_type,
2581  bool is_path,
2582  std::vector<std::string> model_value);
2583 
2584 // to json
2586  Graph *graph, rapidjson::Value &json,
2587  rapidjson::Document::AllocatorType &allocator);
2588 extern NNDEPLOY_CC_API std::string serialize(Graph *graph);
2590  const std::string &path);
2591 // from json
2592 extern NNDEPLOY_CC_API Graph *deserialize(rapidjson::Value &json);
2593 extern NNDEPLOY_CC_API Graph *deserialize(const std::string &json_str);
2594 extern NNDEPLOY_CC_API Graph *loadFile(const std::string &path);
2595 
2596 } // namespace dag
2597 } // namespace nndeploy
2598 
2599 #endif // _NNDEPLOY_DAG_EXECUTOR_H_
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
Directed Acyclic Graph Node.
Definition: graph.h:31
base::Status removeOtherUrl(const std::string &url)
Remove other type URL.
std::vector< Edge * > trace(Edge *input)
Trace execution (single input version)
virtual std::vector< Edge * > operator()(std::vector< Edge * > inputs)
Operator overload (multiple inputs version)
virtual base::Status setInputsSharedPtr(std::vector< std::shared_ptr< Edge >> inputs)
Set input edge list (shared pointer version)
base::Status connect(Node *predecessor, Node *successor, int predecessor_port=0, int successor_port=0)
Connect two nodes.
Node * createNode4Py(const std::string &key, const std::string &name="")
Create node for Python.
std::vector< EdgeWrapper * > edge_repository_
Edge repository.
Definition: graph.h:1365
bool isForwardApiOk()
Check if forward API is working properly.
std::vector< std::string > getVideoUrl() const
Get all video URL list.
virtual base::Status defaultParam()
Set default parameters.
EdgeWrapper * addEdge(Edge *edge, bool is_external=true)
Add edge to graph.
virtual base::Status init()
Initialize graph.
virtual std::map< std::string, int > getLoopCountMap()
Get loop count map.
base::Status addNodeSharedPtr(std::shared_ptr< Node > node)
Add node to graph (shared pointer version)
base::Status addImageUrl(const std::string &url)
Add image URL.
Node * getNode(const std::string &name)
Get node by name.
std::map< std::string, std::shared_ptr< RunStatus > > getNodesRunStatusRecursive()
Recursively get run status of all nodes (including nodes in subgraphs)
std::vector< std::string > getModelUrl() const
Get all model URL list.
std::shared_ptr< base::Param > getExternalParam(const std::string &key)
Get external parameter.
virtual std::set< std::string > getUnusedNodeNames()
Get unused node name set.
virtual base::Any & getResourceWithoutState(const std::string &key)
Get stateless global resource.
virtual base::Status deserialize(const std::string &json_str)
Deserialize from JSON string.
Graph(const std::string &name)
Constructor.
Edge * createEdge(const std::string &name)
Create edge.
base::Status updateNodeIO(Node *node, std::vector< Edge * > inputs, std::vector< Edge * > outputs)
Update node's input and output.
std::vector< Edge * > trace()
Trace execution (no input version)
std::vector< Node * > getNodesRecursive()
Recursively get all nodes (including nodes in subgraphs)
std::vector< std::string > getNodesName()
Get all node names.
int getEdgeQueueDropCount()
Get edge queue drop count.
std::vector< NodeWrapper * > run_node_repository_
Run node repository.
Definition: graph.h:1367
std::shared_ptr< Node > getNodeSharedPtr(const std::string &name)
Get node by name (shared pointer version)
virtual base::Status setOutputs(std::vector< Edge * > outputs)
Set output edge list.
bool getGraphNodeShareStream()
Get whether graph nodes share stream.
std::vector< std::string > other_url_
Other URL list.
Definition: graph.h:1362
Node * createNode4Py(const NodeDesc &desc)
Create node for Python by node description.
base::Status setEdgeQueueOverflowPolicy(base::QueueOverflowPolicy policy, int drop_count=1)
Set edge queue overflow policy.
base::Status setNodeDesc(Node *node, const NodeDesc &desc)
Set node description.
base::Status removeAudioUrl(const std::string &url)
Remove audio URL.
base::Status addOtherUrl(const std::string &url)
Add other type URL.
Node * getNode(int index)
Get node by index.
base::Status addNode(Node *node, bool is_external=true)
Add node to graph.
NodeWrapper * getNodeWrapper(const std::string &name)
Get node wrapper by name.
EdgeWrapper * getEdgeWrapper(const std::string &name)
Get edge wrapper by name.
virtual void removeInOutNode()
Remove input/output nodes.
std::map< std::string, std::map< std::string, std::string > > node_value_map_
Definition: graph.h:1393
base::Status markInputEdge(std::vector< Edge * > inputs)
Mark input edges.
void setGraphNodeShareStream(bool flag)
Set whether graph nodes share stream.
base::QueueOverflowPolicy getEdgeQueueOverflowPolicy()
Get edge queue overflow policy.
std::map< std::string, base::Any > resource_without_state_
Global resources (stateless)
Definition: graph.h:1400
Node * createNode(const std::string &key, const std::string &name="")
Create node by key.
std::vector< NodeWrapper * > node_repository_
Node repository.
Definition: graph.h:1366
virtual void setLoopMaxFlag(bool is_loop_max_flag)
Set loop max flag.
std::vector< std::string > getAudioUrl() const
Get all audio URL list.
base::Status removeVideoUrl(const std::string &url)
Remove video URL.
base::Status addNodeInputAndOutput(NodeWrapper *node_wrapper, std::vector< Edge * > inputs, std::vector< Edge * > outputs)
Add node's input and output.
Node * getOutputNode(int index)
Get output node by index.
virtual base::Status setInputSharedPtr(std::shared_ptr< Edge > input, int index=-1)
Set input edge (shared pointer version)
Node * getNodeByKey(const std::string &key)
Get node by key.
virtual std::vector< Edge * > forward(std::vector< Edge * > inputs)
Forward propagation (multiple inputs version)
virtual base::Status addResourceWithoutState(const std::string &key, const base::Any &value)
Add stateless global resource.
virtual base::Status setOutputSharedPtr(std::shared_ptr< Edge > output, int index=-1)
Set output edge (shared pointer version)
virtual base::Status executor()
Execute graph.
base::Status setNodeParam(const std::string &node_name, base::Param *param)
Set node parameter.
std::vector< std::string > getImageUrl() const
Get all image URL list.
virtual std::vector< Edge * > forward()
Forward propagation (no input version)
virtual base::Status setOutputsSharedPtr(std::vector< std::shared_ptr< Edge >> outputs)
Set output edge list (shared pointer version)
virtual void setNodeValue(const std::string &node_value_str)
Set node value (string format)
base::Status addModelUrl(const std::string &url)
Add model URL.
std::vector< std::shared_ptr< Node > > shared_node_repository_
Shared node repository.
Definition: graph.h:1369
base::Status updteEdge(EdgeWrapper *edge_wrapper, Edge *edge, bool is_external=true)
Update edge.
std::shared_ptr< Edge > getEdgeSharedPtr(const std::string &name)
Get edge by name (shared pointer version)
virtual bool getLoopMaxFlag()
Get loop max flag.
base::Status disconnect(Node *predecessor, Node *successor, int predecessor_port=0, int successor_port=0)
Disconnect two nodes.
virtual int getLoopCount()
Get loop count.
Node * getInputNode(int index)
Get input node by index.
base::Status setNodeParamSharedPtr(const std::string &node_name, std::shared_ptr< base::Param > param)
Set node parameter (shared pointer version)
virtual std::map< std::string, std::map< std::string, std::string > > getNodeValue()
Get node value map.
base::Status removeModelUrl(const std::string &url)
Remove model URL.
std::vector< Node * > getNodes()
Get all nodes.
virtual void setUnusedNodeNames(const std::string &node_name)
Set unused node name.
virtual void removeUnusedNodeNames(const std::set< std::string > &node_names)
Remove unused node name set.
virtual void setLoopCount(int loop_count)
Set loop count.
Edge * getEdge(const std::string &name)
Get edge by name.
Graph(const std::string &name, std::vector< Edge * > inputs, std::vector< Edge * > outputs)
Constructor.
virtual base::Status serialize(rapidjson::Value &json, rapidjson::Document::AllocatorType &allocator)
Serialize to JSON.
std::map< std::string, std::shared_ptr< RunStatus > > getNodesRunStatus()
Get run status of all nodes.
virtual base::Status run()
Run graph.
virtual void setTraceFlag(bool flag)
Set trace flag.
virtual bool synchronize()
Synchronize execution.
base::Status addAudioUrl(const std::string &url)
Add audio URL.
std::vector< std::shared_ptr< Edge > > shared_edge_repository_
Shared edge repository.
Definition: graph.h:1368
virtual base::Status addResourceWithState(const std::string &key, Edge *edge)
Add stateful global resource.
base::Status deleteEdge(Edge *edge)
Delete edge from graph.
base::Status setNodeParallelType(const std::string &node_name, base::ParallelType parallel_type)
Set node parallel type.
virtual base::Status construct()
Construct graph.
virtual base::Status setOutput(Edge *output, int index=-1)
Set output edge.
std::shared_ptr< Edge > createEdgeSharedPtr(const std::string &name)
Create edge (shared pointer version)
virtual base::Status deserialize(rapidjson::Value &json)
Deserialize from JSON.
virtual bool interrupt()
Interrupt execution.
std::vector< std::string > image_url_
Image URL list.
Definition: graph.h:1358
base::Status setExternalParam(const std::string &key, std::shared_ptr< base::Param > param)
Set external parameter.
virtual base::Status setInputs(std::vector< Edge * > inputs)
Set input edge list.
NodeWrapper * getNodeWrapper(Node *node)
Get node wrapper.
virtual ~Graph()
Destructor.
std::vector< std::string > getOtherUrl() const
Get all other type URL list.
base::Status dump(std::ostream &oss=std::cout)
Print graph information.
std::vector< Edge * > trace(std::vector< Edge * > inputs)
Trace execution (multiple inputs version)
base::Status removeImageUrl(const std::string &url)
Remove image URL.
EdgeWrapper * getEdgeWrapper(Edge *edge)
Get edge wrapper.
virtual std::string serialize()
Serialize to JSON string.
virtual std::vector< Edge * > operator()(Edge *input)
Operator overload (single input version)
std::shared_ptr< base::Param > getNodeParamSharedPtr(const std::string &node_name)
Get node parameter (shared pointer version)
base::Status markOutputEdge(std::vector< Edge * > outputs)
Mark output edges.
std::vector< std::string > video_url_
Video URL list.
Definition: graph.h:1359
std::map< std::string, std::shared_ptr< base::Param > > external_param_repository_
External parameter repository.
Definition: graph.h:1378
std::vector< std::string > audio_url_
Audio URL list.
Definition: graph.h:1360
std::map< std::string, Edge * > resource_with_state_
Global resources (stateful)
Definition: graph.h:1407
virtual base::Status toStaticGraph()
Convert to static graph.
std::vector< std::string > getNodesNameRecursive()
Recursively get all node names (including nodes in subgraphs)
virtual std::vector< Edge * > forward(Edge *input)
Forward propagation (single input version)
int getNodeCount()
Get total number of nodes.
virtual base::Status deinit()
Deinitialize graph.
EdgeWrapper * addEdgeSharedPtr(std::shared_ptr< Edge > edge)
Add edge to graph (shared pointer version)
virtual Edge * getResourceWithState(const std::string &key)
Get stateful global resource.
std::set< std::string > unused_node_names_
Unused node name set.
Definition: graph.h:1383
virtual std::vector< Edge * > operator()()
Operator overload (no input version)
std::set< std::string > used_node_names_
Used node name set.
Definition: graph.h:1370
base::Status deleteNode(Node *node)
Delete node from graph.
Node * createInfer(const std::string &name, base::InferenceType type, Edge *input, Edge *output)
Template method: Create inference node (single input single output)
Definition: graph.h:1967
std::vector< std::string > model_url_
Model URL list.
Definition: graph.h:1361
base::Status setEdgeQueueMaxSize(int queue_max_size)
Set maximum size of edge queue.
Node * createNode(const NodeDesc &desc)
Create node by node description.
virtual void setNodeValue(std::map< std::string, std::map< std::string, std::string >> node_value_map)
Set node value map.
base::Status addVideoUrl(const std::string &url)
Add video URL.
int getEdgeQueueMaxSize()
Get maximum size of edge queue.
std::vector< Node * > getNodesByKey(const std::string &key)
Get all nodes matching the key.
base::Param * getNodeParam(const std::string &node_name)
Get node parameter.
virtual base::Status setInput(Edge *input, int index=-1)
Set input edge.
virtual void setNodeValue(const std::string &node_name, const std::string &key, const std::string &value)
Set node value.
virtual base::Status removeUnusedNodeAndEdge()
Remove unused nodes and edges.
virtual void setUnusedNodeNames(const std::set< std::string > &node_names)
Set unused node name set.
Node * getInferNode(int index)
Get inference node by index.
std::shared_ptr< Executor > executor_
Executor.
Definition: graph.h:1372
virtual void removeUnusedNodeNames(const std::string &node_name)
Remove unused node name.
std::set< std::string > used_edge_names_
Used edge name set.
Definition: graph.h:1371
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 setGraph(Graph *graph)
Set parent graph.
TypeGraphRegister(const std::string &name, createGraphFunc func)
Definition: graph.h:2570
#define NNDEPLOY_LOGE(fmt,...)
Definition: log.h:59
#define NNDEPLOY_CC_API
api
Definition: macro.h:29
@ kQueueOverflowPolicyNodeBackpressure
Definition: common.h:202
std::map< std::string, createGraphFunc > & getGlobalGraphCreatorMap()
std::function< Graph *(const std::string &name, base::InferenceType inference_type, base::DeviceType device_type, Edge *input, Edge *output, base::ModelType model_type, bool is_path, std::vector< std::string > model_value)> createGraphFunc
Definition: graph.h:2565
Graph * loadFile(const std::string &path)
base::Status serialize(Graph *graph, rapidjson::Value &json, rapidjson::Document::AllocatorType &allocator)
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.
Graph * createGraph(const std::string &name, base::InferenceType inference_type, base::DeviceType device_type, Edge *input, Edge *output, base::ModelType model_type, bool is_path, std::vector< std::string > model_value)
Graph * deserialize(rapidjson::Value &json)
base::Status saveFile(Graph *graph, const std::string &path)