Skip to content

RRGraphView node_R(), node_C(), node_rc_index() Implementation #1816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions vpr/src/device/rr_graph_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,6 @@ e_side RRGraph::node_side(const RRNodeId& node) const {
return node_sides_[node];
}

/* Get the resistance of a node */
float RRGraph::node_R(const RRNodeId& node) const {
VTR_ASSERT_SAFE(valid_node_id(node));
return node_Rs_[node];
}

/* Get the capacitance of a node */
float RRGraph::node_C(const RRNodeId& node) const {
VTR_ASSERT_SAFE(valid_node_id(node));
return node_Cs_[node];
}

/*
* Get a segment id of a node in rr_graph
*/
Expand Down
6 changes: 0 additions & 6 deletions vpr/src/device/rr_graph_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,12 +434,6 @@ class RRGraph {
*/
e_side node_side(const RRNodeId& node) const;

/* Get resistance of a node, used to built RC tree for timing analysis */
float node_R(const RRNodeId& node) const;

/* Get capacitance of a node, used to built RC tree for timing analysis */
float node_C(const RRNodeId& node) const;

/* Get segment id of a node, containing the information of the routing
* segment that the node represents. See more details in the data structure t_segment_inf
*/
Expand Down
15 changes: 15 additions & 0 deletions vpr/src/device/rr_graph_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,21 @@ class RRGraphView {
return node_storage_.node_direction_string(node);
}

/* Get the capacitance of a routing resource node. This function is inlined for runtime optimization. */
inline float node_C(RRNodeId node) const {
return node_storage_.node_C(node);
}

/* Get the resistance of a routing resource node. This function is inlined for runtime optimization. */
inline float node_R(RRNodeId node) const {
return node_storage_.node_R(node);
}

/* Get the rc_index of a routing resource node. This function is inlined for runtime optimization. */
inline int16_t node_rc_index(RRNodeId node) const {
return node_storage_.node_rc_index(node);
}

/* Get the fan in of a routing resource node. This function is inlined for runtime optimization. */
inline t_edge_size node_fan_in(RRNodeId node) const {
return node_storage_.fan_in(node);
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/route/check_rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
}

/* Check that the capacitance and resistance are reasonable. */
C = device_ctx.rr_nodes[inode].C();
R = device_ctx.rr_nodes[inode].R();
C = rr_graph.node_C(RRNodeId(inode));
R = rr_graph.node_R(RRNodeId(inode));

if (rr_type == CHANX || rr_type == CHANY) {
if (C < 0. || R < 0.) {
Expand Down
7 changes: 5 additions & 2 deletions vpr/src/route/connection_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,13 +685,16 @@ void ConnectionRouter<Heap>::evaluate_timing_driven_node_costs(t_heap* to,
float switch_Tdel = rr_switch_inf_[iswitch].Tdel;
float switch_Cinternal = rr_switch_inf_[iswitch].Cinternal;

const auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

//To node info
auto rc_index = rr_nodes_.node_rc_index(RRNodeId(to_node));
auto rc_index = rr_graph.node_rc_index(RRNodeId(to_node));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The connection_router object actually caches the rr_graph, in order to avoid the use of global variables. I suggest to add the RRGraphView to the cache here:

ConnectionRouter(
const DeviceGrid& grid,
const RouterLookahead& router_lookahead,
const t_rr_graph_storage& rr_nodes,
const std::vector<t_rr_rc_data>& rr_rc_data,
const std::vector<t_rr_switch_inf>& rr_switch_inf,
std::vector<t_rr_node_route_inf>& rr_node_route_inf)
: grid_(grid)
, router_lookahead_(router_lookahead)
, rr_nodes_(rr_nodes.view())
, rr_rc_data_(rr_rc_data.data(), rr_rc_data.size())
, rr_switch_inf_(rr_switch_inf.data(), rr_switch_inf.size())
, rr_node_route_inf_(rr_node_route_inf.data(), rr_node_route_inf.size())
, router_stats_(nullptr)
, router_debug_(false) {
heap_.init_heap(grid);
heap_.set_prune_limit(rr_nodes_.size(), kHeapPruneFactor * rr_nodes_.size());
}

Then you just use the cached copy rr_graph_ in these functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tangxifan I am trying to add the RRGraphView to the cache with

const RRGraphView& rr_graph, and

, rr_graph_(rr_graph)

But when I try this, the compiler gives me the following warning

error: use of deleted function ‘RRGraphView::RRGraphView(const RRGraphView&)’

Do you know what I am missing? I know that the copy constructors have been disabled in RRGraphView, but perhaps I am supposed to copy to cache in a different way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. You can consider to use the pointer

which works fine in the reader/writer class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyhow, I think the use of const RRGraphView& is better. But not sure the compiler spits out such error.
@hzeller If you have time, can you look into this and share your opinion? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code snippet looks like a call to the deleted copy constructor (but I am just going by the conversation, so I don't see the code in context):
, rr_graph_(rr_graph)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vaughnbetz, I think you are correct. I have implemented the RRGraphView* as @tangxifan suggested, but we could also modify RRGraphView.h so that the copy constructor was no longer deleted if that is what we wanted to do.

float node_C = rr_rc_data_[rc_index].C;
float node_R = rr_rc_data_[rc_index].R;

//From node info
float from_node_R = rr_rc_data_[rr_nodes_.node_rc_index(RRNodeId(from_node))].R;
float from_node_R = rr_rc_data_[rr_graph.node_rc_index(RRNodeId(from_node))].R;

//Update R_upstream
if (switch_buffered) {
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/route/overuse_report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ static void report_overused_chanx_chany(std::ostream& os, RRNodeId node_id) {
os << "Yhigh = " << device_ctx.rr_nodes.node_yhigh(node_id) << '\n';

//Print out associated RC characteristics as they will be non-zero
os << "Resistance = " << device_ctx.rr_nodes.node_R(node_id) << '\n';
os << "Capacitance = " << device_ctx.rr_nodes.node_C(node_id) << '\n';
os << "Resistance = " << rr_graph.node_R(RRNodeId(node_id)) << '\n';
os << "Capacitance = " << rr_graph.node_C(RRNodeId(node_id)) << '\n';
}

///@brief Print out information specific to SOURCE/SINK type rr nodes
Expand Down
33 changes: 19 additions & 14 deletions vpr/src/route/route_tree_timing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ t_rt_node* init_route_tree_to_source(ClusterNetId inet) {

auto& route_ctx = g_vpr_ctx.routing();
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

rt_root = alloc_rt_node();
rt_root->u.child_list = nullptr;
Expand All @@ -195,9 +196,9 @@ t_rt_node* init_route_tree_to_source(ClusterNetId inet) {

rt_root->inode = inode;
rt_root->net_pin_index = OPEN;
rt_root->C_downstream = device_ctx.rr_nodes[inode].C();
rt_root->R_upstream = device_ctx.rr_nodes[inode].R();
rt_root->Tdel = 0.5 * device_ctx.rr_nodes[inode].R() * device_ctx.rr_nodes[inode].C();
rt_root->C_downstream = rr_graph.node_C(RRNodeId(inode));
rt_root->R_upstream = rr_graph.node_R(RRNodeId(inode));
rt_root->Tdel = 0.5 * rr_graph.node_R(RRNodeId(inode)) * rr_graph.node_C(RRNodeId(inode));
rr_node_to_rt_node[inode] = rt_root;

return (rt_root);
Expand Down Expand Up @@ -457,6 +458,7 @@ void load_new_subtree_R_upstream(t_rt_node* rt_node) {
}

auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

t_rt_node* parent_rt_node = rt_node->parent_node;
int inode = rt_node->inode;
Expand All @@ -472,7 +474,7 @@ void load_new_subtree_R_upstream(t_rt_node* rt_node) {
}
R_upstream += device_ctx.rr_switch_inf[iswitch].R; //Parent switch R
}
R_upstream += device_ctx.rr_nodes[inode].R(); //Current node R
R_upstream += rr_graph.node_R(RRNodeId(inode)); //Current node R

rt_node->R_upstream = R_upstream;

Expand All @@ -487,7 +489,8 @@ float load_new_subtree_C_downstream(t_rt_node* rt_node) {

if (rt_node) {
auto& device_ctx = g_vpr_ctx.device();
C_downstream += device_ctx.rr_nodes[rt_node->inode].C();
const auto& rr_graph = device_ctx.rr_graph;
C_downstream += rr_graph.node_C(RRNodeId(rt_node->inode));
for (t_linked_rt_edge* edge = rt_node->u.child_list; edge != nullptr; edge = edge->next) {
/*Similar to net_delay.cpp, this for loop traverses a rc subtree, whose edges represent enabled switches.
* When switches such as multiplexers and tristate buffers are enabled, their fanout
Expand Down Expand Up @@ -573,13 +576,14 @@ void load_route_tree_Tdel(t_rt_node* subtree_rt_root, float Tarrival) {
float Tdel, Tchild;

auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

inode = subtree_rt_root->inode;

/* Assuming the downstream connections are, on average, connected halfway
* along a wire segment's length. See discussion in net_delay.c if you want
* to change this. */
Tdel = Tarrival + 0.5 * subtree_rt_root->C_downstream * device_ctx.rr_nodes[inode].R();
Tdel = Tarrival + 0.5 * subtree_rt_root->C_downstream * rr_graph.node_R(RRNodeId(inode));
subtree_rt_root->Tdel = Tdel;

/* Now expand the children of this node to load their Tdel values (depth-
Expand Down Expand Up @@ -1373,20 +1377,20 @@ bool is_valid_route_tree(const t_rt_node* root) {
short iswitch = root->parent_switch;
if (root->parent_node) {
if (device_ctx.rr_switch_inf[iswitch].buffered()) {
float R_upstream_check = device_ctx.rr_nodes[inode].R() + device_ctx.rr_switch_inf[iswitch].R;
float R_upstream_check = rr_graph.node_R(RRNodeId(inode)) + device_ctx.rr_switch_inf[iswitch].R;
if (!vtr::isclose(root->R_upstream, R_upstream_check, RES_REL_TOL, RES_ABS_TOL)) {
VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, root->R_upstream, R_upstream_check);
return false;
}
} else {
float R_upstream_check = device_ctx.rr_nodes[inode].R() + root->parent_node->R_upstream + device_ctx.rr_switch_inf[iswitch].R;
float R_upstream_check = rr_graph.node_R(RRNodeId(inode)) + root->parent_node->R_upstream + device_ctx.rr_switch_inf[iswitch].R;
if (!vtr::isclose(root->R_upstream, R_upstream_check, RES_REL_TOL, RES_ABS_TOL)) {
VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, root->R_upstream, R_upstream_check);
return false;
}
}
} else if (root->R_upstream != device_ctx.rr_nodes[inode].R()) {
VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, root->R_upstream, device_ctx.rr_nodes[inode].R());
} else if (root->R_upstream != rr_graph.node_R(RRNodeId(inode))) {
VTR_LOG("%d mismatch R upstream %e supposed %e\n", inode, root->R_upstream, rr_graph.node_R(RRNodeId(inode)));
return false;
}

Expand Down Expand Up @@ -1427,7 +1431,7 @@ bool is_valid_route_tree(const t_rt_node* root) {
}
edge = edge->next;
}
float C_downstream_check = C_downstream_children + device_ctx.rr_nodes[inode].C();
float C_downstream_check = C_downstream_children + rr_graph.node_C(RRNodeId(inode));
if (!vtr::isclose(root->C_downstream, C_downstream_check, CAP_REL_TOL, CAP_ABS_TOL)) {
VTR_LOG("%d mismatch C downstream %e supposed %e\n", inode, root->C_downstream, C_downstream_check);
return false;
Expand Down Expand Up @@ -1467,6 +1471,7 @@ init_route_tree_to_source_no_net(int inode) {
t_rt_node* rt_root;

auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

rt_root = alloc_rt_node();
rt_root->u.child_list = nullptr;
Expand All @@ -1475,9 +1480,9 @@ init_route_tree_to_source_no_net(int inode) {
rt_root->re_expand = true;
rt_root->inode = inode;
rt_root->net_pin_index = OPEN;
rt_root->C_downstream = device_ctx.rr_nodes[inode].C();
rt_root->R_upstream = device_ctx.rr_nodes[inode].R();
rt_root->Tdel = 0.5 * device_ctx.rr_nodes[inode].R() * device_ctx.rr_nodes[inode].C();
rt_root->C_downstream = rr_graph.node_C(RRNodeId(inode));
rt_root->R_upstream = rr_graph.node_R(RRNodeId(inode));
rt_root->Tdel = 0.5 * rr_graph.node_R(RRNodeId(inode)) * rr_graph.node_C(RRNodeId(inode));
rr_node_to_rt_node[inode] = rt_root;

return (rt_root);
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/route/router_lookahead_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class PQ_Entry {
this->R_upstream = parent_R_upstream;
if (!starting_node) {
int cost_index = device_ctx.rr_nodes.node_cost_index(RRNodeId(set_rr_node));
//this->delay += g_rr_nodes[set_rr_node].C() * (g_rr_switch_inf[switch_ind].R + 0.5*g_rr_nodes[set_rr_node].R()) +
//this->delay += rr_graph.node_C(RRNodeId(set_rr_node)) * (g_rr_switch_inf[switch_ind].R + 0.5*rr_graph.node_R(RRNodeId(set_rr_node))) +
// g_rr_switch_inf[switch_ind].Tdel;

//FIXME going to use the delay data that the VPR7 lookahead uses. For some reason the delay calculation above calculates
Expand Down
10 changes: 6 additions & 4 deletions vpr/src/route/router_lookahead_map_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ PQ_Entry::PQ_Entry(
this->rr_node = set_rr_node;

auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
this->delay = parent_delay;
this->congestion_upstream = parent_congestion_upstream;
this->R_upstream = parent_R_upstream;
Expand All @@ -78,8 +79,8 @@ PQ_Entry::PQ_Entry(
Tsw += Tsw_adjust;
VTR_ASSERT(Tsw >= 0.f);
float Rsw = device_ctx.rr_switch_inf[switch_ind].R;
float Cnode = device_ctx.rr_nodes[size_t(set_rr_node)].C();
float Rnode = device_ctx.rr_nodes[size_t(set_rr_node)].R();
float Cnode = rr_graph.node_C(set_rr_node);
float Rnode = rr_graph.node_R(set_rr_node);

float T_linear = 0.f;
if (device_ctx.rr_switch_inf[switch_ind].buffered()) {
Expand Down Expand Up @@ -112,10 +113,11 @@ util::PQ_Entry_Delay::PQ_Entry_Delay(

if (parent != nullptr) {
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
float Tsw = device_ctx.rr_switch_inf[switch_ind].Tdel;
float Rsw = device_ctx.rr_switch_inf[switch_ind].R;
float Cnode = device_ctx.rr_nodes[size_t(set_rr_node)].C();
float Rnode = device_ctx.rr_nodes[size_t(set_rr_node)].R();
float Cnode = rr_graph.node_C(set_rr_node);
float Rnode = rr_graph.node_R(set_rr_node);

float T_linear = 0.f;
if (device_ctx.rr_switch_inf[switch_ind].buffered()) {
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/route/rr_graph_indexed_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ static void load_rr_indexed_data_T_values() {
VTR_ASSERT(num_switches > 0);

num_nodes_of_index[cost_index]++;
C_total[cost_index].push_back(rr_nodes[inode].C());
R_total[cost_index].push_back(rr_nodes[inode].R());
C_total[cost_index].push_back(rr_graph.node_C(RRNodeId(inode)));
R_total[cost_index].push_back(rr_graph.node_R(RRNodeId(inode)));

switch_R_total[cost_index].push_back(avg_switch_R);
switch_T_total[cost_index].push_back(avg_switch_T);
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/route/rr_graph_timing_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) {

for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
//The C may have already been partly initialized (e.g. with metal capacitance)
rr_node_C[inode] += device_ctx.rr_nodes[inode].C();
rr_node_C[inode] += rr_graph.node_C(RRNodeId(inode));

from_rr_type = rr_graph.node_type(RRNodeId(inode));

Expand Down Expand Up @@ -191,7 +191,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) {

//Create the final flywieghted t_rr_rc_data
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
mutable_device_ctx.rr_nodes[inode].set_rc_index(find_create_rr_rc_data(device_ctx.rr_nodes[inode].R(), rr_node_C[inode]));
mutable_device_ctx.rr_nodes[inode].set_rc_index(find_create_rr_rc_data(rr_graph.node_R(RRNodeId(inode)), rr_node_C[inode]));
}

free(Couts_to_add);
Expand Down
6 changes: 4 additions & 2 deletions vpr/src/route/rr_graph_uxsdcxx_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,12 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
}

inline float get_node_timing_C(const t_rr_node& node) final {
return node.C();
const auto& rr_graph = (*rr_graph_);
return rr_graph.node_C(node.id());
}
inline float get_node_timing_R(const t_rr_node& node) final {
return node.R();
const auto& rr_graph = (*rr_graph_);
return rr_graph.node_R(node.id());
}

/** Generated for complex type "node_segment":
Expand Down
11 changes: 0 additions & 11 deletions vpr/src/route/rr_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ bool t_rr_node::edge_is_configurable(t_edge_size iedge) const {
return device_ctx.rr_switch_inf[iswitch].configurable();
}

float t_rr_node::R() const {
auto& device_ctx = g_vpr_ctx.device();
return device_ctx.rr_rc_data[rc_index()].R;
}

float t_rr_node::C() const {
auto& device_ctx = g_vpr_ctx.device();
VTR_ASSERT(rc_index() < (short)device_ctx.rr_rc_data.size());
return device_ctx.rr_rc_data[rc_index()].C;
}

bool t_rr_node::validate() const {
//Check internal assumptions about RR node are valid
t_edge_size iedge = 0;
Expand Down
3 changes: 0 additions & 3 deletions vpr/src/route/rr_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,6 @@ class t_rr_node {

bool is_node_on_specific_side(e_side side) const;

float R() const;
float C() const;

bool validate() const;

public: //Mutators
Expand Down