Fixed memory problem by creating separate function clear_rr_node_to_rt_node
diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp
index b6d5dd4..f5ce456 100644
--- a/vpr/src/draw/draw.cpp
+++ b/vpr/src/draw/draw.cpp
@@ -3240,7 +3240,9 @@
std::reverse(rr_nodes_on_path.begin(), rr_nodes_on_path.end());
if (allocated_route_tree_structs) {
- free_route_tree_timing_structs(); //Clean-up
+ clear_rr_node_to_rt_node(); //Clean-up
+ free_route_tree_timing_structs();
+ //See discussion in route_tree_timing.cpp on clear_rr_node_to_rt_node usage.
}
return rr_nodes_on_path;
}
diff --git a/vpr/src/route/route_timing.cpp b/vpr/src/route/route_timing.cpp
index 85b80e3..8a8a501 100644
--- a/vpr/src/route/route_timing.cpp
+++ b/vpr/src/route/route_timing.cpp
@@ -827,6 +827,9 @@
free(sink_order + 1);
// coverity[offset_free : Intentional]
free(rt_node_of_sink + 1);
+
+ //See discussion in route_tree_timing.cpp on clear_rr_node_to_rt_node usage.
+ clear_rr_node_to_rt_node();
free_route_tree_timing_structs();
}
diff --git a/vpr/src/route/route_tree_timing.cpp b/vpr/src/route/route_tree_timing.cpp
index 5cb0490..e2619ce 100644
--- a/vpr/src/route/route_tree_timing.cpp
+++ b/vpr/src/route/route_tree_timing.cpp
@@ -21,11 +21,7 @@
* about the partial routing during timing-driven routing, so the routines
* in this module are used to keep a tree representation of the partial
* routing during timing-driven routing. This allows rapid incremental
- * timing analysis. The net_delay module does timing analysis in one step
- * (not incrementally as pieces of the routing are added). I could probably
- * one day remove a lot of net_delay.c and call the corresponding routines
- * here, but it's useful to have a from-scratch delay calculator to check
- * the results of this one. */
+ * timing analysis. */
/********************** Variables local to this module ***********************/
@@ -93,6 +89,25 @@
return true;
}
+void clear_rr_node_to_rt_node() {
+ /* This is a function which clears the rr_node_to_rt_node vector.
+ * We do not include this inside free_route_tree_timing_structs()
+ * because of a VTR_SAFE_ASSERT(timing_check_net_delays) in
+ * route_timing.cpp. Doing so would clear the vector during routing
+ * and result in undefined behavior. It is encouraged to use
+ * free_route_tree_timing_structs() with clear_rr_node_to_rt_node()
+ * in external modules.
+ * Example usage:
+ *
+ * module(){
+ * ...
+ * clear_rr_node_to_rt_node();
+ * free_route_tree_timing_structs();
+ * ...
+ * } */
+ rr_node_to_rt_node.clear();
+}
+
void free_route_tree_timing_structs() {
/* Frees the structures needed to build routing trees, and really frees
* (i.e. calls free) all the data on the free lists. */
@@ -100,8 +115,6 @@
t_rt_node *rt_node, *next_node;
t_linked_rt_edge *rt_edge, *next_edge;
- rr_node_to_rt_node.clear();
-
rt_node = rt_node_free_list;
while (rt_node != nullptr) {
diff --git a/vpr/src/route/route_tree_timing.h b/vpr/src/route/route_tree_timing.h
index 8c8c12f..7e17eca 100644
--- a/vpr/src/route/route_tree_timing.h
+++ b/vpr/src/route/route_tree_timing.h
@@ -36,6 +36,8 @@
bool verify_route_tree(t_rt_node* root);
bool verify_traceback_route_tree_equivalent(const t_trace* trace_head, const t_rt_node* rt_root);
+void clear_rr_node_to_rt_node();
+
/********** Incremental reroute ***********/
// instead of ripping up a net that has some congestion, cut the branches
// that don't legally lead to a sink and start routing with that partial route tree
diff --git a/vpr/src/route/router_delay_profiling.cpp b/vpr/src/route/router_delay_profiling.cpp
index 7ed4657..7217eed 100644
--- a/vpr/src/route/router_delay_profiling.cpp
+++ b/vpr/src/route/router_delay_profiling.cpp
@@ -203,5 +203,7 @@
free_route_structs();
free_trace_structs();
+ //See discussion in route_tree_timing.cpp on clear_rr_node_to_rt_node usage.
+ clear_rr_node_to_rt_node();
free_route_tree_timing_structs();
}
diff --git a/vpr/src/timing/net_delay.cpp b/vpr/src/timing/net_delay.cpp
index 38c67cc..93db645 100644
--- a/vpr/src/timing/net_delay.cpp
+++ b/vpr/src/timing/net_delay.cpp
@@ -74,7 +74,7 @@
void load_net_delay_from_routing(vtr::vector<ClusterNetId, float*>& net_delay) {
/* This routine loads net_delay[0..nets.size()-1][1..num_pins-1]. Each entry *
- * is the Elmore delay from the net source to the appropriate sink. Both *
+ * is the Elmore delay from the net source to the appropriate sink. Both *
* the rr_graph and the routing traceback must be completely constructed *
* before this routine is called, and the net_delay array must have been *
* allocated. */
@@ -91,15 +91,15 @@
}
static void load_one_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id) {
- /* This routine loads delay values of one net of the 2-d data structure i.e. *
- * net_delay[net_id][1..num_pins-1]. First, it constructs the route tree *
- * from the traceback, next it updates the values for R, C, and Tdel. *
+ /* This routine loads delay values for one net in *
+ * net_delay[net_id][1..num_pins-1]. First, from the traceback, it *
+ * the route tree and computes its values for R, C, and Tdel. *
* Next, it walks the route tree recursively, storing the time delays for *
* each node into the map inode_to_Tdel. Then, while looping through the *
* net_delay array we search for the inode corresponding to the pin *
- * identifiers, and updated the entry in net_delay. *
- * array during the traversal. Finally, it frees the route tree and clears *
- * the inode_to_Tdel_map associated with that net. */
+ * identifiers, and correspondingly update the entry in net_delay. *
+ * Finally, it frees the route tree and clears the inode_to_Tdel_map *
+ * associated with that net. */
auto& route_ctx = g_vpr_ctx.routing();
@@ -115,14 +115,14 @@
load_new_subtree_R_upstream(rt_root); // load in the resistance values for the route tree
load_new_subtree_C_downstream(rt_root); // load in the capacitance values for the route tree
load_route_tree_Tdel(rt_root, 0.); // load the time delay values for the route tree
- load_one_net_delay_recurr(rt_root, net_id); // recursively the tree and load entries into the inode_to_Tdel map
+ load_one_net_delay_recurr(rt_root, net_id); // recursively traverse the tree and load entries into the inode_to_Tdel map
for (unsigned int ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++) {
inode = route_ctx.net_rr_terminals[net_id][ipin]; // look for the inode corresponding to the net_delay indices
net_delay[net_id][ipin] = inode_to_Tdel_map.find(inode)->second; // search for the value of Tdel in the inode map and load into net_delay
}
free_route_tree(rt_root); // free the route tree
- inode_to_Tdel_map.clear(); // clear the net pairs from the map
+ inode_to_Tdel_map.clear(); // clear the map
}
static void load_one_net_delay_recurr(t_rt_node* node, ClusterNetId net_id) {