Skip to content

Commit 5f49e17

Browse files
committed
Merge branch 'rr_graph_interposer_cut' of https://github.com/verilog-to-routing/vtr-verilog-to-routing into remove_node
2 parents 3b9f552 + b57b08f commit 5f49e17

File tree

7 files changed

+173
-61
lines changed

7 files changed

+173
-61
lines changed

libs/libarchfpga/src/device_grid.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,19 @@ void DeviceGrid::count_instances() {
8989
}
9090
}
9191
}
92+
93+
bool DeviceGrid::has_interposer_cuts() const {
94+
for (const std::vector<int>& layer_h_cuts : horizontal_interposer_cuts_) {
95+
if (!layer_h_cuts.empty()) {
96+
return true;
97+
}
98+
}
99+
100+
for (const std::vector<int>& layer_v_cuts : vertical_interposer_cuts_) {
101+
if (!layer_v_cuts.empty()) {
102+
return true;
103+
}
104+
}
105+
106+
return false;
107+
}

libs/libarchfpga/src/device_grid.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ class DeviceGrid {
211211
return vertical_interposer_cuts_;
212212
}
213213

214+
/// Returns if the grid has any interposer cuts. You should use this function instead of
215+
/// checking if get_horizontal/vertical_interposer_cuts is empty, since the return value
216+
/// of those functions might look something like this: {{}} which is technically not empty.
217+
bool has_interposer_cuts() const;
218+
214219
private:
215220
/// @brief Counts the number of each tile type on each layer and store it in instance_counts_.
216221
/// It is called in the constructor.

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <algorithm>
1111
#include <cstddef>
12+
#include <ranges>
1213

