diff --git a/plugins/graph_algorithm/include/graph_algorithm/algorithms/neighborhood.h b/plugins/graph_algorithm/include/graph_algorithm/algorithms/neighborhood.h index 1b0466be180..f0ae8d381a5 100644 --- a/plugins/graph_algorithm/include/graph_algorithm/algorithms/neighborhood.h +++ b/plugins/graph_algorithm/include/graph_algorithm/algorithms/neighborhood.h @@ -44,13 +44,13 @@ namespace hal * Returns each neighborhood as a vector of vertices in the netlist graph. * * @param[in] graph - The netlist graph. - * @param[in] start_gates - The gates for which to compute the neighborhood. + * @param[in] start_gates - A vector of gates for which to compute the neighborhood. * @param[in] order - The order of the neighborhood to compute. * @param[in] direction - The direction in which the neighborhood should be computed. * @param[in] min_dist - The minimum distance of the vertices to include in the result. * @returns A vector of neighborhoods of each of the provided start gates (in order) on success, an error otherwise. */ - Result>> get_neighborhood(NetlistGraph* graph, std::vector start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist = 0); + Result>> get_neighborhood(NetlistGraph* graph, const std::vector& start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist = 0); /** * Compute the neighborhood of the given order for each of the specified vertices within the given netlist graph. @@ -58,12 +58,26 @@ namespace hal * Returns each neighborhood as a vector of vertices in the netlist graph. * * @param[in] graph - The netlist graph. - * @param[in] start_vertices - The vertices for which to compute the neighborhood. + * @param[in] start_vertices - A vector of vertices for which to compute the neighborhood. * @param[in] order - The order of the neighborhood to compute. * @param[in] direction - The direction in which the neighborhood should be computed. * @param[in] min_dist - The minimum distance of the vertices to include in the result. * @returns A vector of neighborhoods of each of the provided start vertices (in order) on success, an error otherwise. */ - Result>> get_neighborhood(NetlistGraph* graph, std::vector start_vertices, u32 order, NetlistGraph::Direction direction, u32 min_dist = 0); + Result>> get_neighborhood(NetlistGraph* graph, const std::vector& start_vertices, u32 order, NetlistGraph::Direction direction, u32 min_dist = 0); + + /** + * Compute the neighborhood of the given order for each of the specified vertices within the given netlist graph. + * 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. + * Returns each neighborhood as a vector of vertices in the netlist graph. + * + * @param[in] graph - The netlist graph. + * @param[in] start_vertices - An igraph vector of vertices for which to compute the neighborhood. + * @param[in] order - The order of the neighborhood to compute. + * @param[in] direction - The direction in which the neighborhood should be computed. + * @param[in] min_dist - The minimum distance of the vertices to include in the result. + * @returns A vector of neighborhoods of each of the provided start vertices (in order) on success, an error otherwise. + */ + Result>> get_neighborhood_igraph(NetlistGraph* graph, const igraph_vector_int_t* start_vertices, u32 order, NetlistGraph::Direction direction, u32 min_dist = 0); } // namespace graph_algorithm } // namespace hal \ No newline at end of file diff --git a/plugins/graph_algorithm/python/python_bindings.cpp b/plugins/graph_algorithm/python/python_bindings.cpp index b4c7a538496..0fd1cfcbf2a 100644 --- a/plugins/graph_algorithm/python/python_bindings.cpp +++ b/plugins/graph_algorithm/python/python_bindings.cpp @@ -461,7 +461,7 @@ namespace hal m.def( "get_neighborhood", - [](graph_algorithm::NetlistGraph* graph, std::vector start_gates, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0) + [](graph_algorithm::NetlistGraph* graph, const std::vector& start_gates, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0) -> std::optional>> { auto res = graph_algorithm::get_neighborhood(graph, start_gates, order, direction, min_dist); if (res.is_ok()) @@ -485,7 +485,7 @@ namespace hal Returns each neighborhood as a list of vertices in the netlist graph. :param graph_algorithm.NetlistGraph graph: The netlist graph. - :param list[hal_py.Gate] start_gates: The gates for which to compute the neighborhood. + :param list[hal_py.Gate] start_gates: A list of gates for which to compute the neighborhood. :param int order: The order of the neighborhood to compute. :param graph_algorithm.NetlistGraph.Direction direction: The direction in which the neighborhood should be computed. :param int min_dist: The minimum distance of the vertices to include in the result. @@ -495,7 +495,7 @@ namespace hal m.def( "get_neighborhood", - [](graph_algorithm::NetlistGraph* graph, std::vector start_vertices, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0) + [](graph_algorithm::NetlistGraph* graph, const std::vector& start_vertices, u32 order, graph_algorithm::NetlistGraph::Direction direction, u32 min_dist = 0) -> std::optional>> { auto res = graph_algorithm::get_neighborhood(graph, start_vertices, order, direction, min_dist); if (res.is_ok()) @@ -519,7 +519,7 @@ namespace hal Returns each neighborhood as a list of vertices in the netlist graph. :param graph_algorithm.NetlistGraph graph: The netlist graph. - :param list[int] start_vertices: The vertices for which to compute the neighborhood. + :param list[int] start_vertices: A list of vertices for which to compute the neighborhood. :param int order: The order of the neighborhood to compute. :param graph_algorithm.NetlistGraph.Direction direction: The direction in which the neighborhood should be computed. :param int min_dist: The minimum distance of the vertices to include in the result. diff --git a/plugins/graph_algorithm/src/algorithms/neighborhood.cpp b/plugins/graph_algorithm/src/algorithms/neighborhood.cpp index 8d72ff80a57..11235061d57 100644 --- a/plugins/graph_algorithm/src/algorithms/neighborhood.cpp +++ b/plugins/graph_algorithm/src/algorithms/neighborhood.cpp @@ -6,7 +6,7 @@ namespace hal namespace graph_algorithm { - Result>> get_neighborhood(NetlistGraph* graph, std::vector start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist) + Result>> get_neighborhood(NetlistGraph* graph, const std::vector& start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist) { if (!graph) { @@ -18,23 +18,29 @@ namespace hal return ERR("no start gates provided"); } - std::vector start_vertices; - for (auto* g : start_gates) + igraph_vector_int_t i_gates; + if (auto res = graph->get_vertices_from_gates_igraph(start_gates); res.is_ok()) { - if (const auto res = graph->get_vertex_from_gate(g); res.is_ok()) - { - start_vertices.push_back(res.get()); - } - else - { - return ERR(res.get_error()); - } + i_gates = std::move(res.get()); + } + else + { + return ERR(res.get_error()); } - return get_neighborhood(graph, start_vertices, order, direction, min_dist); + auto res = get_neighborhood_igraph(graph, &i_gates, order, direction, min_dist); + + igraph_vector_int_destroy(&i_gates); + + if (res.is_error()) + { + return ERR(res.get_error()); + } + + return res; } - Result>> get_neighborhood(NetlistGraph* graph, std::vector start_vertices, u32 order, NetlistGraph::Direction direction, u32 min_dist) + Result>> get_neighborhood(NetlistGraph* graph, const std::vector& start_vertices, u32 order, NetlistGraph::Direction direction, u32 min_dist) { if (!graph) { @@ -46,28 +52,39 @@ namespace hal return ERR("no start vertices provided"); } - u32 num_vertices = igraph_vcount(graph->get_graph()); - if (std::any_of(start_vertices.begin(), start_vertices.end(), [num_vertices](const u32 v) { return v >= num_vertices; })) + igraph_vector_int_t i_gates; + if (auto res = igraph_vector_int_init(&i_gates, start_vertices.size()); res != IGRAPH_SUCCESS) { - return ERR("invalid vertex contained in start vertices"); + return ERR(igraph_strerror(res)); } - igraph_vector_int_t v_vec; - if (auto res = igraph_vector_int_init(&v_vec, start_vertices.size()); res != IGRAPH_SUCCESS) + for (u32 i = 0; i < start_vertices.size(); i++) { - return ERR(igraph_strerror(res)); + VECTOR(i_gates)[i] = start_vertices.at(i); } - u32 v_count = 0; - for (const auto v : start_vertices) + auto res = get_neighborhood_igraph(graph, &i_gates, order, direction, min_dist); + + igraph_vector_int_destroy(&i_gates); + + if (res.is_error()) { - VECTOR(v_vec)[v_count++] = v; + return ERR(res.get_error()); + } + + return res; + } + + Result>> get_neighborhood_igraph(NetlistGraph* graph, const igraph_vector_int_t* start_gates, u32 order, NetlistGraph::Direction direction, u32 min_dist) + { + if (!graph) + { + return ERR("graph is a nullptr"); } igraph_vs_t v_sel; - if (auto res = igraph_vs_vector(&v_sel, &v_vec); res != IGRAPH_SUCCESS) + if (auto res = igraph_vs_vector(&v_sel, start_gates); res != IGRAPH_SUCCESS) { - igraph_vector_int_destroy(&v_vec); return ERR(igraph_strerror(res)); } @@ -85,7 +102,6 @@ namespace hal break; case NetlistGraph::Direction::NONE: igraph_vs_destroy(&v_sel); - igraph_vector_int_destroy(&v_vec); return ERR("invalid direction 'NONE'"); } @@ -93,14 +109,12 @@ namespace hal if (auto res = igraph_vector_int_list_init(&neighborhoods_raw, 1); res != IGRAPH_SUCCESS) { igraph_vs_destroy(&v_sel); - igraph_vector_int_destroy(&v_vec); return ERR(igraph_strerror(res)); } if (auto res = igraph_neighborhood(graph->get_graph(), &neighborhoods_raw, v_sel, order, mode, min_dist); res != IGRAPH_SUCCESS) { igraph_vs_destroy(&v_sel); - igraph_vector_int_destroy(&v_vec); igraph_vector_int_list_destroy(&neighborhoods_raw); return ERR(igraph_strerror(res)); } @@ -120,7 +134,6 @@ namespace hal } igraph_vs_destroy(&v_sel); - igraph_vector_int_destroy(&v_vec); igraph_vector_int_list_destroy(&neighborhoods_raw); return OK(neighborhoods);