Skip to content

Commit bf156bf

Browse files
Add interposer crossing wire cutting
1 parent b8c96bc commit bf156bf

File tree

10 files changed

+385
-116
lines changed

10 files changed

+385
-116
lines changed

libs/librrgraph/src/base/rr_graph_builder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,10 @@ class RRGraphBuilder {
352352
node_storage_.alloc_and_load_edges(rr_edges_to_create);
353353
}
354354

355+
inline void remove_edges(std::vector<RREdgeId>& rr_edges_to_remove) {
356+
node_storage_.remove_edges(rr_edges_to_remove);
357+
}
358+
355359
/** @brief Overrides the associated switch for a given edge by
356360
* updating the edge to use the passed in switch. */
357361
inline void override_edge_switch(RREdgeId edge_id, RRSwitchId switch_id) {

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
#include "rr_graph_storage.h"
33
#include "physical_types.h"
44
#include "rr_graph_fwd.h"
5+
#include "vtr_assert.h"
56
#include "vtr_error.h"
67
#include "librrgraph_types.h"
8+
#include "vtr_util.h"
79

810
#include <algorithm>
911
#include <cstddef>
@@ -57,6 +59,33 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges
5759
}
5860
}
5961

62+
void t_rr_graph_storage::remove_edges(std::vector<RREdgeId>& rr_edges_to_remove) {
63+
size_t starting_edge_count = edge_dest_node_.size();
64+
65+
vtr::uniquify(rr_edges_to_remove);
66+
67+
size_t edge_list_end = edge_dest_node_.size() - 1;
68+
for (auto it = rr_edges_to_remove.rbegin(); it != rr_edges_to_remove.rend(); ++it) {
69+
RREdgeId erase_idx = *it;
70+
71+
edge_dest_node_[erase_idx] = edge_dest_node_[RREdgeId(edge_list_end)];
72+
edge_src_node_[erase_idx] = edge_src_node_[RREdgeId(edge_list_end)];
73+
edge_switch_[erase_idx] = edge_switch_[RREdgeId(edge_list_end)];
74+
edge_remapped_[erase_idx] = edge_remapped_[RREdgeId(edge_list_end)];
75+
76+
edge_list_end--;
77+
78+
}
79+
80+
edge_dest_node_.erase(edge_dest_node_.begin() + edge_list_end + 1, edge_dest_node_.end());
81+
edge_src_node_.erase(edge_src_node_.begin() + edge_list_end + 1, edge_src_node_.end());
82+
edge_switch_.erase(edge_switch_.begin() + edge_list_end + 1, edge_switch_.end());
83+
edge_remapped_.erase(edge_remapped_.begin() + edge_list_end + 1, edge_remapped_.end());
84+
85+
VTR_ASSERT(edge_dest_node_.size() == (starting_edge_count - rr_edges_to_remove.size()));
86+
}
87+
88+
6089
void t_rr_graph_storage::assign_first_edges() {
6190
VTR_ASSERT(node_first_edge_.empty());
6291

@@ -68,39 +97,42 @@ void t_rr_graph_storage::assign_first_edges() {
6897
edge_src_node_.end()));
6998

