Skip to content

Commit e78d1d9

Browse files
author
Simon Klix
committed
added functionality to create garph algorithm netlist graph from a netlist abstraction
1 parent cb8b290 commit e78d1d9

File tree

4 files changed

+197
-7
lines changed

4 files changed

+197
-7
lines changed

include/hal_core/netlist/decorators/netlist_abstraction_decorator.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ namespace hal
6464
const std::function<bool(const Endpoint*, const u32 current_depth)>& exit_endpoint_filter = nullptr,
6565
const std::function<bool(const Endpoint*, const u32 current_depth)>& entry_endpoint_filter = nullptr);
6666

67+
const std::vector<Gate*>& get_target_gates() const;
68+
6769
/**
6870
* @brief Gets the predecessors of a gate within the abstraction.
6971
*
@@ -136,6 +138,14 @@ namespace hal
136138
*/
137139
Result<std::vector<Net*>> get_global_input_predecessors(const Endpoint* endpoint) const;
138140

141+
/**
142+
* @brief Gets the global input nets that are predecessors of a gate.
143+
*
144+
* @param[in] gate - The gate to get global input predecessors for.
145+
* @returns A vector of global input nets.
146+
*/
147+
Result<std::vector<Net*>> get_global_input_predecessors(const Gate* gate) const;
148+
139149
/**
140150
* @brief Gets the global output nets that are successors of an endpoint.
141151
*
@@ -144,9 +154,20 @@ namespace hal
144154
*/
145155
Result<std::vector<Net*>> get_global_output_successors(const Endpoint* endpoint) const;
146156

157+
/**
158+
* @brief Gets the global output nets that are successors of a gate.
159+
*
160+
* @param[in] gate - The gate to get global output successors for.
161+
* @returns A vector of global output nets.
162+
*/
163+
Result<std::vector<Net*>> get_global_output_successors(const Gate* gate) const;
164+
147165
private:
148166
NetlistAbstraction() = default;
149167

168+
std::vector<Gate*> m_target_gates;
169+
// std::vector<Gate*> m_included_gates;
170+
150171
/**
151172
* @brief Maps endpoints to their successor endpoints within the abstraction.
152173
*/

plugins/graph_algorithm/include/graph_algorithm/netlist_graph.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace hal
4444
class Netlist;
4545
class Gate;
4646
class Net;
47+
class NetlistAbstraction;
4748