1314
void t_rr_graph_storage::reserve_edges(size_t num_edges) {
1415
edge_src_node_.reserve(num_edges);
@@ -67,14 +68,16 @@ void t_rr_graph_storage::remove_edges(std::vector<RREdgeId>& rr_edges_to_remove)
6768
// Sort and make sure all edge indices are unique
6869
vtr::uniquify(rr_edges_to_remove);
6970
VTR_ASSERT_SAFE(std::is_sorted(rr_edges_to_remove.begin(), rr_edges_to_remove.end()));
71+
72+
// Make sure the edge indices are valid
73+
VTR_ASSERT(static_cast<size_t>(rr_edges_to_remove.back()) <= edge_dest_node_.size());
7074

7175
// Index of the last edge
7276
size_t edge_list_end = edge_dest_node_.size() - 1;
7377

7478
// Iterate backwards through the list of indices we want to remove.
75-
for (auto it = rr_edges_to_remove.rbegin(); it != rr_edges_to_remove.rend(); ++it) {
76-
RREdgeId erase_idx = *it;
77-
79+
80+
for (RREdgeId erase_idx : std::ranges::reverse_view(rr_edges_to_remove)) {
7881
// Copy what's at the end of the list to the index we wanted to remove
7982
edge_dest_node_[erase_idx] = edge_dest_node_[RREdgeId(edge_list_end)];
8083
edge_src_node_[erase_idx] = edge_src_node_[RREdgeId(edge_list_end)];

libs/librrgraph/src/base/rr_graph_view.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ class RRGraphView {
591591
*
592592
* @note Iterating on the range returned by this function will not give you an RREdgeId, but instead gives you the index among a node's outgoing edges
593593
*/
594-
inline edge_idx_range edges(const RRNodeId& id) const {
594+
inline edge_idx_range edges(RRNodeId id) const {
595595
return vtr::make_range(edge_idx_iterator(0), edge_idx_iterator(num_edges(id)));
596596
}
597597

@@ -607,7 +607,7 @@ class RRGraphView {
607607
/**
608608
* @brief Return ID range for outgoing edges.
609609
*/
610-
inline edge_idx_range node_out_edges(const RRNodeId& id) const {
610+
inline edge_idx_range node_out_edges(RRNodeId id) const {
611611
return vtr::make_range(edge_idx_iterator(0), edge_idx_iterator(num_edges(id)));
612612
}
613613

vpr/src/route/rr_graph_generation/rr_graph.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "rr_graph_intra_cluster.h"
3434
#include "rr_graph_tile_nodes.h"
3535
#include "rr_graph_3d.h"
36+
#include "rr_graph_interposer.h"
3637
#include "rr_graph_timing_params.h"
3738
#include "check_rr_graph.h"
3839
#include "echo_files.h"
@@ -47,8 +48,6 @@
4748
#include "rr_types.h"
4849
#include "rr_node_indices.h"
4950

50-
#include "interposer_cut.h"
51-
5251
//#define VERBOSE
5352
//used for getting the exact count of each edge type and printing it to std out.
5453

@@ -1671,14 +1670,15 @@ static std::function<void(t_chan_width*)> alloc_and_load_rr_graph(RRGraphBuilder
16711670
}
16721671

16731672
// If there are any interposer cuts, remove the edges and shorten the wires that cross interposer cut lines.
1674-
if (!grid.get_horizontal_interposer_cuts().empty() || !grid.get_vertical_interposer_cuts().empty()) {
1673+
if (grid.has_interposer_cuts()) {
16751674
std::vector<RREdgeId> interposer_edges = mark_interposer_cut_edges_for_removal(rr_graph, grid);
16761675
rr_graph_builder.remove_edges(interposer_edges);
16771676

16781677
update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(rr_graph, grid, rr_graph_builder, sg_node_indices);
16791678
}
16801679

1681-
// Add 2D scatter-gather link edges (the nodes have already been created at this point). These links are mostly used for interposer-crossing connections, but could also be used for other things.
1680+
// Add 2D scatter-gather link edges (the nodes have already been created at this point).
1681+
// These links are mostly used for interposer-crossing connections, but could also be used for other things.
16821682
add_and_connect_non_3d_sg_links(rr_graph_builder, sg_links, sg_node_indices, chan_details_x, chan_details_y, num_seg_types_x, rr_edges_to_create);
16831683
uniquify_edges(rr_edges_to_create);
16841684
alloc_and_load_edges(rr_graph_builder, rr_edges_to_create);

vpr/src/route/rr_graph_generation/interposer_cut.cpp renamed to vpr/src/route/rr_graph_generation/rr_graph_interposer.cpp

Lines changed: 136 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cstddef>
2+
#include <utility>
23
#include <vector>
34
#include <algorithm>
45
#include <ranges>
@@ -13,11 +14,82 @@
1314
#include "vpr_error.h"
1415
#include "vtr_assert.h"
1516

16-
#include "interposer_cut.h"
17+
#include "rr_graph_interposer.h"
18+
19+
// Static function declarations
20+
21+
/**
22+
* @brief Takes location of a source and a sink and determines wether it crosses cut_loc or not.
23+
* For example, the interval (1, 4) is cut by 3, while it is not cut by 5 or 0.
24+
*/
25+
static bool should_cut(int src_loc, int sink_loc, int cut_loc);
26+
27+
/**
28+
* @brief Calculates the starting x point of node based on it's directionality.
29+
*/
30+
static short node_xstart(const RRGraphView& rr_graph, RRNodeId node);
31+
32+
/**
33+
* @brief Calculates the starting y point of node based on it's directionality.
34+
*/
35+
static short node_ystart(const RRGraphView& rr_graph, RRNodeId node);
1736

1837
/**
19-
* @brief Takes location of a source and a sink and determines wether it crosses cut_loc or not. For example, the interval (1, 4) is cut by 3, while it is not cut by 5 or 0.
38+
* @brief Update a CHANY node's bounding box in RRGraph and SpatialLookup entries.
39+
* This function assumes that the channel node actually crosses the cut location and
40+
* might not function correctly otherwise.
41+
*
42+
* This is a low level function, you should use cut_channel_node that wraps this up in a nicer API.
2043
*/
44+
static void cut_chan_y_node(RRNodeId node,
45+
int x_low,
46+
int y_low,
47+
int x_high,
48+
int y_high,
49+
int layer,
50+
int ptc_num,
51+
int cut_loc_y,
52+
Direction node_direction,
53+
RRGraphBuilder& rr_graph_builder,
54+
RRSpatialLookup& spatial_lookup);
55+
56+
/**
57+
* @brief Update a CHANX node's bounding box in RRGraph and SpatialLookup entries.
58+
* This function assumes that the channel node actually crosses the cut location and
59+
* might not function correctly otherwise.
60+
*
61+
* This is a low level function, you should use cut_channel_node that wraps this up in a nicer API.
62+
*/
63+
static void cut_chan_x_node(RRNodeId node,
64+
int x_low,
65+
int y_low,
66+
int x_high,
67+
int y_high,
68+
int layer,
69+
int ptc_num,
70+
int cut_loc_x,
71+
Direction node_direction,
72+
RRGraphBuilder& rr_graph_builder,
73+
RRSpatialLookup& spatial_lookup);
74+
75+
/**
76+
* @brief Update a CHANX or CHANY node's bounding box in RRGraph and SpatialLookup entries if it crosses cut_loc
77+
*
78+
* @param node Channel segment RR graph node that might cross the interposer cut line
79+
* @param cut_loc location of vertical interposer cut line
80+
* @param interposer_cut_type Type of the interposer cut line (Horizontal or vertical)
81+
* @param sg_node_indices Sorted list of scatter-gather node IDs. We do not want to cut these nodes as they're allowed to cross an interposer cut line.
82+
*/
83+
static void cut_channel_node(RRNodeId node,
84+
int cut_loc,
85+
e_interposer_cut_type interposer_cut_type,
86+
const RRGraphView& rr_graph,
87+
RRGraphBuilder& rr_graph_builder,
88+
RRSpatialLookup& spatial_lookup,
89+
const std::vector<std::pair<RRNodeId, int>>& sg_node_indices);
90+
91+
// Function definitions
92+
2193
static bool should_cut(int src_loc, int sink_loc, int cut_loc) {
2294
int src_delta = src_loc - cut_loc;
2395
int sink_delta = sink_loc - cut_loc;
@@ -30,26 +102,28 @@ static bool should_cut(int src_loc, int sink_loc, int cut_loc) {
30102
}
31103
}
32104

33-
/**
34-
* @brief Calculates the starting x point of node based on it's directionality.
35-
*/
36105
static short node_xstart(const RRGraphView& rr_graph, RRNodeId node) {
106+
e_rr_type node_type = rr_graph.node_type(node);
107+
Direction node_direction = rr_graph.node_direction(node);
108+
short node_xlow = rr_graph.node_xlow(node);
109+
short node_xhigh = rr_graph.node_xhigh(node);
110+
37111
// Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below)
38-
if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) {
39-
VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node));
40-
return rr_graph.node_xlow(node);
112+
if (is_pin(node_type)) {
113+
VTR_ASSERT(node_xlow == node_xhigh);
114+
return node_xlow;
41115
}
42116

43-
switch (rr_graph.node_direction(node)) {
117+
switch (node_direction) {
44118
case Direction::DEC:
45-
return rr_graph.node_xhigh(node);
119+
return node_xhigh;
46120

47121
case Direction::INC:
48-
return rr_graph.node_xlow(node);
122+
return node_xlow;
49123

50124
case Direction::NONE:
51-
VTR_ASSERT(rr_graph.node_xlow(node) == rr_graph.node_xhigh(node));
52-
return (rr_graph.node_xlow(node));
125+
VTR_ASSERT(node_xlow == node_xhigh);
126+
return (node_xlow);
53127

54128
case Direction::BIDIR:
55129
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Bidir node has no starting point.");
@@ -61,25 +135,27 @@ static short node_xstart(const RRGraphView& rr_graph, RRNodeId node) {
61135
}
62136
}
63137

64-
/**
65-
* @brief Calculates the starting y point of node based on it's directionality.
66-
*/
67138
static short node_ystart(const RRGraphView& rr_graph, RRNodeId node) {
139+
e_rr_type node_type = rr_graph.node_type(node);
140+
Direction node_direction = rr_graph.node_direction(node);
141+
short node_ylow = rr_graph.node_ylow(node);
142+
short node_yhigh = rr_graph.node_yhigh(node);
143+
68144
// Return early for OPIN and IPIN types (Some BIDIR pins would trigger the assertion below)
69-
if (rr_graph.node_type(node) == e_rr_type::OPIN || rr_graph.node_type(node) == e_rr_type::IPIN) {
70-
return rr_graph.node_ylow(node);
145+
if (is_pin(node_type)) {
146+
return node_ylow;
71147
}
72148

73-
switch (rr_graph.node_direction(node)) {
149+
switch (node_direction) {
74150
case Direction::DEC:
75-
return rr_graph.node_yhigh(node);
151+
return node_yhigh;
76152

77153
case Direction::INC:
78-
return rr_graph.node_ylow(node);
154+
return node_ylow;
79155

80156
case Direction::NONE:
81-
VTR_ASSERT(rr_graph.node_ylow(node) == rr_graph.node_yhigh(node));
82-
return (rr_graph.node_ylow(node));
157+
VTR_ASSERT(node_ylow == node_yhigh);
158+
return (node_ylow);
83159

84160
case Direction::BIDIR:
85161
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Bidir node has no starting point.");
@@ -136,14 +212,17 @@ std::vector<RREdgeId> mark_interposer_cut_edges_for_removal(const RRGraphView& r
136212
return edges_to_be_removed;
137213
}
138214

139-
/**
140-
* @brief Update a CHANY node's bounding box in RRGraph and SpatialLookup entries.
141-
* This function assumes that the channel node actually crosses the cut location and
142-
* might not function correctly otherwise.
143-
*
144-
* This is a low level function, you should use cut_channel_node that wraps this up in a nicer API.
145-
*/
146-
static void cut_chan_y_node(RRNodeId node, int x_low, int y_low, int x_high, int y_high, int layer, int ptc_num, int cut_loc_y, Direction node_direction, RRGraphBuilder& rr_graph_builder, RRSpatialLookup& spatial_lookup) {
215+
static void cut_chan_y_node(RRNodeId node,
216+
int x_low,
217+
int y_low,
218+
int x_high,
219+
int y_high,
220+
int layer,
221+
int ptc_num,
222+
int cut_loc_y,
223+
Direction node_direction,
224+
RRGraphBuilder& rr_graph_builder,
225+
RRSpatialLookup& spatial_lookup) {
147226
if (node_direction == Direction::INC) {
148227
// Anything above cut_loc_y shouldn't exist
149228
rr_graph_builder.set_node_coordinates(node, x_low, y_low, x_high, cut_loc_y);
@@ -165,14 +244,17 @@ static void cut_chan_y_node(RRNodeId node, int x_low, int y_low, int x_high, int
165244
}
166245
}
167246

168-
/**
169-
* @brief Update a CHANX node's bounding box in RRGraph and SpatialLookup entries.
170-
* This function assumes that the channel node actually crosses the cut location and
171-
* might not function correctly otherwise.
172-
*
173-
* This is a low level function, you should use cut_channel_node that wraps this up in a nicer API.
174-
*/
175-
static void cut_chan_x_node(RRNodeId node, int x_low, int y_low, int x_high, int y_high, int layer, int ptc_num, int cut_loc_x, Direction node_direction, RRGraphBuilder& rr_graph_builder, RRSpatialLookup& spatial_lookup) {
247+
static void cut_chan_x_node(RRNodeId node,
248+
int x_low,
249+
int y_low,
250+
int x_high,
251+
int y_high,
252+
int layer,
253+
int ptc_num,
254+
int cut_loc_x,
255+
Direction node_direction,
256+
RRGraphBuilder& rr_graph_builder,
257+
RRSpatialLookup& spatial_lookup) {
176258
if (node_direction == Direction::INC) {
177259
// Anything to the right of cut_loc_x shouldn't exist
178260
rr_graph_builder.set_node_coordinates(node, x_low, y_low, cut_loc_x, y_high);
@@ -194,15 +276,13 @@ static void cut_chan_x_node(RRNodeId node, int x_low, int y_low, int x_high, int
194276
}
195277
}
196278

197-
/**
198-
* @brief Update a CHANX or CHANY node's bounding box in RRGraph and SpatialLookup entries if it crosses cut_loc
199-
*
200-
* @param node Channel segment RR graph node that might cross the interposer cut line
201-
* @param cut_loc location of vertical interposer cut line
202-
* @param interposer_cut_type Type of the interposer cut line (Horizontal or vertical)
203-
* @param sg_node_indices Sorted list of scatter-gather node IDs. We do not want to cut these nodes as they're allowed to cross an interposer cut line.
204-
*/
205-
static void cut_channel_node(RRNodeId node, int cut_loc, e_interposer_cut_type interposer_cut_type, const RRGraphView& rr_graph, RRGraphBuilder& rr_graph_builder, RRSpatialLookup& spatial_lookup, const std::vector<std::pair<RRNodeId, int>>& sg_node_indices) {
279+
static void cut_channel_node(RRNodeId node,
280+
int cut_loc,
281+
e_interposer_cut_type interposer_cut_type,
282+
const RRGraphView& rr_graph,
283+
RRGraphBuilder& rr_graph_builder,
284+
RRSpatialLookup& spatial_lookup,
285+
const std::vector<std::pair<RRNodeId, int>>& sg_node_indices) {
206286
constexpr auto node_indice_compare = [](RRNodeId l, RRNodeId r) noexcept { return size_t(l) < size_t(r); };
207287
bool is_sg_node = std::ranges::binary_search(std::views::keys(sg_node_indices), node, node_indice_compare);
208288
if (is_sg_node) {
@@ -239,7 +319,10 @@ static void cut_channel_node(RRNodeId node, int cut_loc, e_interposer_cut_type i
239319
}
240320
}
241321

242-
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) {
322+
void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(const RRGraphView& rr_graph,
323+
const DeviceGrid& grid,
324+
RRGraphBuilder& rr_graph_builder,
325+
const std::vector<std::pair<RRNodeId, int>>& sg_node_indices) {
243326

244327
VTR_ASSERT(std::is_sorted(sg_node_indices.begin(), sg_node_indices.end()));
245328

@@ -249,7 +332,8 @@ void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(con
249332
for (size_t x_loc = 0; x_loc < grid.width(); x_loc++) {
250333
std::vector<RRNodeId> channel_nodes = spatial_lookup.find_channel_nodes(layer, x_loc, cut_loc_y, e_rr_type::CHANY);
251334
for (RRNodeId node : channel_nodes) {
252-
cut_channel_node(node, cut_loc_y, e_interposer_cut_type::HORZ, rr_graph, rr_graph_builder, spatial_lookup, sg_node_indices);
335+
cut_channel_node(node, cut_loc_y, e_interposer_cut_type::HORZ,
336+
rr_graph, rr_graph_builder, spatial_lookup, sg_node_indices);
253337
}
254338
}
255339
}
@@ -258,7 +342,8 @@ void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(con
258342
for (size_t y_loc = 0; y_loc < grid.height(); y_loc++) {
259343
std::vector<RRNodeId> channel_nodes = spatial_lookup.find_channel_nodes(layer, cut_loc_x, y_loc, e_rr_type::CHANX);
260344
for (RRNodeId node : channel_nodes) {
261-
cut_channel_node(node, cut_loc_x, e_interposer_cut_type::VERT, rr_graph, rr_graph_builder, spatial_lookup, sg_node_indices);
345+
cut_channel_node(node, cut_loc_x, e_interposer_cut_type::VERT,
346+
rr_graph, rr_graph_builder, spatial_lookup, sg_node_indices);
262347
}
263348
}
264349
}

vpr/src/route/rr_graph_generation/interposer_cut.h renamed to vpr/src/route/rr_graph_generation/rr_graph_interposer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ std::vector<RREdgeId> mark_interposer_cut_edges_for_removal(const RRGraphView& r
2828
* @param rr_graph_builder RRGraphBuilder, to modify the RRGraph.
2929
* @param sg_node_indices list of scatter-gather node IDs. We do not want to cut these nodes as they're allowed to cross an interposer cut line.
3030
*/
31-
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);
31+
void update_interposer_crossing_nodes_in_spatial_lookup_and_rr_graph_storage(const RRGraphView& rr_graph,
32+
const DeviceGrid& grid,
33+
RRGraphBuilder& rr_graph_builder,
34+
const std::vector<std::pair<RRNodeId, int>>& sg_node_indices);

0 commit comments

Comments
 (0)