Skip to content

Commit

Permalink
added computation of shortest paths
Browse files Browse the repository at this point in the history
  • Loading branch information
SJulianS committed May 8, 2024
1 parent 0d30bfd commit 7f5a198
Show file tree
Hide file tree
Showing 3 changed files with 552 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// MIT License
//
// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#include "graph_algorithm/netlist_graph.h"
#include "hal_core/defines.h"
#include "hal_core/utilities/result.h"

#include <igraph/igraph.h>
#include <set>

namespace hal
{
class Gate;

namespace graph_algorithm
{
/**
* Compute a shortest path from the specified `from_gate` to each of the given `to_gates` by traversing in the provided direction.
* Returns one shortest path for each end gate, even if multiple shortest paths exist.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start gate of the shortest path.
* @param[in] to_gates - A vector of end gates of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_gate`.
* @returns The shortest paths in order of the `to_gates` on success, an error otherwise.
*/
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_vertex` to each of the given `to_vertices` by traversing in the provided direction.
* Returns one shortest path for each end vertex, even if multiple shortest paths exist.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start vertex of the shortest path.
* @param[in] to_gates - A vector of end vertices of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_vertex`.
* @returns The shortest paths in order of the `to_vertices` on success, an error otherwise.
*/
Result<std::vector<std::vector<u32>>> get_shortest_paths(NetlistGraph* graph, u32 from_vertex, const std::vector<u32>& to_vertices, NetlistGraph::Direction direction);

/**
* Compute a shortest path from the specified `from_vertex` to each of the given `to_vertices` by traversing in the provided direction.
* Returns one shortest path for each end vertex, even if multiple shortest paths exist.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start vertex of the shortest path.
* @param[in] to_gates - An igraph vector of end vertices of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_vertex`.
* @returns The shortest paths in order of the `to_vertices` on success, an error otherwise.
*/
Result<std::vector<std::vector<u32>>> get_shortest_paths_igraph(NetlistGraph* graph, u32 from_vertex, const igraph_vector_int_t* to_vertices, NetlistGraph::Direction direction);

/**
* Compute a shortest path from the specified `from_gate` to each of the given `to_gates` by traversing in the provided direction.
* Returns all shortest paths for each end gate.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start gate of the shortest path.
* @param[in] to_gates - A vector of end gates of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_gate`.
* @returns The shortest paths in order of the `to_gates` on success, an error otherwise.
*/
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 a shortest path from the specified `from_vertex` to each of the given `to_vertices` by traversing in the provided direction.
* Returns all shortest paths for each end gate.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start vertex of the shortest path.
* @param[in] to_gates - A vector of end vertices of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_vertex`.
* @returns The shortest paths in order of the `to_vertices` on success, an error otherwise.
*/
Result<std::vector<std::vector<u32>>> get_all_shortest_paths(NetlistGraph* graph, u32 from_vertex, const std::vector<u32>& to_vertices, NetlistGraph::Direction direction);

/**
* Compute a shortest path from the specified `from_vertex` to each of the given `to_vertices` by traversing in the provided direction.
* Returns all shortest paths for each end gate.
* Each shortest path is given as a vector of vertices in the order of traversal.
*
* @param[in] graph - The netlist graph.
* @param[in] from_gate - The start vertex of the shortest path.
* @param[in] to_gates - An igraph vector of end vertices of the shortest path.
* @param[in] direction - The direction in which to compute the shortest paths starting at the `from_vertex`.
* @returns The shortest paths in order of the `to_vertices` on success, an error otherwise.
*/
Result<std::vector<std::vector<u32>>> get_all_shortest_paths_igraph(NetlistGraph* graph, u32 from_vertex, const igraph_vector_int_t* to_vertices, NetlistGraph::Direction direction);
} // namespace graph_algorithm
} // namespace hal
129 changes: 129 additions & 0 deletions plugins/graph_algorithm/python/python_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "graph_algorithm/algorithms/components.h"
#include "graph_algorithm/algorithms/neighborhood.h"
#include "graph_algorithm/algorithms/shortest_path.h"
#include "graph_algorithm/algorithms/subgraph.h"
#include "graph_algorithm/netlist_graph.h"
#include "graph_algorithm/plugin_graph_algorithm.h"
Expand Down Expand Up @@ -551,6 +552,134 @@ namespace hal
:rtype: list[list[int]] or None
)");

m.def(
"get_shortest_paths",
[](graph_algorithm::NetlistGraph* graph, Gate* from_gate, const std::vector<Gate*>& to_gates, graph_algorithm::NetlistGraph::Direction direction)
-> std::optional<std::vector<std::vector<u32>>> {
auto res = graph_algorithm::get_shortest_paths(graph, from_gate, to_gates, direction);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while computing shortest paths:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("graph"),
py::arg("from_gate"),
py::arg("to_gates"),
py::arg("direction"),
R"(
Compute a shortest path from the specified ``from_gate`` to each of the given ``to_gates`` by traversing in the provided direction.
Returns one shortest path for each end gate, even if multiple shortest paths exist.
Each shortest path is given as a list of vertices in the order of traversal.
:param graph_algorithm.NetlistGraph graph: The netlist graph.
:param hal_py.Gate from_gate: The start gate of the shortest path.
:param list[hal_py.Gate] to_gates: A list of end gates of the shortest path.
:param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_gate``.
:returns: The shortest paths in order of the ``to_gates`` on success, an error otherwise.
:rtype: list[list[int]] or None
)");

m.def(
"get_shortest_paths",
[](graph_algorithm::NetlistGraph* graph, u32 from_vertice, const std::vector<u32>& to_vertices, graph_algorithm::NetlistGraph::Direction direction)
-> std::optional<std::vector<std::vector<u32>>> {
auto res = graph_algorithm::get_shortest_paths(graph, from_vertice, to_vertices, direction);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while computing shortest paths:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("graph"),
py::arg("from_vertex"),
py::arg("to_vertices"),
py::arg("direction"),
R"(
Compute a shortest path from the specified ``from_vertex`` to each of the given ``to_vertices`` by traversing in the provided direction.
Returns one shortest path for each end vertex, even if multiple shortest paths exist.
Each shortest path is given as a list of vertices in the order of traversal.
:param graph_algorithm.NetlistGraph graph: The netlist graph.
:param int from_vertex: The start vertex of the shortest path.
:param list[int] to_vertices: A list of end vertices of the shortest path.
:param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_vertex``.
:returns: The shortest paths in order of the ``to_vertices`` on success, an error otherwise.
:rtype: list[list[int]] or None
)");

m.def(
"get_all_shortest_paths",
[](graph_algorithm::NetlistGraph* graph, Gate* from_gate, const std::vector<Gate*>& to_gates, graph_algorithm::NetlistGraph::Direction direction)
-> std::optional<std::vector<std::vector<u32>>> {
auto res = graph_algorithm::get_all_shortest_paths(graph, from_gate, to_gates, direction);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while computing all shortest paths:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("graph"),
py::arg("from_gate"),
py::arg("to_gates"),
py::arg("direction"),
R"(
Compute a shortest path from the specified ``from_gate`` to each of the given ``to_gates`` by traversing in the provided direction.
Returns all shortest paths for each end gate.
Each shortest path is given as a list of vertices in the order of traversal.
:param graph_algorithm.NetlistGraph graph: The netlist graph.
:param hal_py.Gate from_gate: The start gate of the shortest path.
:param list[hal_py.Gate] to_gates: A list of end gates of the shortest path.
:param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_gate``.
:returns: The shortest paths in order of the ``to_gates`` on success, an error otherwise.
:rtype: list[list[int]] or None
)");

m.def(
"get_all_shortest_paths",
[](graph_algorithm::NetlistGraph* graph, u32 from_vertice, const std::vector<u32>& to_vertices, graph_algorithm::NetlistGraph::Direction direction)
-> std::optional<std::vector<std::vector<u32>>> {
auto res = graph_algorithm::get_all_shortest_paths(graph, from_vertice, to_vertices, direction);
if (res.is_ok())
{
return res.get();
}
else
{
log_error("python_context", "error encountered while computing all shortest paths:\n{}", res.get_error().get());
return std::nullopt;
}
},
py::arg("graph"),
py::arg("from_vertex"),
py::arg("to_vertices"),
py::arg("direction"),
R"(
Compute a shortest path from the specified ``from_vertex`` to each of the given ``to_vertices`` by traversing in the provided direction.
Returns all shortest paths for each end gate.
Each shortest path is given as a list of vertices in the order of traversal.
:param graph_algorithm.NetlistGraph graph: The netlist graph.
:param int from_vertex: The start vertex of the shortest path.
:param list[int] to_vertices: A list of end vertices of the shortest path.
:param graph_algorithm.NetlistGraph.Direction direction: The direction in which to compute the shortest paths starting at the ``from_vertex``.
:returns: The shortest paths in order of the ``to_vertices`` on success, an error otherwise.
:rtype: list[list[int]] or None
)");

m.def(
"get_subgraph",
[](graph_algorithm::NetlistGraph* graph, const std::vector<Gate*>& subgraph_gates) -> std::optional<std::unique_ptr<graph_algorithm::NetlistGraph>> {
Expand Down
Loading

0 comments on commit 7f5a198

Please sign in to comment.