7099
size_t node_id = 0;
71-
size_t first_id = 0;
72-
size_t second_id = 0;
100+
size_t first_edge_id = 0;
101+
size_t second_edge_id = 0;
102+
73103
size_t num_edges = edge_src_node_.size();
74104
VTR_ASSERT(edge_dest_node_.size() == num_edges);
75105
VTR_ASSERT(edge_switch_.size() == num_edges);
76106
VTR_ASSERT(edge_remapped_.size() == num_edges);
107+
77108
while (true) {
78-
VTR_ASSERT(first_id < num_edges);
79-
VTR_ASSERT(second_id < num_edges);
80-
size_t current_node_id = size_t(edge_src_node_[RREdgeId(second_id)]);
109+
VTR_ASSERT(first_edge_id < num_edges);
110+
VTR_ASSERT(second_edge_id < num_edges);
111+
112+
size_t current_node_id = size_t(edge_src_node_[RREdgeId(second_edge_id)]);
81113
if (node_id < current_node_id) {
82114
// All edges belonging to node_id are assigned.
83115
while (node_id < current_node_id) {
84116
// Store any edges belongs to node_id.
85117
VTR_ASSERT(node_id < node_first_edge_.size());
86-
node_first_edge_[RRNodeId(node_id)] = RREdgeId(first_id);
87-
first_id = second_id;
118+
node_first_edge_[RRNodeId(node_id)] = RREdgeId(first_edge_id);
119+
first_edge_id = second_edge_id;
88120
node_id += 1;
89121
}
90122

91123
VTR_ASSERT(node_id == current_node_id);
92-
node_first_edge_[RRNodeId(node_id)] = RREdgeId(second_id);
124+
node_first_edge_[RRNodeId(node_id)] = RREdgeId(second_edge_id);
93125
} else {
94-
second_id += 1;
95-
if (second_id == num_edges) {
126+
second_edge_id += 1;
127+
if (second_edge_id == num_edges) {
96128
break;
97129
}
98130
}
99131
}
100132

101133
// All remaining nodes have no edges, set as such.
102134
for (size_t inode = node_id + 1; inode < node_first_edge_.size(); ++inode) {
103-
node_first_edge_[RRNodeId(inode)] = RREdgeId(second_id);
135+
node_first_edge_[RRNodeId(inode)] = RREdgeId(second_edge_id);
104136
}
105137

106138
VTR_ASSERT_SAFE(verify_first_edges());

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ class t_rr_graph_storage {
400400
return vtr::StrongIdRange<RREdgeId>(first_edge(id), last_edge(id));
401401
}
402402

403+
404+
inline vtr::StrongIdRange<RREdgeId> all_edges() const {
405+
return vtr::StrongIdRange<RREdgeId>(RREdgeId(0), RREdgeId(edge_src_node_.size()));
406+
}
407+
403408
/** @brief Retrieve the RREdgeId for iedge'th edge in RRNodeId.
404409
*
405410
* This method should generally not be used, and instead first_edge and
@@ -776,6 +781,8 @@ class t_rr_graph_storage {
776781
/** @brief Adds a batch of edges.*/
777782
void alloc_and_load_edges(const t_rr_edge_info_set* rr_edges_to_create);
778783

784+
void remove_edges(std::vector<RREdgeId>& rr_edges_to_remove);
785+
779786
/* Edge finalization methods */
780787

781788
/** @brief Counts the number of rr switches needed based on fan in to support mux

libs/librrgraph/src/base/rr_graph_view.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,3 @@ bool RRGraphView::validate_in_edges() const {
129129
}
130130
return true;
131131
}
132-
133-

libs/librrgraph/src/base/rr_graph_view.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@
6565
#include "metadata_storage.h"
6666
#include "rr_node.h"
6767
#include "physical_types.h"
68+
#include "rr_node_types.h"
6869
#include "rr_spatial_lookup.h"
6970
#include "vtr_geometry.h"
7071
#include "rr_graph_utils.h"
72+
#include "vtr_range.h"
7173

7274
class RRGraphView {
7375
/* -- Constructors -- */
@@ -584,14 +586,19 @@ class RRGraphView {
584586
* @example
585587
* RRGraphView rr_graph; // A dummy rr_graph for a short example
586588
* RRNodeId node; // A dummy node for a short example
587-
* for (RREdgeId edge : rr_graph.edges(node)) {
589+
* for (t_edge_size edge : rr_graph.edges(node)) {
588590
* // Do something with the edge
589591
* }
590592
*/
591593
inline edge_idx_range edges(const RRNodeId& id) const {
592594
return vtr::make_range(edge_idx_iterator(0), edge_idx_iterator(num_edges(id)));
593595
}
594596

597+
inline vtr::StrongIdRange<RREdgeId> all_edges() const {
598+
return node_storage_.all_edges();
599+
}
600+
601+
595602
/**
596603
* @brief Return ID range for outgoing edges.
597604
*/
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#include <cstddef>
2+
#include <vector>
3+
#include <algorithm>
4+
#include <ranges>
5+
6+
#include "device_grid.h"
7+
#include "rr_graph_builder.h"
8+
#include "rr_graph_fwd.h"
9+
#include "rr_graph_view.h"
10+
#include "rr_node_types.h"
11+
#include "rr_spatial_lookup.h"
12+
#include "vtr_assert.h"
13+
#include "vtr_log.h"
14+
15+
#include "interposer_cut.h"
16+
17+
static bool should_cut_edge(int src_start_loc, int sink_start_loc, int cut_loc) {
18+
int src_delta = src_start_loc - cut_loc;
19+
int sink_delta = sink_start_loc - cut_loc;
20+
21+
// Same sign means that both sink and source are on the same side of this cut
22+
if ((src_delta < 0 && sink_delta < 0) || (src_delta >= 0 && sink_delta >= 0)) {
23+
return false;
24+
} else {
25+
return true;
26+
}
27+
}
28+
29+
static bool should_cut_node(int src_start_loc, int sink_start_loc, int cut_loc) {
30+
int src_delta = src_start_loc - cut_loc;
31+
int sink_delta = sink_start_loc - cut_loc;
32+
33+
// Same sign means that both sink and source are on the same side of this cut
34+
if ((src_delta <= 0 && sink_delta <= 0) || (src_delta > 0 && sink_delta > 0)) {
35+
return false;
36+
} else {
37+
return true;
38+
}
39+
}
40+
41+
static short node_xstart(const RRGraphView& rr_graph, RRNodeId node) {
42+
// Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below)
43+
if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) {
44+
VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node));
45+
return rr_graph.node_xlow(node);
46+
}
47+
48+
switch (rr_graph.node_direction(node)) {
49+
case Direction::DEC:
50+
return rr_graph.node_xhigh(node);
51+
break;
52+
53+
case Direction::INC:
54+
return rr_graph.node_xlow(node);
55+
break;
56+
57+
case Direction::NONE:
58+
VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node));
59+
return (rr_graph.node_xlow(node));
60+
break;
61+
62+
case Direction::BIDIR:
63+
VTR_ASSERT_MSG(false, "Bidir node has no starting point");
64+
break;
65+
66+
default:
67+
VTR_ASSERT(false);
68+
break;
69+
}
70+
}
71+
72+
static short node_ystart(const RRGraphView& rr_graph, RRNodeId node) {
73+
// Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below)
74+
if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) {
75+
return rr_graph.node_ylow(node);
76+
}
77+
78+
switch (rr_graph.node_direction(node)) {
79+
case Direction::DEC:
80+
return rr_graph.node_yhigh(node);
81+
break;
82+
83+
case Direction::INC:
84+
return rr_graph.node_ylow(node);
85+
break;
86+
87+
case Direction::NONE:
88+
VTR_ASSERT(rr_graph.node_ylow(node) == rr_graph.node_yhigh(node));
89+
return (rr_graph.node_ylow(node));
90+
break;
91+
92+
case Direction::BIDIR:
93+
VTR_ASSERT_MSG(false, "Bidir node has no starting point");
94+
break;
95+
96+
default:
97+
VTR_ASSERT(false);
98+
break;
99+
}
100+
}
101+
102+
std::vector<RREdgeId> mark_interposer_cut_edges_for_removal(const RRGraphView& rr_graph, const DeviceGrid& grid) {
103+
std::vector<RREdgeId> edges_to_be_removed;
104+
105+
// Loop over all RREdgeIds and mark ones that cross a cutline to be removed
106+
107+
for (RREdgeId edge_id : rr_graph.all_edges()) {
108+
RRNodeId src_node = rr_graph.edge_src_node(edge_id);
109+
RRNodeId sink_node = rr_graph.edge_sink_node(edge_id);
110+
111+
if (src_node == RRNodeId(5866) && sink_node == RRNodeId(5604)) {
112+
VTR_LOG("HI\n");
113+
}
114+
115+
// TODO: ignoring chanz nodes for now
116+
if (rr_graph.node_type(src_node) == e_rr_type::CHANZ || rr_graph.node_type(sink_node) == e_rr_type::CHANZ) {
117+
continue;
118+
}
119+
120+
VTR_ASSERT(rr_graph.node_layer_low(src_node) == rr_graph.node_layer_low(sink_node));
121+
VTR_ASSERT(rr_graph.node_layer_low(src_node) == rr_graph.node_layer_high(src_node));
122+
VTR_ASSERT(rr_graph.node_layer_low(sink_node) == rr_graph.node_layer_high(sink_node));
123+
124+
int layer = rr_graph.node_layer_low(src_node);
125+
126+
for (int cut_loc_y : grid.get_horizontal_interposer_cuts()[layer]) {
127+
int src_start_loc_y = node_ystart(rr_graph, src_node);
128+
int sink_start_loc_y = node_ystart(rr_graph, sink_node);
129+
130+
if (should_cut_edge(src_start_loc_y, sink_start_loc_y, cut_loc_y)) {
131+
edges_to_be_removed.push_back(edge_id);
132+
}
133+
}
134+
135+
for (int cut_loc_x : grid.get_vertical_interposer_cuts()[layer]) {
136+
int src_start_loc_x = node_xstart(rr_graph, src_node);
137+
int sink_start_loc_x = node_xstart(rr_graph, sink_node);
138+
139+
if (should_cut_edge(src_start_loc_x, sink_start_loc_x, cut_loc_x)) {
140+
edges_to_be_removed.push_back(edge_id);
141+
}
142+
}
143+
}
144+
145+
return edges_to_be_removed;
146+
}
147+
148+
// TODO: workshop a better name
149+
void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(const RRGraphView& rr_graph, const DeviceGrid& grid, RRGraphBuilder& rr_graph_builder, const std::vector<std::pair<RRNodeId, int>>& sg_node_indices) {
150+
VTR_ASSERT(std::is_sorted(sg_node_indices.begin(), sg_node_indices.end()));
151+
152+
RRSpatialLookup& spatial_lookup = rr_graph_builder.node_lookup();
153+
size_t num_sg = 0;
154+
for (size_t layer = 0; layer < grid.get_num_layers(); layer++) {
155+
for (int cut_loc_y : grid.get_horizontal_interposer_cuts()[layer]) {
156+
for (size_t x_loc = 0; x_loc < grid.width(); x_loc++) {
157+
std::vector<RRNodeId> channel_nodes = spatial_lookup.find_channel_nodes(layer, x_loc, cut_loc_y, e_rr_type::CHANY);
158+
for (RRNodeId node : channel_nodes) {
159+
160+
bool is_sg_node = std::ranges::binary_search(std::views::keys(sg_node_indices), node, [](RRNodeId l, RRNodeId r) {return size_t(l) < size_t(r);});
161+
if (is_sg_node) {
162+
num_sg++;
163+
continue;
164+
}
165+
166+
167+
int x_high = rr_graph.node_xhigh(node);
168+
int x_low = rr_graph.node_xlow(node);
169+
VTR_ASSERT(x_high == x_low);
170+
int y_high = rr_graph.node_yhigh(node);
171+
int y_low = rr_graph.node_ylow(node);
172+
int ptc_num = rr_graph.node_ptc_num(node);
173+
174+
175+
// No need to cut 1-length wires
176+
if (y_high == y_low) {
177+
continue;
178+
}
179+
180+
if (!should_cut_node(y_low, y_high, cut_loc_y)) {
181+
continue;
182+
}
183+
184+
if (rr_graph.node_direction(node) == Direction::INC) {
185+
// Anything above cut_loc_y shouldn't exist
186+
rr_graph_builder.set_node_coordinates(node, x_low, y_low, x_high, cut_loc_y);
187+
188+
// Do a loop from cut_loc_y to y_high and remove node from spatial lookup
189+
for (int y_loc = cut_loc_y + 1; y_loc <= y_high; y_loc++) {
190+
spatial_lookup.remove_node(node, layer, x_low, y_loc, e_rr_type::CHANY, ptc_num);
191+
}
192+
} else if (rr_graph.node_direction(node) == Direction::DEC) {
193+
// Anything below cut_loc_y shouldn't exist
194+
rr_graph_builder.set_node_coordinates(node, x_low, cut_loc_y + 1, x_high, y_high);
195+
196+
// Do a loop from y_low to cut_loc_y and remove node from spatial lookup
197+
for (int y_loc = y_low; y_loc <= cut_loc_y; y_loc++) {
198+
spatial_lookup.remove_node(node, layer, x_low, y_loc, e_rr_type::CHANY, ptc_num);
199+
}
200+
}
201+
}
202+
}
203+
}
204+
}
205+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include "rr_graph_fwd.h"
5+
#include "rr_graph_view.h"
6+
#include "device_grid.h"
7+
8+
std::vector<RREdgeId> mark_interposer_cut_edges_for_removal(const RRGraphView& rr_graph, const DeviceGrid& grid);
9+
10+
void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(const RRGraphView& rr_graph, const DeviceGrid& grid, RRGraphBuilder& rr_graph_builder, const std::vector<std::pair<RRNodeId, int>>& sg_node_indices);

0 commit comments

Comments
 (0)