HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
shortest_path.cpp
Go to the documentation of this file.
2 
5 
6 namespace hal
7 {
8  namespace graph_algorithm
9  {
11  {
12  if (graph == nullptr)
13  {
14  return ERR("graph is a nullptr");
15  }
16 
17  if (!from_gate)
18  {
19  return ERR("no source gate provided");
20  }
21 
22  if (to_gates.empty())
23  {
24  return ERR("no destination gates provided");
25  }
26 
27  u32 from_vertex;
28  if (auto res = graph->get_vertex_from_gate(from_gate); res.is_ok())
29  {
30  from_vertex = res.get();
31  }
32  else
33  {
34  return ERR(res.get_error());
35  }
36 
37  igraph_vector_int_t i_to_vertices;
38  if (auto res = graph->get_vertices_from_gates_igraph(to_gates); res.is_ok())
39  {
40  i_to_vertices = std::move(res.get());
41  }
42  else
43  {
44  return ERR(res.get_error());
45  }
46 
47  auto res = get_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
48 
49  igraph_vector_int_destroy(&i_to_vertices);
50 
51  if (res.is_error())
52  {
53  return ERR(res.get_error());
54  }
55 
56  return res;
57  }
58 
59  Result<std::vector<std::vector<u32>>> get_shortest_paths(NetlistGraph* graph, u32 from_vertex, const std::vector<u32>& to_vertices, NetlistGraph::Direction direction)
60  {
61  if (graph == nullptr)
62  {
63  return ERR("graph is a nullptr");
64  }
65 
66  if (to_vertices.empty())
67  {
68  return ERR("no destination vertices provided");
69  }
70 
71  igraph_vector_int_t i_to_vertices;
72  if (auto res = igraph_vector_int_init(&i_to_vertices, to_vertices.size()); res != IGRAPH_SUCCESS)
73  {
74  return ERR(igraph_strerror(res));
75  }
76 
77  for (u32 i = 0; i < to_vertices.size(); i++)
78  {
79  VECTOR(i_to_vertices)[i] = to_vertices.at(i);
80  }
81 
82  auto res = get_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
83 
84  igraph_vector_int_destroy(&i_to_vertices);
85 
86  if (res.is_error())
87  {
88  return ERR(res.get_error());
89  }
90 
91  return res;
92  }
93 
95  {
96  if (graph == nullptr)
97  {
98  return ERR("graph is a nullptr");
99  }
100 
101  igraph_neimode_t mode;
102  switch (direction)
103  {
105  mode = IGRAPH_IN;
106  break;
108  mode = IGRAPH_OUT;
109  break;
111  mode = IGRAPH_ALL;
112  break;
114  return ERR("invalid direction 'NONE'");
115  }
116 
117  igraph_vs_t v_sel = igraph_vss_vector(to_vertices);
118  igraph_vector_int_list_t paths_raw;
119  if (auto res = igraph_vector_int_list_init(&paths_raw, 1); res != IGRAPH_SUCCESS)
120  {
121  igraph_vs_destroy(&v_sel);
122  return ERR(igraph_strerror(res));
123  }
124 
125  // a `nullptr` weight vector makes igraph treat all edges as having unit weight
126  if (auto res = igraph_get_shortest_paths(graph->get_graph(), nullptr, &paths_raw, nullptr, from_vertex, v_sel, mode, nullptr, nullptr); res != IGRAPH_SUCCESS)
127  {
128  igraph_vs_destroy(&v_sel);
129  igraph_vector_int_list_destroy(&paths_raw);
130  return ERR(igraph_strerror(res));
131  }
132 
133  std::vector<std::vector<u32>> paths;
134  for (u32 i = 0; i < igraph_vector_int_list_size(&paths_raw); i++)
135  {
136  auto vec = igraph_vector_int_list_get_ptr(&paths_raw, i);
137 
138  u32 vec_size = igraph_vector_int_size(vec);
139  std::vector<u32> tmp(vec_size);
140  for (u32 j = 0; j < igraph_vector_int_size(vec); j++)
141  {
142  tmp[j] = VECTOR(*vec)[j];
143  }
144  paths.push_back(std::move(tmp));
145  }
146 
147  igraph_vs_destroy(&v_sel);
148  igraph_vector_int_list_destroy(&paths_raw);
149 
150  return OK(paths);
151  }
152 
154  {
155  if (graph == nullptr)
156  {
157  return ERR("graph is a nullptr");
158  }
159 
160  if (!from_gate)
161  {
162  return ERR("no source gate provided");
163  }
164 
165  if (to_gates.empty())
166  {
167  return ERR("no destination gates provided");
168  }
169 
170  u32 from_vertex;
171  if (auto res = graph->get_vertex_from_gate(from_gate); res.is_ok())
172  {
173  from_vertex = res.get();
174  }
175  else
176  {
177  return ERR(res.get_error());
178  }
179 
180  igraph_vector_int_t i_to_vertices;
181  if (auto res = graph->get_vertices_from_gates_igraph(to_gates); res.is_ok())
182  {
183  i_to_vertices = std::move(res.get());
184  }
185  else
186  {
187  return ERR(res.get_error());
188  }
189 
190  auto res = get_all_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
191 
192  igraph_vector_int_destroy(&i_to_vertices);
193 
194  if (res.is_error())
195  {
196  return ERR(res.get_error());
197  }
198 
199  return res;
200  }
201 
203  {
204  if (graph == nullptr)
205  {
206  return ERR("graph is a nullptr");
207  }
208 
209  if (to_vertices.empty())
210  {
211  return ERR("no destination vertices provided");
212  }
213 
214  igraph_vector_int_t i_to_vertices;
215  if (auto res = igraph_vector_int_init(&i_to_vertices, to_vertices.size()); res != IGRAPH_SUCCESS)
216  {
217  return ERR(igraph_strerror(res));
218  }
219 
220  for (u32 i = 0; i < to_vertices.size(); i++)
221  {
222  VECTOR(i_to_vertices)[i] = to_vertices.at(i);
223  }
224 
225  auto res = get_all_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
226 
227  igraph_vector_int_destroy(&i_to_vertices);
228 
229  if (res.is_error())
230  {
231  return ERR(res.get_error());
232  }
233 
234  return res;
235  }
236 
238  {
239  if (graph == nullptr)
240  {
241  return ERR("graph is a nullptr");
242  }
243 
244  igraph_neimode_t mode;
245  switch (direction)
246  {
248  mode = IGRAPH_IN;
249  break;
251  mode = IGRAPH_OUT;
252  break;
254  mode = IGRAPH_ALL;
255  break;
257  return ERR("invalid direction 'NONE'");
258  }
259 
260  igraph_vs_t v_sel = igraph_vss_vector(to_vertices);
261  igraph_vector_int_list_t paths_raw;
262  if (auto res = igraph_vector_int_list_init(&paths_raw, 1); res != IGRAPH_SUCCESS)
263  {
264  igraph_vs_destroy(&v_sel);
265  return ERR(igraph_strerror(res));
266  }
267 
268  // a `nullptr` weight vector makes igraph treat all edges as having unit weight
269  if (auto res = igraph_get_all_shortest_paths(graph->get_graph(), nullptr, &paths_raw, nullptr, nullptr, from_vertex, v_sel, mode); res != IGRAPH_SUCCESS)
270  {
271  igraph_vs_destroy(&v_sel);
272  igraph_vector_int_list_destroy(&paths_raw);
273  return ERR(igraph_strerror(res));
274  }
275 
276  std::vector<std::vector<u32>> paths;
277  const u32 paths_size = igraph_vector_int_list_size(&paths_raw);
278  for (u32 i = 0; i < paths_size; i++)
279  {
280  auto vec = igraph_vector_int_list_get_ptr(&paths_raw, i);
281 
282  const u32 vec_size = igraph_vector_int_size(vec);
283  std::vector<u32> tmp(vec_size);
284  for (u32 j = 0; j < vec_size; j++)
285  {
286  tmp[j] = VECTOR(*vec)[j];
287  }
288  paths.push_back(std::move(tmp));
289  }
290 
291  igraph_vs_destroy(&v_sel);
292  igraph_vector_int_list_destroy(&paths_raw);
293 
294  return OK(paths);
295  }
296  } // namespace graph_algorithm
297 } // namespace hal
Definition: gate.h:58
A directed graph corresponding to a netlist.
Definition: netlist_graph.h:60
Direction
The direction of exploration within the graph.
Definition: netlist_graph.h:67
@ 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.
Result< u32 > get_vertex_from_gate(Gate *g) const
Get the vertex corresponding to the specified gate.
Result< igraph_vector_int_t > get_vertices_from_gates_igraph(const std::vector< Gate * > &gates) const
Get the vertices corresponding to the specified gates.
igraph_t * get_graph() const
Get the graph object of the netlist graph.
uint32_t u32
Definition: defines.h:41
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
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_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::vector< std::vector< u32 > > > get_all_shortest_paths_igraph(NetlistGraph *graph, u32 from_vertex, const igraph_vector_int_t *to_vertices, NetlistGraph::Direction direction)
Compute shortest paths from the specified from_vertex to each of the given to_vertices by traversing ...
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_vertex to each of the given to_vertices by traversing...
Definition: defines.h:45
PinDirection direction
This file contains the class that holds a netlist graph.
This file contains functions related to shortest paths in graphs.