Skip to content

Commit 69f83bf

Browse files
committed
Replace rr_node_indices in block_rr_indices with RRSpatialLookup; Deposit invalid node ids when allocating RRSpatialLookup; No long need complex sanity checks. The vectors in RRSpatialLookup can be well aligned and allocated just in need; Remove the dead loop between rr_graph2.h and rr_graph_storage.h
1 parent 448b8e1 commit 69f83bf

File tree

7 files changed

+112
-91
lines changed

7 files changed

+112
-91
lines changed

vpr/src/device/rr_spatial_lookup.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,33 @@ void RRSpatialLookup::add_node(RRNodeId node,
8080
t_rr_type type,
8181
int ptc,
8282
e_side side) {
83+
VTR_ASSERT(node); /* Must have a valid node id to be added */
8384
VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims());
8485

86+
resize_nodes(x, y, type, side);
87+
88+
if (size_t(ptc) >= rr_node_indices_[type][x][y][side].size()) {
89+
/* Deposit invalid ids to newly allocated elements while original elements are untouched */
90+
rr_node_indices_[type][x][y][side].resize(ptc + 1, int(size_t(RRNodeId::INVALID())));
91+
}
92+
93+
/* Resize on demand finished; Register the node */
94+
rr_node_indices_[type][x][y][side][ptc] = int(size_t(node));
95+
}
96+
97+
void RRSpatialLookup::mirror_nodes(const vtr::Point<int>& src_coord,
98+
const vtr::Point<int>& des_coord,
99+
t_rr_type type,
100+
e_side side) {
101+
VTR_ASSERT(SOURCE == type || SINK == type);
102+
resize_nodes(des_coord.x(), des_coord.y(), type, side);
103+
rr_node_indices_[type][des_coord.x()][des_coord.y()][side] = rr_node_indices_[type][src_coord.x()][src_coord.y()][side];
104+
}
105+
106+
void RRSpatialLookup::resize_nodes(int x,
107+
int y,
108+
t_rr_type type,
109+
e_side side) {
85110
/* Expand the fast look-up if the new node is out-of-range
86111
* This may seldom happen because the rr_graph building function
87112
* should ensure the fast look-up well organized
@@ -97,11 +122,4 @@ void RRSpatialLookup::add_node(RRNodeId node,
97122
std::max(rr_node_indices_[type].dim_size(1), size_t(y) + 1),
98123
std::max(rr_node_indices_[type].dim_size(2), size_t(side) + 1)});
99124
}
100-
101-
if (size_t(ptc) >= rr_node_indices_[type][x][y][side].size()) {
102-
rr_node_indices_[type][x][y][side].resize(ptc + 1);
103-
}
104-
105-
/* Resize on demand finished; Register the node */
106-
rr_node_indices_[type][x][y][side][ptc] = int(size_t(node));
107125
}

vpr/src/device/rr_spatial_lookup.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef RR_SPATIAL_LOOKUP_H
22
#define RR_SPATIAL_LOOKUP_H
33

4+
#include "vtr_geometry.h"
45
#include "vpr_types.h"
56

67
/********************************************************************
@@ -89,7 +90,32 @@ class RRSpatialLookup {
8990
int ptc,
9091
e_side side);
9192

92-
/* TODO: Add an API remove_node() to unregister a node from the look-up */
93+
/* Mirror the last dimension of a look-up, i.e., a list of nodes, from a source coordinate to
94+
* a destination coordinate.
95+
* This function is mostly need by SOURCE and SINK nodes which are indexable in multiple locations.
96+
* Considering a bounding box (x, y)->(x + width, y + height) of a multi-height and multi-width grid,
97+
* SOURCE and SINK nodes are indexable in any location inside the boundry.
98+
*
99+
* Note: currently this function only accept SOURCE/SINK nodes. May unlock for other depending on needs
100+
*/
101+
void mirror_nodes(const vtr::Point<int>& src_coord,
102+
const vtr::Point<int>& des_coord,
103+
t_rr_type type,
104+
e_side side);
105+
106+
/* Resize three dimensions of the lookup under a given type of node to be memory efficient
107+
* This function is called to expand the matrix when x, y or side
108+
* when one or more of them beyond current capacity
109+
*
110+
* Strongly recommend to use when the sizes of dimensions are deterministic
111+
*
112+
* TODO: should have a reserve function but vtd::ndmatrix does not have such API
113+
* as a result, resize can be an internal one while reserve function is a public mutator
114+
*/
115+
void resize_nodes(int x,
116+
int y,
117+
t_rr_type type,
118+
e_side side);
93119

