Skip to content

Commit ab5e24e

Browse files
committed
Hoist lookup outside of nested loops.
Signed-off-by: Keith Rothman <[email protected]>
1 parent 18cfc99 commit ab5e24e

File tree

1 file changed

+58
-53
lines changed

1 file changed

+58
-53
lines changed

vpr/src/base/read_route.cpp

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,21 @@
4444
#include "rr_graph2.h"
4545

4646
/*************Functions local to this module*************/
47-
static void process_route(std::ifstream& fp, const char* filename, int& lineno);
48-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
49-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno);
47+
static void process_route(std::ifstream& fp, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
48+
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
49+
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block);
5050
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno);
5151
static void format_coordinates(int& x, int& y, std::string coord, ClusterNetId net, const char* filename, const int lineno);
5252
static void format_pin_info(std::string& pb_name, std::string& port_name, int& pb_pin_num, std::string input);
53+
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block);
5354
static std::string format_name(std::string name);
5455

5556
/*************Global Functions****************************/
5657
bool read_route(const char* route_file, const t_router_opts& router_opts, bool verify_file_digests) {
5758
/* Reads in the routing file to fill in the trace.head and t_clb_opins_used data structure.
5859
* Perform a series of verification tests to ensure the netlist, placement, and routing
5960
* files match */
60-
auto& device_ctx = g_vpr_ctx.mutable_device();
61+
auto& device_ctx = g_vpr_ctx.device();
6162
auto& place_ctx = g_vpr_ctx.placement();
6263
/* Begin parsing the file */
6364
VTR_LOG("Begin loading FPGA routing file.\n");
@@ -105,8 +106,12 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
105106
header[2].c_str(), header[4].c_str(), device_ctx.grid.width(), device_ctx.grid.height());
106107
}
107108

109+
// Build lookup from SOURCE/SINK node to ClusterBlockId.
110+
std::unordered_map<int, ClusterBlockId> node_to_block;
111+
build_cluster_block_map(&node_to_block);
112+
108113
/* Read in every net */
109-
process_route(fp, route_file, lineno);
114+
process_route(fp, route_file, lineno, node_to_block);
110115

111116
fp.close();
112117

@@ -128,7 +133,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
128133
return is_feasible;
129134
}
130135

131-
static void process_route(std::ifstream& fp, const char* filename, int& lineno) {
136+
static void process_route(std::ifstream& fp, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
132137
/*Walks through every net and add the routing appropriately*/
133138
std::string input;
134139
std::vector<std::string> tokens;
@@ -142,16 +147,56 @@ static void process_route(std::ifstream& fp, const char* filename, int& lineno)
142147
continue; //Skip commented lines
143148
} else if (tokens[0] == "Net") {
144149
ClusterNetId inet(atoi(tokens[1].c_str()));
145-
process_nets(fp, inet, tokens[2], tokens, filename, lineno);
150+
process_nets(fp, inet, tokens[2], tokens, filename, lineno, node_to_block);
146151
}
147152
}
148153

149154
tokens.clear();
150155
}
151156

152-
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno) {
157+
static void build_cluster_block_map(std::unordered_map<int, ClusterBlockId>* node_to_block) {
158+
auto& cluster_ctx = g_vpr_ctx.clustering();
159+
auto& place_ctx = g_vpr_ctx.placement();
160+
auto& device_ctx = g_vpr_ctx.device();
161+
162+
vtr::ScopedStartFinishTimer timer("Building ClusterBlockId lookup");
163+
164+
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
165+
int pin_count = 0;
166+
for (auto pin_id : cluster_ctx.clb_nlist.net_pins(net_id)) {
167+
auto block_id = cluster_ctx.clb_nlist.pin_block(pin_id);
168+
169+
const auto* logical_tile = cluster_ctx.clb_nlist.block_type(block_id);
170+
const auto* physical_tile = physical_tile_type(block_id);
171+
VTR_ASSERT(block_id);
172+
int i = place_ctx.block_locs[block_id].loc.x;
173+
int j = place_ctx.block_locs[block_id].loc.y;
174+
175+
int logical_pin_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
176+
int physical_pin_index = get_physical_pin(
177+
physical_tile, place_ctx.block_locs[block_id].loc.z,
178+
logical_tile, logical_pin_index);
179+
int physical_pin_class = physical_tile->pin_class[physical_pin_index];
180+
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
181+
i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
182+
physical_pin_class);
183+
184+
auto result = node_to_block->insert(std::make_pair(class_inode, block_id));
185+
if (!result.second && result.first->second != block_id) {
186+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
187+
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
188+
class_inode, (size_t)block_id, result.first->second);
189+
}
190+
pin_count++;
191+
}
192+
}
193+
194+
VTR_LOG("ClusterBlockId lookup has %zu entries\n", node_to_block->size());
195+
}
196+
197+
static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
153198
/* Check if the net is global or not, and process appropriately */
154-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
199+
auto& cluster_ctx = g_vpr_ctx.clustering();
155200

