From 0d30bfd6d4eb9bcddbe25fe956d3f5f812cce187 Mon Sep 17 00:00:00 2001 From: "julian.speith" Date: Wed, 8 May 2024 14:36:22 +0200 Subject: [PATCH] added function to get all (used) vertices --- .../include/graph_algorithm/netlist_graph.h | 8 +++ .../python/python_bindings.cpp | 23 ++++++++ plugins/graph_algorithm/src/netlist_graph.cpp | 52 +++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/plugins/graph_algorithm/include/graph_algorithm/netlist_graph.h b/plugins/graph_algorithm/include/graph_algorithm/netlist_graph.h index eaa5bb58917..7878641fe10 100644 --- a/plugins/graph_algorithm/include/graph_algorithm/netlist_graph.h +++ b/plugins/graph_algorithm/include/graph_algorithm/netlist_graph.h @@ -174,6 +174,14 @@ namespace hal */ u32 get_num_edges() const; + /** + * Get the vertices in the netlist graph. + * + * @param[in] only_connected - Set `true` to only return vertices connected to at least one edge, `false` otherwise. Defaults to `false`. + * @returns A vector of vertices on success, an error otherwise. + */ + Result> get_vertices(bool only_connected = false) const; + /** * Get the edges between vertices in the netlist graph. * diff --git a/plugins/graph_algorithm/python/python_bindings.cpp b/plugins/graph_algorithm/python/python_bindings.cpp index 57a51634b9a..4bcde4dec51 100644 --- a/plugins/graph_algorithm/python/python_bindings.cpp +++ b/plugins/graph_algorithm/python/python_bindings.cpp @@ -292,6 +292,29 @@ namespace hal :rtype: int )"); + py_netlist_graph.def( + "get_vertices", + [](const graph_algorithm::NetlistGraph& self, bool only_connected = false) -> std::optional> { + auto res = self.get_vertices(only_connected); + if (res.is_ok()) + { + return res.get(); + } + else + { + log_error("python_context", "error encountered while getting vertices:\n{}", res.get_error().get()); + return std::nullopt; + } + }, + py::arg("only_connected") = false, + R"( + Get the vertices in the netlist graph. + + :param bool only_connected: Set ``True`` to only return vertices connected to at least one edge, ``False`` otherwise. Defaults to ``False``. + :returns: A list of vertices on success, ``None`` otherwise. + :rtype: list[int] or None + )"); + py_netlist_graph.def( "get_edges", [](const graph_algorithm::NetlistGraph& self) -> std::optional>> { diff --git a/plugins/graph_algorithm/src/netlist_graph.cpp b/plugins/graph_algorithm/src/netlist_graph.cpp index fefd434d9b4..b157f4abf9d 100644 --- a/plugins/graph_algorithm/src/netlist_graph.cpp +++ b/plugins/graph_algorithm/src/netlist_graph.cpp @@ -396,6 +396,58 @@ namespace hal return igraph_ecount(&m_graph); } + Result> NetlistGraph::get_vertices(bool only_connected) const + { + u32 num_vertices = igraph_vcount(&m_graph); + + if (!only_connected) + { + std::vector vertices(num_vertices); + for (u32 i = 0; i < num_vertices; i++) + { + vertices[i] = i; + } + return OK(vertices); + } + else + { + std::vector vertices; + + igraph_vector_int_t degrees; + if (auto res = igraph_vector_int_init(°rees, num_vertices); res != IGRAPH_SUCCESS) + { + return ERR(igraph_strerror(res)); + } + + igraph_vs_t v_sel; + if (auto res = igraph_vs_all(&v_sel); res != IGRAPH_SUCCESS) + { + igraph_vector_int_destroy(°rees); + return ERR(igraph_strerror(res)); + } + + if (auto res = igraph_degree(&m_graph, °rees, v_sel, IGRAPH_ALL, IGRAPH_LOOPS); res != IGRAPH_SUCCESS) + { + igraph_vs_destroy(&v_sel); + igraph_vector_int_destroy(°rees); + return ERR(igraph_strerror(res)); + } + + for (u32 i = 0; i < num_vertices; i++) + { + if (VECTOR(degrees)[i] != 0) + { + vertices.push_back(i); + } + } + + igraph_vector_int_destroy(°rees); + igraph_vs_destroy(&v_sel); + + return OK(vertices); + } + } + Result>> NetlistGraph::get_edges() const { const u32 ecount = igraph_ecount(&m_graph);