HAL
python_bindings.cpp
Go to the documentation of this file.
1 
3 
10 
11 #pragma GCC diagnostic push
12 #pragma GCC diagnostic ignored "-Wshadow"
13 #ifdef COMPILER_CLANG
14 #pragma clang diagnostic ignored "-Wself-assign-overloaded"
15 #pragma clang diagnostic ignored "-Wnested-anon-types"
16 #pragma clang diagnostic ignored "-Wshadow-field-in-constructor-modified"
17 #endif
18 
19 #include "hal_core/defines.h"
20 #include "hal_core/netlist/gate.h"
21 #include "hal_core/netlist/net.h"
23 #include "hal_core/utilities/log.h"
25 #include "pybind11/operators.h"
26 #include "pybind11/pybind11.h"
27 #include "pybind11/stl.h"
28 #include "pybind11/stl_bind.h"
29 
30 #pragma GCC diagnostic pop
31 
32 namespace py = pybind11;
33 namespace hal
34 {
35 #ifdef PYBIND11_MODULE
36  PYBIND11_MODULE(graph_algorithm, m)
37  {
38  m.doc() = "Graph algorithms based on igraph operating on a netlist graph abstraction.";
39 #else
40  PYBIND11_PLUGIN(graph_algorithm)
41  {
42  py::module m("graph_algorithm", "Graph algorithms based on igraph operating on a netlist graph abstraction.");
43 #endif // ifdef PYBIND11_MODULE
44 
45  py::class_<GraphAlgorithmPlugin, RawPtrWrapper<GraphAlgorithmPlugin>, BasePluginInterface> py_graph_algorithm_plugin(m, "GraphAlgorithmPlugin");
46 
47  py_graph_algorithm_plugin.def_property_readonly("name", &GraphAlgorithmPlugin::get_name, R"(
48  The name of the plugin.
49 
50  :type: str
51  )");
52 
53  py_graph_algorithm_plugin.def("get_name", &GraphAlgorithmPlugin::get_name, R"(
54  Get the name of the plugin.
55 
56  :returns: The name of the plugin.
57  :rtype: str
58  )");
59 
60  py_graph_algorithm_plugin.def_property_readonly("version", &GraphAlgorithmPlugin::get_version, R"(
61  The version of the plugin.
62 
63  :type: str
64  )");
65 
66  py_graph_algorithm_plugin.def("get_version", &GraphAlgorithmPlugin::get_version, R"(
67  Get the version of the plugin.
68 
69  :returns: The version of the plugin.
70  :rtype: str
71  )");
72 
73  py_graph_algorithm_plugin.def_property_readonly("description", &GraphAlgorithmPlugin::get_description, R"(
74  The description of the plugin.
75 
76  :type: str
77  )");
78 
79  py_graph_algorithm_plugin.def("get_description", &GraphAlgorithmPlugin::get_description, R"(
80  Get the description of the plugin.
81 
82  :returns: The description of the plugin.
83  :rtype: str
84  )");
85 
86  py_graph_algorithm_plugin.def_property_readonly("dependencies", &GraphAlgorithmPlugin::get_dependencies, R"(
87  A set of plugin names that this plugin depends on.
88 
89  :type: set[str]
90  )");
91 
92  py_graph_algorithm_plugin.def("get_dependencies", &GraphAlgorithmPlugin::get_dependencies, R"(
93  Get a set of plugin names that this plugin depends on.
94 
95  :returns: A set of plugin names that this plugin depends on.
96  :rtype: set[str]
97  )");
98 
99  py::class_<graph_algorithm::NetlistGraph, RawPtrWrapper<graph_algorithm::NetlistGraph>> py_netlist_graph(m, "NetlistGraph", R"(
100  Holds a directed graph corresponding to a netlist.
101  )");
102 
103  py::enum_<graph_algorithm::NetlistGraph::Direction>(py_netlist_graph, "Direction", R"(
104  The direction of exploration within the graph.
105  )")
106  .value("NONE", graph_algorithm::NetlistGraph::Direction::NONE, R"(No direction, invalid default setting.)")
107  .value("IN", graph_algorithm::NetlistGraph::Direction::IN, R"(Explore through the inputs of the current node, i.e., traverse backwards.)")
108  .value("OUT", graph_algorithm::NetlistGraph::Direction::OUT, R"(Explore through the outputs of the current node, i.e., traverse forwards.)")
109  .value("ALL", graph_algorithm::NetlistGraph::Direction::ALL, R"(Explore in both directions, i.e., treat the graph as undirected.)")
110  .export_values();
111 
112  py_netlist_graph.def_static(
113  "from_netlist",
114  [](Netlist* nl, bool create_dummy_vertices = false, const std::function<bool(const Net*)>& filter = nullptr) -> std::unique_ptr<graph_algorithm::NetlistGraph> {
115  auto res = graph_algorithm::NetlistGraph::from_netlist(nl, create_dummy_vertices, filter);
116  if (res.is_ok())
117  {
118  return res.get();
119  }
120  else
121  {
122  log_error("python_context", "error encountered while creating a graph from a netlist:\n{}", res.get_error().get());
123  return nullptr;
124  }
125  },
126  py::arg("nl"),
127  py::arg("create_dummy_vertices") = false,
128  py::arg("filter") = nullptr,
129  R"(Create a directed graph from a netlist. Optionally create dummy nodes at nets missing a source or destination. An optional filter can be applied to exclude undesired edges.
130 
131  :param hal_py.Netlist nl: The netlist.
132  :param bool create_dummy_vertices: Set ``True`` to create dummy vertices, ``False`` otherwise. Defaults to ``False``.
133  :param lambda filter: An optional filter that is evaluated on every net of the netlist. Defaults to ``None``.
134  :returns: The netlist graph on success, ``None`` otherwise.
135  :rtype: graph_algorithm.NetlistGraph or None
136  )");
137 
138  py_netlist_graph.def_static(
139  "from_netlist_no_edges",
140  [](Netlist* nl, const std::vector<Gate*>& gates = {}) -> std::unique_ptr<graph_algorithm::NetlistGraph> {
142  if (res.is_ok())
143  {
144  return res.get();
145  }
146  else
147  {
148  log_error("python_context", "error encountered while creating a graph from a netlist:\n{}", res.get_error().get());
149  return nullptr;
150  }
151  },
152  py::arg("nl"),
153  py::arg("gates") = std::vector<Gate*>(),
154  R"(Create an empty directed graph from a netlist, i.e., vertices for all gates are created, but no edges are added.
155 
156  :param hal_py.Netlist nl: The netlist.
157  :param list[hal_py.Gate] gates: The gates to include in the graph. If omitted, all gates of the netlist will be included.
158  :returns: The netlist graph on success, ``None`` otherwise.
159  :rtype: graph_algorithm.NetlistGraph or None
160  )");
161 
162  py_netlist_graph.def(
163  "copy",
164  [](const graph_algorithm::NetlistGraph& self) -> std::unique_ptr<graph_algorithm::NetlistGraph> {
165  auto res = self.copy();
166  if (res.is_ok())
167  {
168  return res.get();
169  }
170  else
171  {
172  log_error("python_context", "error encountered while copying netlist graph:\n{}", res.get_error().get());
173  return nullptr;
174  }
175  },
176  R"(
177  Create a deep copy of the netlist graph.
178 
179  :returns: The copied netlist graph on success, ``None`` otherwise.
180  :rtype: graph_algorithm.NetlistGraph or None
181  )");
182 
183  py_netlist_graph.def("get_netlist", &graph_algorithm::NetlistGraph::get_netlist, R"(
184  Get the netlist associated with the netlist graph.
185 
186  :returns: The netlist.
187  :rtype: hal_py.Netlist
188  )");
189 
190  py_netlist_graph.def(
191  "get_gates_from_vertices",
192  [](const graph_algorithm::NetlistGraph& self, const std::vector<u32>& vertices) -> std::optional<std::vector<Gate*>> {
193  auto res = self.get_gates_from_vertices(vertices);
194  if (res.is_ok())
195  {
196  return res.get();
197  }
198  else
199  {
200  log_error("python_context", "error encountered while getting gates from vertices:\n{}", res.get_error().get());
201  return std::nullopt;
202  }
203  },
204  py::arg("vertices"),
205  R"(
206  Get the gates corresponding to the specified list of vertices.
207  The result may contain ``None`` for dummy vertices.
208 
209  :param list[int] vertices: A list of vertices.
210  :returns: A list of gates on success, ``None`` otherwise.
211  :rtype: list[hal_py.Gate] or None
212  )");
213 
214  py_netlist_graph.def(
215  "get_gates_from_vertices",
216  [](const graph_algorithm::NetlistGraph& self, const std::set<u32>& vertices) -> std::optional<std::vector<Gate*>> {
217  const auto res = self.get_gates_from_vertices(vertices);
218  if (res.is_ok())
219  {
220  return res.get();
221  }
222  else
223  {
224  log_error("python_context", "error encountered while getting gates from vertices:\n{}", res.get_error().get());
225  return std::nullopt;
226  }
227  },
228  py::arg("vertices"),
229  R"(
230  Get the gates corresponding to the specified set of vertices.
231  The result may contain ``None`` for dummy vertices.
232 
233  :param set[int] vertices: A set of vertices.
234  :returns: A list of gates on success, ``None`` otherwise.
235  :rtype: list[hal_py.Gate] or None
236  )");
237 
238  py_netlist_graph.def(
239  "get_gates_set_from_vertices",
240  [](const graph_algorithm::NetlistGraph& self, const std::vector<u32>& vertices) -> std::optional<std::set<Gate*>> {
241  auto res = self.get_gates_set_from_vertices(vertices);
242  if (res.is_ok())
243  {
244  return res.get();
245  }
246  else
247  {
248  log_error("python_context", "error encountered while getting gates from vertices:\n{}", res.get_error().get());
249  return std::nullopt;
250  }
251  },
252  py::arg("vertices"),
253  R"(
254  Get the gates corresponding to the specified list of vertices.
255 
256  :param list[int] vertices: A list of vertices.
257  :returns: A list of gates on success, ``None`` otherwise.
258  :rtype: set[hal_py.Gate] or None
259  )");
260 
261  py_netlist_graph.def(
262  "get_gates_set_from_vertices",
263  [](const graph_algorithm::NetlistGraph& self, const std::set<u32>& vertices) -> std::optional<std::set<Gate*>> {
264  const auto res = self.get_gates_set_from_vertices(vertices);
265  if (res.is_ok())
266  {
267  return res.get();
268  }
269  else
270  {
271  log_error("python_context", "error encountered while getting gates from vertices:\n{}", res.get_error().get());
272  return std::nullopt;
273  }
274  },
275  py::arg("vertices"),
276  R"(
277  Get the gates corresponding to the specified set of vertices.
278 
279  :param set[int] vertices: A set of vertices.
280  :returns: A list of gates on success, ``None`` otherwise.
281  :rtype: set[hal_py.Gate] or None
282  )");
283 
284  py_netlist_graph.def(
285  "get_gate_from_vertex",
286  [](const graph_algorithm::NetlistGraph& self, const u32 vertex) -> Gate* {
287  const auto res = self.get_gate_from_vertex(vertex);
288  if (res.is_ok())
289  {
290  return res.get();
291  }
292  else
293  {
294  log_error("python_context", "error encountered while getting gate from vertex:\n{}", res.get_error().get());
295  return nullptr;
296  }
297  },
298  py::arg("vertex"),
299  R"(
300  Get the gates corresponding to the specified vertex.
301 
302  :param int vertex: A vertex.
303  :returns: A gate on success, ``None`` otherwise.
304  :rtype: hal_py.Gate or None
305  )");
306 
307  py_netlist_graph.def(
308  "get_vertices_from_gates",
309  [](const graph_algorithm::NetlistGraph& self, const std::vector<Gate*>& gates) -> std::optional<std::vector<u32>> {
310  auto res = self.get_vertices_from_gates(gates);
311  if (res.is_ok())
312  {
313  return res.get();
314  }
315  else
316  {
317  log_error("python_context", "error encountered while getting vertices from gates:\n{}", res.get_error().get());
318  return std::nullopt;
319  }
320  },
321  py::arg("gates"),
322  R"(
323  Get the vertices corresponding to the specified list of gates.
324 
325  :param list[hal_py.Gate] gates: A list of gates.
326  :returns: A list of vertices on success, ``None`` otherwise.
327  :rtype: list[int] or None
328  )");
329 
330  py_netlist_graph.def(
331  "get_vertices_from_gates",
332  [](const graph_algorithm::NetlistGraph& self, const std::set<Gate*>& gates) -> std::optional<std::vector<u32>> {
333  auto res = self.get_vertices_from_gates(gates);
334  if (res.is_ok())
335  {
336  return res.get();
337  }
338  else
339  {
340  log_error("python_context", "error encountered while getting vertices from gates:\n{}", res.get_error().get());
341  return std::nullopt;
342  }
343  },
344  py::arg("gates"),
345  R"(
346  Get the vertices corresponding to the specified set of gates.
347 
348  :param set[hal_py.Gate] gates: A set of gates.
349  :returns: A list of vertices on success, ``None`` otherwise.
350  :rtype: list[int] or None
351  )");
352 
353  py_netlist_graph.def(
354  "get_vertex_from_gate",
355  [](const graph_algorithm::NetlistGraph& self, Gate* g) -> std::optional<u32> {
356  auto res = self.get_vertex_from_gate(g);
357  if (res.is_ok())
358  {
359  return res.get();
360  }
361  else
362  {
363  log_error("python_context", "error encountered while getting vertex from gate:\n{}", res.get_error().get());
364  return std::nullopt;
365  }
366  },
367  py::arg("g"),
368  R"(
369  Get the vertex corresponding to the specified gate.
370 
371  :param hal_py.Gate g: A gate.
372  :returns: A vertex on success, ``None`` otherwise.
373  :rtype: int or None
374  )");
375 
376  py_netlist_graph.def("get_num_vertices", &graph_algorithm::NetlistGraph::get_num_vertices, py::arg("only_connected") = false, R"(
377  Get the number of vertices in the netlist graph.
378 
379  :param bool only_connected: Set ``True`` to only count vertices connected to at least one edge, ``False`` otherwise. Defaults to ``False``.
380  :returns: The number of vertices in the netlist graph.
381  :rtype: int
382  )");
383 
384  py_netlist_graph.def("get_num_edges", &graph_algorithm::NetlistGraph::get_num_edges, R"(
385  Get the number of edges in the netlist graph.
386 
387  :returns: The number of edges in the netlist graph.
388  :rtype: int
389  )");
390 
391  py_netlist_graph.def(
392  "get_vertices",
393  [](const graph_algorithm::NetlistGraph& self, bool only_connected = false) -> std::optional<std::vector<u32>> {
394  auto res = self.get_vertices(only_connected);
395  if (res.is_ok())
396  {
397  return res.get();
398  }
399  else
400  {
401  log_error("python_context", "error encountered while getting vertices:\n{}", res.get_error().get());
402  return std::nullopt;
403  }
404  },
405  py::arg("only_connected") = false,
406  R"(
407  Get the vertices in the netlist graph.
408 
409  :param bool only_connected: Set ``True`` to only return vertices connected to at least one edge, ``False`` otherwise. Defaults to ``False``.
410  :returns: A list of vertices on success, ``None`` otherwise.
411  :rtype: list[int] or None
412  )");
413 
414  py_netlist_graph.def(
415  "get_edges",
416  [](const graph_algorithm::NetlistGraph& self) -> std::optional<std::vector<std::pair<u32, u32>>> {
417  auto res = self.get_edges();
418  if (res.is_ok())
419  {
420  return res.get();
421  }
422  else
423  {
424  log_error("python_context", "error encountered while getting edges:\n{}", res.get_error().get());
425  return std::nullopt;
426  }
427  },
428  R"(
429  Get the edges between vertices in the netlist graph.
430 
431  :returns: A list of edges on success, ``None`` otherwise.
432  :rtype: list[tuple(int,int)] or None
433  )");
434 
435  py_netlist_graph.def(
436  "get_edges_in_netlist",
437  [](const graph_algorithm::NetlistGraph& self) -> std::optional<std::vector<std::pair<Gate*, Gate*>>> {
438  auto res = self.get_edges_in_netlist();
439  if (res.is_ok())
440  {
441  return res.get();
442  }
443  else
444  {
445  log_error("python_context", "error encountered while getting edges:\n{}", res.get_error().get());
446  return std::nullopt;
447  }
448  },
449  R"(
450  Get the edges between gates in the netlist corresponding to the netlist graph.
451 
452  :returns: A list of edges on success, ``None`` otherwise.
453  :rtype: list[tuple(hal_py.Gate,hal_py.Gate)] or None
454  )");
455 
456  py_netlist_graph.def(
457  "add_edges",
458  [](graph_algorithm::NetlistGraph& self, const std::vector<std::pair<Gate*, Gate*>>& edges) -> bool {
459  auto res = self.add_edges(edges);
460  if (res.is_ok())
461  {
462  return true;
463  }
464  else
465  {
466  log_error("python_context", "error encountered while adding edges:\n{}", res.get_error().get());
467  return false;
468  }
469  },
470  py::arg("edges"),
471  R"(
472  Add edges between the specified pairs of source and destination gates to the netlist graph.
473  The gates must already correspond to vertices in the graph.
474 
475  :param list[tuple(hal_py.Gate,hal_py.Gate)] edges: The edges to add as pairs of gates.
476  :returns: ``True`` on success, ``False`` otherwise.
477  :rtype: bool
478  )");
479 
480  py_netlist_graph.def(
481  "add_edges",
482  [](graph_algorithm::NetlistGraph& self, const std::vector<std::pair<u32, u32>>& edges) -> bool {
483  auto res = self.add_edges(edges);
484  if (res.is_ok())
485  {
486  return true;
487  }
488  else
489  {
490  log_error("python_context", "error encountered while adding edges:\n{}", res.get_error().get());
491  return false;
492  }
493  },
494  py::arg("edges"),
495  R"(
496  Add edges between the specified pairs of source and destination vertices to the netlist graph.
497  The vertices must already exist in the graph.
498 
499  :param list[tuple(int,int)] edges: The edges to add as pairs of vertices.
500  :returns: ``True`` on success, ``False`` otherwise.
501  :rtype: bool
502  )");
503 
504  py_netlist_graph.def(
505  "add_edges",
506  [](graph_algorithm::NetlistGraph& self, const std::map<Gate*, std::set<Gate*>>& edges) -> bool {
507  auto res = self.add_edges(edges);
508  if (res.is_ok())
509  {
510  return true;
511  }
512  else
513  {
514  log_error("python_context", "error encountered while adding edges:\n{}", res.get_error().get());
515  return false;
516  }
517  },
518  py::arg("edges"),
519  R"(
520  Add edges between the specified pairs of source and destination gates to the netlist graph.
521  The vertices must already exist in the graph.
522 
523  :param dict[hal_py.Gate,set[hal_py.Gate]] edges: The edges to add as a dict from source gate to its destination gates.
524  :returns: ``True`` on success, ``False`` otherwise.
525  :rtype: bool
526  )");
527 
528  py_netlist_graph.def(
529  "delete_edges",
530  [](graph_algorithm::NetlistGraph& self, const std::vector<std::pair<Gate*, Gate*>>& edges) -> bool {
531  auto res = self.delete_edges(edges);
532  if (res.is_ok())
533  {
534  return true;
535  }
536  else
537  {
538  log_error("python_context", "error encountered while deleting edges:\n{}", res.get_error().get());
539  return false;
540  }
541  },
542  py::arg("edges"),
543  R"(
544  Delete edges between the specified pairs of source and destination gates from the netlist graph.
545 
546  :param list[tuple(hal_py.Gate,hal_py.Gate)] edges: The edges to delete as pairs of gates.
547  :returns: ``True`` on success, ``False`` otherwise.
548  :rtype: bool
549  )");
550 
551  py_netlist_graph.def(
552  "delete_edges",
553  [](graph_algorithm::NetlistGraph& self, const std::vector<std::pair<u32, u32>>& edges) -> bool {
554  auto res = self.delete_edges(edges);
555  if (res.is_ok())
556  {
557  return true;
558  }
559  else
560  {
561  log_error("python_context", "error encountered while deleting edges:\n{}", res.get_error().get());
562  return false;
563  }
564  },
565  py::arg("edges"),
566  R"(
567  Delete edges between the specified pairs of source and destination vertices from the netlist graph.
568 
569  :param list[tuple(int,int)] edges: The edges to delete as pairs of vertices.
570  :returns: ``True`` on success, ``False`` otherwise.
571  :rtype: bool
572  )");
573 
574  py_netlist_graph.def("print", &graph_algorithm::NetlistGraph::print, R"(
575  Print the edge list of the graph to stdout.
576  )");
577 
578  m.def(
579  "get_connected_components",
580  [](graph_algorithm::NetlistGraph* graph, bool strong, u32 min_size = 0) -> std::optional<std::vector<std::vector<u32>>> {
581  auto res = graph_algorithm::get_connected_components(graph, strong, min_size);
582  if (res.is_ok())
583  {
584  return res.get();
585  }
586  else
587  {
588  log_error("python_context", "error encountered while computing connected components:\n{}", res.get_error().get());
589  return std::nullopt;
590  }
591  },
592  py::arg("graph"),
593  py::arg("strong"),
594  py::arg("min_size") = 0,
595  R"(
596  Compute the (strongly) connected components of the specified graph.
597  Returns each connected component as a list of vertices in the netlist graph.
598 
599  :param graph_algorithm.NetlistGraph graph: The netlist graph.
600  :param bool strong: Set ``True`` to compute strongly connected components, ``False`` otherwise.
601  :param int min_size: Minimal size of a connected component to be part of the result. Set to ``0`` to include all components. Defaults to ``0``.
602  :returns: A list of strongly connected components on success, ``None`` otherwise.
603  :rtype: list[list[int]] or None
604  )");
605 
606  m.def(
607  "get_neighborhood",
608  [](graph_algorithm::NetlistGraph* graph, const std::vector<Gate*>& start_gates, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0)
609  -> std::optional<std::vector<std::vector<u32>>> {
610  auto res = graph_algorithm::get_neighborhood(graph, start_gates, order, direction, min_dist);
611  if (res.is_ok())
612  {
613  return res.get();
614  }
615  else
616  {
617  log_error("python_context", "error encountered while computing neighborhood:\n{}", res.get_error().get());
618  return std::nullopt;
619  }
620  },
621  py::arg("graph"),
622  py::arg("start_gates"),
623  py::arg("order"),
624  py::arg("direction"),
625  py::arg("min_dist") = 0,
626  R"(
627  Compute the neighborhood of the given order for each of the specified gates within the given netlist graph.
628  For order 0, only the vertex itself is returned. For order 1, the vertex itself and all vertices that are its direct predecessors and/or successors (depending on the specified direction). For order 2, the neighborhood of order 1 plus all direct predecessors and/or successors of the vertices in order 1 are returned, etc.
629  Returns each neighborhood as a list of vertices in the netlist graph.
630 
631  :param graph_algorithm.NetlistGraph graph: The netlist graph.
632  :param list[hal_py.Gate] start_gates: A list of gates for which to compute the neighborhood.
633  :param int order: The order of the neighborhood to compute.
634  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which the neighborhood should be computed.
635  :param int min_dist: The minimum distance of the vertices to include in the result.
636  :returns: A list of neighborhoods of each of the provided start gates (in order) on success, ``None`` otherwise.
637  :rtype: list[list[int]] or None
638  )");
639 
640  m.def(
641  "get_neighborhood",
642  [](graph_algorithm::NetlistGraph* graph, const std::vector<u32>& start_vertices, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0)
643  -> std::optional<std::vector<std::vector<u32>>> {
644  auto res = graph_algorithm::get_neighborhood(graph, start_vertices, order, direction, min_dist);
645  if (res.is_ok())
646  {
647  return res.get();
648  }
649  else
650  {
651  log_error("python_context", "error encountered while computing neighborhood:\n{}", res.get_error().get());
652  return std::nullopt;
653  }
654  },
655  py::arg("graph"),
656  py::arg("start_vertices"),
657  py::arg("order"),
658  py::arg("direction"),
659  py::arg("min_dist") = 0,
660  R"(
661  Compute the neighborhood of the given order for each of the specified vertices within the given netlist graph.
662  For order 0, only the vertex itself is returned. For order 1, the vertex itself and all vertices that are its direct predecessors and/or successors (depending on the specified direction). For order 2, the neighborhood of order 1 plus all direct predecessors and/or successors of the vertices in order 1 are returned, etc.
663  Returns each neighborhood as a list of vertices in the netlist graph.
664 
665  :param graph_algorithm.NetlistGraph graph: The netlist graph.
666  :param list[int] start_vertices: A list of vertices for which to compute the neighborhood.
667  :param int order: The order of the neighborhood to compute.
668  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which the neighborhood should be computed.
669  :param int min_dist: The minimum distance of the vertices to include in the result.
670  :returns: A list of neighborhoods of each of the provided start vertices (in order) on success, ``None`` otherwise.
671  :rtype: list[list[int]] or None
672  )");
673 
674  m.def(
675  "get_shortest_paths",
676  [](graph_algorithm::NetlistGraph* graph, Gate* from_gate, const std::vector<Gate*>& to_gates, graph_algorithm::NetlistGraph::Direction direction)
677  -> std::optional<std::vector<std::vector<u32>>> {
678  auto res = graph_algorithm::get_shortest_paths(graph, from_gate, to_gates, direction);
679  if (res.is_ok())
680  {
681  return res.get();
682  }
683  else
684  {
685  log_error("python_context", "error encountered while computing shortest paths:\n{}", res.get_error().get());
686  return std::nullopt;
687  }
688  },
689  py::arg("graph"),
690  py::arg("from_gate"),
691  py::arg("to_gates"),
692  py::arg("direction"),
693  R"(
694  Compute a shortest path from the specified ``from_gate`` to each of the given ``to_gates`` by traversing in the provided direction.
695  Returns one shortest path for each end gate, even if multiple shortest paths exist.
696  Each shortest path is given as a list of vertices in the order of traversal.
697 
698  :param graph_algorithm.NetlistGraph graph: The netlist graph.
699  :param hal_py.Gate from_gate: The start gate of the shortest path.
700  :param list[hal_py.Gate] to_gates: A list of end gates of the shortest path.
701  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_gate``.
702  :returns: The shortest paths in order of the ``to_gates`` on success, an error otherwise.
703  :rtype: list[list[int]] or None
704  )");
705 
706  m.def(
707  "get_shortest_paths",
708  [](graph_algorithm::NetlistGraph* graph, u32 from_vertice, const std::vector<u32>& to_vertices, graph_algorithm::NetlistGraph::Direction direction)
709  -> std::optional<std::vector<std::vector<u32>>> {
710  auto res = graph_algorithm::get_shortest_paths(graph, from_vertice, to_vertices, direction);
711  if (res.is_ok())
712  {
713  return res.get();
714  }
715  else
716  {
717  log_error("python_context", "error encountered while computing shortest paths:\n{}", res.get_error().get());
718  return std::nullopt;
719  }
720  },
721  py::arg("graph"),
722  py::arg("from_vertex"),
723  py::arg("to_vertices"),
724  py::arg("direction"),
725  R"(
726  Compute a shortest path from the specified ``from_vertex`` to each of the given ``to_vertices`` by traversing in the provided direction.
727  Returns one shortest path for each end vertex, even if multiple shortest paths exist.
728  Each shortest path is given as a list of vertices in the order of traversal.
729 
730  :param graph_algorithm.NetlistGraph graph: The netlist graph.
731  :param int from_vertex: The start vertex of the shortest path.
732  :param list[int] to_vertices: A list of end vertices of the shortest path.
733  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_vertex``.
734  :returns: The shortest paths in order of the ``to_vertices`` on success, an error otherwise.
735  :rtype: list[list[int]] or None
736  )");
737 
738  m.def(
739  "get_all_shortest_paths",
740  [](graph_algorithm::NetlistGraph* graph, Gate* from_gate, const std::vector<Gate*>& to_gates, graph_algorithm::NetlistGraph::Direction direction)
741  -> std::optional<std::vector<std::vector<u32>>> {
742  auto res = graph_algorithm::get_all_shortest_paths(graph, from_gate, to_gates, direction);
743  if (res.is_ok())
744  {
745  return res.get();
746  }
747  else
748  {
749  log_error("python_context", "error encountered while computing all shortest paths:\n{}", res.get_error().get());
750  return std::nullopt;
751  }
752  },
753  py::arg("graph"),
754  py::arg("from_gate"),
755  py::arg("to_gates"),
756  py::arg("direction"),
757  R"(
758  Compute shortest paths from the specified ``from_gate`` to each of the given ``to_gates`` by traversing in the provided direction.
759  Returns all shortest paths for each end gate.
760  Each shortest path is given as a list of vertices in the order of traversal.
761 
762  :param graph_algorithm.NetlistGraph graph: The netlist graph.
763  :param hal_py.Gate from_gate: The start gate of the shortest path.
764  :param list[hal_py.Gate] to_gates: A list of end gates of the shortest path.
765  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_gate``.
766  :returns: The shortest paths in order of the ``to_gates`` on success, an error otherwise.
767  :rtype: list[list[int]] or None
768  )");
769 
770  m.def(
771  "get_all_shortest_paths",
772  [](graph_algorithm::NetlistGraph* graph, u32 from_vertice, const std::vector<u32>& to_vertices, graph_algorithm::NetlistGraph::Direction direction)
773  -> std::optional<std::vector<std::vector<u32>>> {
774  auto res = graph_algorithm::get_all_shortest_paths(graph, from_vertice, to_vertices, direction);
775  if (res.is_ok())
776  {
777  return res.get();
778  }
779  else
780  {
781  log_error("python_context", "error encountered while computing all shortest paths:\n{}", res.get_error().get());
782  return std::nullopt;
783  }
784  },
785  py::arg("graph"),
786  py::arg("from_vertex"),
787  py::arg("to_vertices"),
788  py::arg("direction"),
789  R"(
790  Compute shortest paths from the specified ``from_vertex`` to each of the given ``to_vertices`` by traversing in the provided direction.
791  Returns all shortest paths for each end gate.
792  Each shortest path is given as a list of vertices in the order of traversal.
793 
794  :param graph_algorithm.NetlistGraph graph: The netlist graph.
795  :param int from_vertex: The start vertex of the shortest path.
796  :param list[int] to_vertices: A list of end vertices of the shortest path.
797  :param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_vertex``.
798  :returns: The shortest paths in order of the ``to_vertices`` on success, an error otherwise.
799  :rtype: list[list[int]] or None
800  )");
801 
802  m.def(
803  "get_subgraph",
804  [](const graph_algorithm::NetlistGraph* graph, const std::vector<Gate*>& subgraph_gates) -> std::optional<std::unique_ptr<graph_algorithm::NetlistGraph>> {
805  auto res = graph_algorithm::get_subgraph(graph, subgraph_gates);
806  if (res.is_ok())
807  {
808  return res.get();
809  }
810  else
811  {
812  log_error("python_context", "error encountered while computing subgraph:\n{}", res.get_error().get());
813  return std::nullopt;
814  }
815  },
816  py::arg("graph"),
817  py::arg("subgraph_gates"),
818  R"(
819  Compute the subgraph induced by the specified gates, including all edges between the corresponding vertices.
820 
821  :param graph_algorithm.NetlistGraph graph: The netlist graph.
822  :param list[hal_py.Gate] subgraph_gates: A list of gates that make up the subgraph.
823  :returns: The subgraph as a new netlist graph on success, ``None`` otherwise.
824  :rtype: graph_algorithm.NetlistGraph or None
825  )");
826 
827  m.def(
828  "get_subgraph",
829  [](const graph_algorithm::NetlistGraph* graph, const std::set<Gate*>& subgraph_gates) -> std::optional<std::unique_ptr<graph_algorithm::NetlistGraph>> {
830  auto res = graph_algorithm::get_subgraph(graph, subgraph_gates);
831  if (res.is_ok())
832  {
833  return res.get();
834  }
835  else
836  {
837  log_error("python_context", "error encountered while computing subgraph:\n{}", res.get_error().get());
838  return std::nullopt;
839  }
840  },
841  py::arg("graph"),
842  py::arg("subgraph_gates"),
843  R"(
844  Compute the subgraph induced by the specified gates, including all edges between the corresponding vertices.
845 
846  :param graph_algorithm.NetlistGraph graph: The netlist graph.
847  :param set[hal_py.Gate] subgraph_gates: A set of gates that make up the subgraph.
848  :returns: The subgraph as a new netlist graph on success, ``None`` otherwise.
849  :rtype: graph_algorithm.NetlistGraph or None
850  )");
851 
852  m.def(
853  "get_subgraph",
854  [](const graph_algorithm::NetlistGraph* graph, const std::vector<u32>& subgraph_vertices) -> std::optional<std::unique_ptr<graph_algorithm::NetlistGraph>> {
855  auto res = graph_algorithm::get_subgraph(graph, subgraph_vertices);
856  if (res.is_ok())
857  {
858  return res.get();
859  }
860  else
861  {
862  log_error("python_context", "error encountered while computing subgraph:\n{}", res.get_error().get());
863  return std::nullopt;
864  }
865  },
866  py::arg("graph"),
867  py::arg("subgraph_vertices"),
868  R"(
869  Compute the subgraph induced by the specified vertices, including all edges between these vertices.
870 
871  :param graph_algorithm.NetlistGraph graph: The netlist graph.
872  :param list[int] subgraph_vertices: A list of vertices that make up the subgraph.
873  :returns: The subgraph as a new netlist graph on success, ``None`` otherwise.
874  :rtype: graph_algorithm.NetlistGraph or None
875  )");
876 
877  m.def(
878  "get_subgraph",
879  [](const graph_algorithm::NetlistGraph* graph, const std::set<u32>& subgraph_vertices) -> std::optional<std::unique_ptr<graph_algorithm::NetlistGraph>> {
880  auto res = graph_algorithm::get_subgraph(graph, subgraph_vertices);
881  if (res.is_ok())
882  {
883  return res.get();
884  }
885  else
886  {
887  log_error("python_context", "error encountered while computing subgraph:\n{}", res.get_error().get());
888  return std::nullopt;
889  }
890  },
891  py::arg("graph"),
892  py::arg("subgraph_vertices"),
893  R"(
894  Compute the subgraph induced by the specified vertices, including all edges between these vertices.
895 
896  :param graph_algorithm.NetlistGraph graph: The netlist graph.
897  :param set[int] subgraph_vertices: A set of vertices that make up the subgraph.
898  :returns: The subgraph as a new netlist graph on success, ``None`` otherwise.
899  :rtype: graph_algorithm.NetlistGraph or None
900  )");
901 
902 #ifndef PYBIND11_MODULE
903  return m.ptr();
904 #endif // PYBIND11_MODULE
905  }
906 } // namespace hal
Definition: gate.h:58
std::string get_description() const override
Get a short description of the plugin.
std::string get_version() const override
Get the version of the plugin.
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
std::string get_name() const override
Get the name of the plugin.
Definition: net.h:58
A directed graph corresponding to a netlist.
Definition: netlist_graph.h:57
Netlist * get_netlist() const
Get the netlist associated with the netlist graph.
u32 get_num_vertices(bool only_connected=false) const
Get the number of vertices in the netlist graph.
static Result< std::unique_ptr< NetlistGraph > > from_netlist(Netlist *nl, bool create_dummy_vertices=false, const std::function< bool(const Net *)> &filter=nullptr)
Create a directed graph from a netlist.
Direction
The direction of exploration within the graph.
Definition: netlist_graph.h:64
@ ALL
Explore in both directions, i.e., treat the graph as undirected.
@ NONE
No direction, invalid default setting.
@ IN
Explore through the inputs of the current node, i.e., traverse backwards.
@ OUT
Explore through the outputs of the current node, i.e., traverse forwards.
void print() const
Print the edge list of the graph to stdout.
u32 get_num_edges() const
Get the number of edges in the netlist graph.
static Result< std::unique_ptr< NetlistGraph > > from_netlist_no_edges(Netlist *nl, const std::vector< Gate * > &gates={})
Create an empty directed graph from a netlist.
This file contains functions related to graph components.
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< std::vector< std::vector< u32 > > > get_all_shortest_paths(NetlistGraph *graph, Gate *from_gate, const std::vector< Gate * > &to_gates, NetlistGraph::Direction direction)
Compute shortest paths from the specified from_gate to each of the given to_gates by traversing in th...
Result< std::vector< std::vector< u32 > > > get_connected_components(const NetlistGraph *graph, bool strong, u32 min_size=0)
Compute the (strongly) connected components of the specified graph.
Definition: components.cpp:11
Result< std::vector< std::vector< u32 > > > get_shortest_paths(NetlistGraph *graph, Gate *from_gate, const std::vector< Gate * > &to_gates, NetlistGraph::Direction direction)
Compute a shortest path from the specified from_gate to each of the given to_gates by traversing in t...
Result< std::unique_ptr< NetlistGraph > > get_subgraph(const NetlistGraph *graph, const std::vector< Gate * > &subgraph_gates)
Compute the subgraph induced by the specified gates, including all edges between the corresponding ve...
Definition: subgraph.cpp:10
Result< std::vector< std::vector< u32 > > > get_neighborhood(NetlistGraph *graph, const std::vector< Gate * > &start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist=0)
Compute the neighborhood of the given order for each of the specified gates within the given netlist ...
Definition: neighborhood.cpp:9
PYBIND11_PLUGIN(hal_py)
This file contains functions related to neighborhoods in graphs.
quint32 u32
PinDirection direction
This file contains the class that holds a netlist graph.
This file contains all functions related to the HAL plugin API.
This file contains functions related to shortest paths in graphs.
This file contains functions related to subgraphs.