156201
if (input_tokens.size() > 3 && input_tokens[3] == "global"
157202
&& input_tokens[4] == "net" && input_tokens[5] == "connecting:") {
@@ -185,19 +230,18 @@ static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name,
185230
name.c_str(), size_t(inet), cluster_ctx.clb_nlist.net_name(inet).c_str());
186231
}
187232

188-
process_nodes(fp, inet, filename, lineno);
233+
process_nodes(fp, inet, filename, lineno, node_to_block);
189234
}
190235
input_tokens.clear();
191236
return;
192237
}
193238

194-
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
239+
static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno, const std::unordered_map<int, ClusterBlockId>& node_to_block) {
195240
/* Not a global net. Goes through every node and add it into trace.head*/
196241

197242
auto& cluster_ctx = g_vpr_ctx.clustering();
198-
auto& device_ctx = g_vpr_ctx.mutable_device();
243+
auto& device_ctx = g_vpr_ctx.device();
199244
auto& route_ctx = g_vpr_ctx.mutable_routing();
200-
auto& place_ctx = g_vpr_ctx.placement();
201245

202246
t_trace* tptr = route_ctx.trace[inet].head;
203247

@@ -208,45 +252,6 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
208252
std::string input;
209253
std::vector<std::string> tokens;
210254

211-
// Build lookup from SOURCE/SINK node to ClusterBlockId.
212-
std::unordered_map<int, ClusterBlockId> node_to_block;
213-
214-
{
215-
vtr::ScopedStartFinishTimer timer("Building ClusterBlockId lookup");
216-
217-
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
218-
int pin_count = 0;
219-
for (auto pin_id : cluster_ctx.clb_nlist.net_pins(net_id)) {
220-
auto block_id = cluster_ctx.clb_nlist.pin_block(pin_id);
221-
222-
const auto* logical_tile = cluster_ctx.clb_nlist.block_type(block_id);
223-
const auto* physical_tile = physical_tile_type(block_id);
224-
VTR_ASSERT(block_id);
225-
int i = place_ctx.block_locs[block_id].loc.x;
226-
int j = place_ctx.block_locs[block_id].loc.y;
227-
228-
int logical_pin_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
229-
int physical_pin_index = get_physical_pin(
230-
physical_tile, place_ctx.block_locs[block_id].loc.z,
231-
logical_tile, logical_pin_index);
232-
int physical_pin_class = physical_tile->pin_class[physical_pin_index];
233-
int class_inode = get_rr_node_index(device_ctx.rr_node_indices,
234-
i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
235-
physical_pin_class);
236-
237-
auto result = node_to_block.insert(std::make_pair(class_inode, block_id));
238-
if (!result.second && result.first->second != block_id) {
239-
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
240-
"Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?",
241-
class_inode, (size_t)block_id, result.first->second);
242-
}
243-
pin_count++;
244-
}
245-
}
246-
247-
VTR_LOG("ClusterBlockId lookup has %zu entries\n", node_to_block.size());
248-
}
249-
250255
/*Walk through every line that begins with Node:*/
251256
while (std::getline(fp, input)) {
252257
++lineno;
@@ -388,7 +393,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
388393
/*This function goes through all the blocks in a global net and verify it with the
389394
* clustered netlist and the placement */
390395
static void process_global_blocks(std::ifstream& fp, ClusterNetId inet, const char* filename, int& lineno) {
391-
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
396+
auto& cluster_ctx = g_vpr_ctx.clustering();
392397
auto& place_ctx = g_vpr_ctx.placement();
393398

394399
std::string block, bnum_str;

0 commit comments

Comments
 (0)