94120
/* -- Internal data storage -- */
95121
private:

vpr/src/route/rr_edge.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef RR_EDGE_H
2+
#define RR_EDGE_H
3+
4+
struct t_rr_edge_info {
5+
t_rr_edge_info(int from, int to, short type) noexcept
6+
: from_node(from)
7+
, to_node(to)
8+
, switch_type(type) {}
9+
10+
int from_node = OPEN;
11+
int to_node = OPEN;
12+
short switch_type = OPEN;
13+
14+
friend bool operator<(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
15+
return std::tie(lhs.from_node, lhs.to_node, lhs.switch_type) < std::tie(rhs.from_node, rhs.to_node, rhs.switch_type);
16+
}
17+
18+
friend bool operator==(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
19+
return std::tie(lhs.from_node, lhs.to_node, lhs.switch_type) == std::tie(rhs.from_node, rhs.to_node, rhs.switch_type);
20+
}
21+
};
22+
23+
typedef std::vector<t_rr_edge_info> t_rr_edge_info_set;
24+
25+
#endif /* RR_EDGE */

vpr/src/route/rr_graph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ static void build_rr_graph(const t_graph_type graph_type,
573573
/* Alloc node lookups, count nodes, alloc rr nodes */
574574
int num_rr_nodes = 0;
575575

576-
alloc_and_load_rr_node_indices(device_ctx.rr_node_indices,
576+
alloc_and_load_rr_node_indices(device_ctx.rr_graph_builder,
577577
max_chan_width, grid,
578578
&num_rr_nodes, chan_details_x, chan_details_y);
579579

vpr/src/route/rr_graph2.cpp

Lines changed: 31 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@ static void load_chan_rr_indices(const int max_chan_width,
3232
const int num_chans,
3333
const t_rr_type type,
3434
const t_chan_details& chan_details,
35-
t_rr_node_indices& indices,
35+
RRGraphBuilder& rr_graph_builder,
3636
int* index);
3737

3838
static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
39-
t_rr_node_indices& indices,
4039
const DeviceGrid& grid,
4140
int* index);
4241

@@ -928,44 +927,40 @@ static void load_chan_rr_indices(const int max_chan_width,
928927
const int num_chans,
929928
const t_rr_type type,
930929
const t_chan_details& chan_details,
931-
t_rr_node_indices& indices,
930+
RRGraphBuilder& rr_graph_builder,
932931
int* index) {
933-
VTR_ASSERT(indices[type].dim_size(0) == size_t(num_chans));
934-
VTR_ASSERT(indices[type].dim_size(1) == size_t(chan_len));
935-
VTR_ASSERT(indices[type].dim_size(2) == NUM_SIDES);
936-
for (int chan = 0; chan < num_chans - 1; ++chan) {
937-
for (int seg = 1; seg < chan_len - 1; ++seg) {
938-
/* Alloc the track inode lookup list */
939-
//Since channels have no side, we just use the first side
940-
indices[type][chan][seg][0].resize(max_chan_width, OPEN);
941-
}
942-
}
943-
944932
for (int chan = 0; chan < num_chans - 1; ++chan) {
945933
for (int seg = 1; seg < chan_len - 1; ++seg) {
946934
/* Assign an inode to the starts of tracks */
947935
int x = (type == CHANX ? seg : chan);
948936
int y = (type == CHANX ? chan : seg);
949937
const t_chan_seg_details* seg_details = chan_details[x][y].data();
950938

951-
for (unsigned track = 0; track < indices[type][chan][seg][0].size(); ++track) {
939+
for (int track = 0; track < max_chan_width; ++track) {
952940
if (seg_details[track].length() <= 0)
953941
continue;
954942

955943
int start = get_seg_start(seg_details, track, chan, seg);
956944

945+
/* TODO: Now we still use the (y, x) convention here for CHANX. Should rework later */
946+
int node_x = chan;
947+
int node_y = start;
948+
if (CHANX == type) {
949+
std::swap(node_x, node_y);
950+
}
951+
957952
/* If the start of the wire doesn't have a inode,
958953
* assign one to it. */
959-
int inode = indices[type][chan][start][0][track];
960-
if (OPEN == inode) {
961-
inode = *index;
954+
RRNodeId inode = rr_graph_builder.node_lookup().find_node(node_x, node_y, type, track, SIDES[0]);
955+
if (!inode) {
956+
inode = RRNodeId(*index);
962957
++(*index);
963958

964-
indices[type][chan][start][0][track] = inode;
959+
rr_graph_builder.node_lookup().add_node(inode, chan, start, type, track, SIDES[0]);
965960
}
966961

967962
/* Assign inode of start of wire to current position */
968-
indices[type][chan][seg][0][track] = inode;
963+
rr_graph_builder.node_lookup().add_node(inode, chan, seg, type, track, SIDES[0]);
969964
}
970965
}
971966
}
@@ -975,7 +970,6 @@ static void load_chan_rr_indices(const int max_chan_width,
975970
* TODO: these building functions should only talk to a RRGraphBuilder object
976971
*/
977972
static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
978-
t_rr_node_indices& indices,
979973
const DeviceGrid& grid,
980974
int* index) {
981975
//Walk through the grid assigning indices to SOURCE/SINK IPIN/OPIN
@@ -991,16 +985,12 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
991985
auto class_type = type->class_inf[iclass].type;
992986
if (class_type == DRIVER) {
993987
rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x, y, SOURCE, iclass, SIDES[0]);
994-
rr_graph_builder.node_lookup().add_node(RRNodeId::INVALID(), x, y, SINK, iclass, SIDES[0]);
995988
} else {
996989
VTR_ASSERT(class_type == RECEIVER);
997990
rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x, y, SINK, iclass, SIDES[0]);
998-
rr_graph_builder.node_lookup().add_node(RRNodeId::INVALID(), x, y, SOURCE, iclass, SIDES[0]);
999991
}
1000992
++(*index);
1001993
}
1002-
VTR_ASSERT(indices[SOURCE][x][y][0].size() == type->class_inf.size());
1003-
VTR_ASSERT(indices[SINK][x][y][0].size() == type->class_inf.size());
1004994

1005995
/* Limited sides for grids
1006996
* The wanted side depends on the location of the grid.
@@ -1068,18 +1058,13 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
10681058
auto class_type = type->class_inf[iclass].type;
10691059

10701060
if (class_type == DRIVER) {
1071-
indices[OPIN][x_tile][y_tile][side].push_back(*index);
1072-
indices[IPIN][x_tile][y_tile][side].push_back(OPEN);
1061+
rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x_tile, y_tile, OPIN, ipin, side);
10731062
assigned_to_rr_node = true;
10741063
} else {
10751064
VTR_ASSERT(class_type == RECEIVER);
1076-
indices[OPIN][x_tile][y_tile][side].push_back(OPEN);
1077-
indices[IPIN][x_tile][y_tile][side].push_back(*index);
1065+
rr_graph_builder.node_lookup().add_node(RRNodeId(*index), x_tile, y_tile, IPIN, ipin, side);
10781066
assigned_to_rr_node = true;
10791067
}
1080-
} else {
1081-
indices[IPIN][x_tile][y_tile][side].push_back(OPEN);
1082-
indices[OPIN][x_tile][y_tile][side].push_back(OPEN);
10831068
}
10841069
}
10851070
}
@@ -1099,25 +1084,6 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
10991084
++(*index);
11001085
}
11011086
}
1102-
1103-
//Sanity check
1104-
for (int width_offset = 0; width_offset < type->width; ++width_offset) {
1105-
int x_tile = x + width_offset;
1106-
for (int height_offset = 0; height_offset < type->height; ++height_offset) {
1107-
int y_tile = y + height_offset;
1108-
for (e_side side : SIDES) {
1109-
//Note that the fast look-up stores all the indices for the pins on each side
1110-
//It has a fixed size (either 0 or the number of pins)
1111-
//Case 0 pins: the side is skipped as no pins are located on it
1112-
//Case number of pins: there are pins on this side
1113-
//and data query can be applied any pin id on this side
1114-
VTR_ASSERT((indices[IPIN][x_tile][y_tile][side].size() == size_t(type->num_pins))
1115-
|| (0 == indices[IPIN][x_tile][y_tile][side].size()));
1116-
VTR_ASSERT((indices[OPIN][x_tile][y_tile][side].size() == size_t(type->num_pins))
1117-
|| (0 == indices[OPIN][x_tile][y_tile][side].size()));
1118-
}
1119-
}
1120-
}
11211087
}
11221088
}
11231089
}
@@ -1132,8 +1098,14 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
11321098
int root_x = x - width_offset;
11331099
int root_y = y - height_offset;
11341100

1135-
indices[SOURCE][x][y][0] = indices[SOURCE][root_x][root_y][0];
1136-
indices[SINK][x][y][0] = indices[SINK][root_x][root_y][0];
1101+
rr_graph_builder.node_lookup().mirror_nodes(vtr::Point<int>(root_x, root_y),
1102+
vtr::Point<int>(x, y),
1103+
SOURCE,
1104+
SIDES[0]);
1105+
rr_graph_builder.node_lookup().mirror_nodes(vtr::Point<int>(root_x, root_y),
1106+
vtr::Point<int>(x, y),
1107+
SINK,
1108+
SIDES[0]);
11371109
}
11381110
}
11391111
}
@@ -1149,7 +1121,7 @@ static void load_block_rr_indices(RRGraphBuilder& rr_graph_builder,
11491121
* This will block us when putting the RRGraphBuilder object as an input arguement
11501122
* of this function
11511123
*/
1152-
void alloc_and_load_rr_node_indices(t_rr_node_indices& indices,
1124+
void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder,
11531125
const int max_chan_width,
11541126
const DeviceGrid& grid,
11551127
int* index,
@@ -1162,20 +1134,20 @@ void alloc_and_load_rr_node_indices(t_rr_node_indices& indices,
11621134
/* Alloc the lookup table */
11631135
for (t_rr_type rr_type : RR_TYPES) {
11641136
if (rr_type == CHANX) {
1165-
indices[rr_type].resize({grid.height(), grid.width(), NUM_SIDES});
1137+
rr_graph_builder.node_lookup().resize_nodes(grid.height(), grid.width(), rr_type, NUM_SIDES);
11661138
} else {
1167-
indices[rr_type].resize({grid.width(), grid.height(), NUM_SIDES});
1139+
rr_graph_builder.node_lookup().resize_nodes(grid.width(), grid.height(), rr_type, NUM_SIDES);
11681140
}
11691141
}
11701142

11711143
/* Assign indices for block nodes */
1172-
load_block_rr_indices(g_vpr_ctx.mutable_device().rr_graph_builder, indices, grid, index);
1144+
load_block_rr_indices(rr_graph_builder, grid, index);
11731145

11741146
/* Load the data for x and y channels */
11751147
load_chan_rr_indices(max_chan_width, grid.width(), grid.height(),
1176-
CHANX, chan_details_x, indices, index);
1148+
CHANX, chan_details_x, rr_graph_builder, index);
11771149
load_chan_rr_indices(max_chan_width, grid.height(), grid.width(),
1178-
CHANY, chan_details_y, indices, index);
1150+
CHANY, chan_details_y, rr_graph_builder, index);
11791151
}
11801152

11811153
bool verify_rr_node_indices(const DeviceGrid& grid, const t_rr_node_indices& rr_node_indices, const t_rr_graph_storage& rr_nodes) {

vpr/src/route/rr_graph2.h

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "build_switchblocks.h"
66
#include "rr_graph_fwd.h"
77
#include "rr_graph_util.h"
8+
#include "rr_graph_builder.h"
89
#include "rr_types.h"
910
#include "device_grid.h"
1011

@@ -15,27 +16,6 @@ enum e_seg_details_type {
1516
SEG_DETAILS_Y
1617
};
1718

18-
struct t_rr_edge_info {
19-
t_rr_edge_info(int from, int to, short type) noexcept
20-
: from_node(from)
21-
, to_node(to)
22-
, switch_type(type) {}
23-
24-
int from_node = OPEN;
25-
int to_node = OPEN;
26-
short switch_type = OPEN;
27-
28-
friend bool operator<(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
29-
return std::tie(lhs.from_node, lhs.to_node, lhs.switch_type) < std::tie(rhs.from_node, rhs.to_node, rhs.switch_type);
30-
}
31-
32-
friend bool operator==(const t_rr_edge_info& lhs, const t_rr_edge_info& rhs) {
33-
return std::tie(lhs.from_node, lhs.to_node, lhs.switch_type) == std::tie(rhs.from_node, rhs.to_node, rhs.switch_type);
34-
}
35-
};
36-
37-
typedef std::vector<t_rr_edge_info> t_rr_edge_info_set;
38-
3919
typedef vtr::NdMatrix<short, 6> t_sblock_pattern;
4020

4121
struct t_opin_connections_scratchpad {
@@ -44,7 +24,7 @@ struct t_opin_connections_scratchpad {
4424

4525
/******************* Subroutines exported by rr_graph2.c *********************/
4626

47-
void alloc_and_load_rr_node_indices(t_rr_node_indices& indices,
27+
void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder,
4828
const int max_chan_width,
4929
const DeviceGrid& grid,
5030
int* index,

vpr/src/route/rr_graph_storage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include "rr_graph_fwd.h"
88
#include "rr_node_fwd.h"
9-
#include "rr_graph2.h"
9+
#include "rr_edge.h"
1010
#include "vtr_log.h"
1111
#include "vtr_memory.h"
1212
#include "vpr_utils.h"

0 commit comments

Comments
 (0)