4849
namespace graph_algorithm
4950
{
@@ -121,6 +122,20 @@ namespace hal
121122
*/
122123
static Result<std::unique_ptr<NetlistGraph>> from_netlist_no_edges(Netlist* nl, const std::vector<Gate*>& gates = {});
123124

125+
/**
126+
* @brief Create a directed graph from a netlist abstraction.
127+
*
128+
* Optionally create dummy vertices at global input and output nets
129+
* An optional filter can be applied to exclude undesired edges.
130+
*
131+
* @param[in] nl_abstr - The netlist abstraction.
132+
* @param[in] create_dummy_vertices - Set `true` to create dummy vertices, `false` otherwise. Defaults to `false`.
133+
* @param[in] filter - An optional filter that is evaluated on every edge in the netlist abstraction. Defaults to `nullptr`.
134+
* @returns The netlist graph on success, an error otherwise.
135+
*/
136+
static Result<std::unique_ptr<NetlistGraph>>
137+
from_netlist_abstraction(const NetlistAbstraction* nl_asbtr, const bool create_dummy_vertices = false, const std::function<bool(const Endpoint*, const Endpoint*)>& filter = nullptr);
138+
124139
/**
125140
* @brief Create a deep copy of the netlist graph.
126141
*

plugins/graph_algorithm/src/netlist_graph.cpp

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "graph_algorithm/netlist_graph.h"
2-
2+
#include "hal_core/netlist/decorators/netlist_abstraction_decorator.h"
33
#include "hal_core/netlist/endpoint.h"
44
#include "hal_core/netlist/gate.h"
55
#include "hal_core/netlist/net.h"
@@ -186,6 +186,104 @@ namespace hal
186186
return OK(std::move(graph));
187187
}
188188

189+
Result<std::unique_ptr<NetlistGraph>>
190+
NetlistGraph::from_netlist_abstraction(const NetlistAbstraction* nl_asbtr, const bool create_dummy_vertices, const std::function<bool(const Endpoint*, const Endpoint*)>& filter)
191+
{
192+
if (!nl_asbtr)
193+
{
194+
return ERR("netlist abstraction is a nullptr");
195+
}
196+
197+
if (nl_asbtr->get_target_gates().empty())
198+
{
199+
return ERR("netlist abstraction has no target gates");
200+
}
201+
202+
auto graph = std::unique_ptr<NetlistGraph>(new NetlistGraph(nl_asbtr->get_target_gates().front()->get_netlist()));
203+
204+
// count all edges as this number is needed to create a new graph
205+
u32 edge_counter = 0;
206+
for (const auto* gate : nl_asbtr->get_target_gates())
207+
{
208+
edge_counter += nl_asbtr->get_unique_successors(gate).get().size();
209+
210+
if (create_dummy_vertices)
211+
{
212+
edge_counter += nl_asbtr->get_global_input_predecessors(gate).get().size();
213+
edge_counter += nl_asbtr->get_global_output_successors(gate).get().size();
214+
}
215+
}
216+
217+
// initialize edge vector
218+
igraph_vector_int_t edges;
219+
auto err = igraph_vector_int_init(&edges, 2 * edge_counter);
220+
if (err != IGRAPH_SUCCESS)
221+
{
222+
return ERR(igraph_strerror(err));
223+
}
224+
225+
// we need dummy gates for input/outputs
226+
u32 node_counter = 0;
227+
u32 edge_index = 0;
228+
229+
for (auto* g : nl_asbtr->get_target_gates())
230+
{
231+
const u32 node = node_counter++;
232+
graph->m_gates_to_nodes[g] = node;
233+
graph->m_nodes_to_gates[node] = g;
234+
}
235+
236+
std::map<Net*, u32> global_in_to_node;
237+
std::map<Net*, u32> global_out_to_node;
238+
for (auto* src_gate : nl_asbtr->get_target_gates())
239+
{
240+
for (auto* dst_gate : nl_asbtr->get_unique_successors(src_gate).get())
241+
{
242+
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
243+
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
244+
}
245+
246+
if (create_dummy_vertices)
247+
{
248+
for (auto* global_in : nl_asbtr->get_global_input_predecessors(src_gate).get())
249+
{
250+
if (global_in_to_node.find(global_in) == global_in_to_node.end())
251+
{
252+
// create dummy node for global input
253+
global_in_to_node[global_in] = node_counter++;
254+
}
255+
256+
VECTOR(edges)[edge_index++] = global_in_to_node.at(global_in);
257+
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
258+
}
259+
260+
for (auto* global_out : nl_asbtr->get_global_output_successors(src_gate).get())
261+
{
262+
if (global_out_to_node.find(global_out) == global_out_to_node.end())
263+
{
264+
// create dummy node for global output
265+
global_out_to_node[global_out] = node_counter++;
266+
}
267+
268+
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
269+
VECTOR(edges)[edge_index++] = global_out_to_node.at(global_out);
270+
}
271+
}
272+
}
273+
274+
graph->m_graph_ptr = &(graph->m_graph);
275+
err = igraph_create(graph->m_graph_ptr, &edges, node_counter, IGRAPH_DIRECTED);
276+
277+
igraph_vector_int_destroy(&edges);
278+
279+
if (err != IGRAPH_SUCCESS)
280+
{
281+
return ERR(igraph_strerror(err));
282+
}
283+
284+
return OK(std::move(graph));
285+
}
286+
189287
Result<std::unique_ptr<NetlistGraph>> NetlistGraph::copy() const
190288
{
191289
auto graph = std::unique_ptr<NetlistGraph>(new NetlistGraph(m_nl));

src/netlist/decorators/netlist_abstraction_decorator.cpp

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ namespace hal
1616
const auto nl_trav_dec = NetlistTraversalDecorator(*netlist);
1717

1818
// transform gates into set to check fast if a gate is part of abstraction
19-
const auto gates_set = utils::to_unordered_set(gates);
20-
const auto& included_gates = include_all_netlist_gates ? netlist->get_gates() : gates;
19+
const auto target_gates_set = utils::to_unordered_set(gates);
20+
const auto& included_gates = include_all_netlist_gates ? netlist->get_gates() : gates;
21+
22+
auto new_abstraction = std::shared_ptr<NetlistAbstraction>(new NetlistAbstraction());
23+
new_abstraction->m_target_gates = gates;
24+
// new_abstraction->m_included_gates = included_gates;
2125

22-
auto new_abstraction = std::shared_ptr<NetlistAbstraction>(new NetlistAbstraction());
2326
const u32 approximated_endpoint_count = included_gates.size() * 8;
2427
new_abstraction->m_successors.reserve(approximated_endpoint_count);
2528
new_abstraction->m_predecessors.reserve(approximated_endpoint_count);
@@ -38,7 +41,7 @@ namespace hal
3841
const auto successors = nl_trav_dec.get_next_matching_endpoints(
3942
ep_out,
4043
true,
41-
[gates_set](const auto& ep) { return ep->is_destination_pin() && gates_set.find(ep->get_gate()) != gates_set.end(); },
44+
[target_gates_set](const auto& ep) { return ep->is_destination_pin() && target_gates_set.find(ep->get_gate()) != target_gates_set.end(); },
4245
false,
4346
exit_endpoint_filter,
4447
entry_endpoint_filter);
@@ -80,8 +83,8 @@ namespace hal
8083
{
8184
new_abstraction->m_predecessors.insert({ep_in, {}});
8285

83-
const auto predecessors =
84-
nl_trav_dec.get_next_matching_endpoints(ep_in, false, [gates_set](const auto& ep) { return ep->is_source_pin() && gates_set.find(ep->get_gate()) != gates_set.end(); });
86+
const auto predecessors = nl_trav_dec.get_next_matching_endpoints(
87+
ep_in, false, [target_gates_set](const auto& ep) { return ep->is_source_pin() && target_gates_set.find(ep->get_gate()) != target_gates_set.end(); });
8588

8689
if (predecessors.is_error())
8790
{
@@ -118,6 +121,11 @@ namespace hal
118121
return OK(new_abstraction);
119122
}
120123

124+
const std::vector<Gate*>& NetlistAbstraction::get_target_gates() const
125+
{
126+
return m_target_gates;
127+
}
128+
121129
Result<std::vector<Endpoint*>> NetlistAbstraction::get_predecessors(const Gate* gate) const
122130
{
123131
std::vector<Endpoint*> predecessors;
@@ -277,6 +285,30 @@ namespace hal
277285
return OK(it->second);
278286
}
279287

288+
Result<std::vector<Net*>> NetlistAbstraction::get_global_input_predecessors(const Gate* gate) const
289+
{
290+
std::vector<Net*> global_input_predecessors;
291+
for (auto* ep : gate->get_fan_out_endpoints())
292+
{
293+
const auto new_global_input_predecessors = get_global_input_predecessors(ep);
294+
if (new_global_input_predecessors.is_error())
295+
{
296+
return ERR_APPEND(new_global_input_predecessors.get_error(),
297+
"failed to get global input predecessors of gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + " in netlist abstraction");
298+
}
299+
300+
for (auto* pred_net : new_global_input_predecessors.get())
301+
{
302+
global_input_predecessors.push_back(pred_net);
303+
}
304+
}
305+
306+
std::sort(global_input_predecessors.begin(), global_input_predecessors.end());
307+
global_input_predecessors.erase(std::unique(global_input_predecessors.begin(), global_input_predecessors.end()), global_input_predecessors.end());
308+
309+
return OK(global_input_predecessors);
310+
}
311+
280312
Result<std::vector<Net*>> NetlistAbstraction::get_global_output_successors(const Endpoint* endpoint) const
281313
{
282314
const auto it = m_global_output_successors.find(endpoint);
@@ -288,6 +320,30 @@ namespace hal
288320
return OK(it->second);
289321
}
290322

323+
Result<std::vector<Net*>> NetlistAbstraction::get_global_output_successors(const Gate* gate) const
324+
{
325+
std::vector<Net*> global_output_successors;
326+
for (auto* ep : gate->get_fan_out_endpoints())
327+
{
328+
const auto new_global_output_successors = get_global_output_successors(ep);
329+
if (new_global_output_successors.is_error())
330+
{
331+
return ERR_APPEND(new_global_output_successors.get_error(),
332+
"failed to get global output successors of gate " + gate->get_name() + " with ID " + std::to_string(gate->get_id()) + " in netlist abstraction");
333+
}
334+
335+
for (auto* succ_net : new_global_output_successors.get())
336+
{
337+
global_output_successors.push_back(succ_net);
338+
}
339+
}
340+
341+
std::sort(global_output_successors.begin(), global_output_successors.end());
342+
global_output_successors.erase(std::unique(global_output_successors.begin(), global_output_successors.end()), global_output_successors.end());
343+
344+
return OK(global_output_successors);
345+
}
346+
291347
NetlistAbstractionDecorator::NetlistAbstractionDecorator(const hal::NetlistAbstraction& abstraction) : m_abstraction(abstraction){};
292348

293349
Result<std::optional<u32>> NetlistAbstractionDecorator::get_shortest_path_distance_internal(const std::vector<Endpoint*>& start,

0 commit comments

Comments
 (0)