Skip to content

RRGraphView edge_sink_node()/edge_switch() Implementation #1930

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 21 commits into from
Dec 23, 2021
Merged

RRGraphView edge_sink_node()/edge_switch() Implementation #1930

merged 21 commits into from
Dec 23, 2021

Conversation

umariqbal-rs
Copy link
Contributor

Description

In this PR, I am implementing RRGraphView::edge_switch(const RREdgeId& edge) and RRGraphView::edge_switch(RRNodeId id, t_edge_size iedge) throughout VTR. Every time device_ctx.rr_nodes[from_node].edge_switch(iedge); was called has been replaced with rr_graph.edge_switch(EdgeId). In order to do this, I followed a pattern similar to that in the last PR.

Related Issue

Motivation and Context

These changes are a continuation of the RRGraphView API implementation effort

How Has This Been Tested?

Types of changes

  • Bug fix (change which fixes an issue)
  • New feature (change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

@github-actions github-actions bot added the VPR VPR FPGA Placement & Routing Tool label Dec 3, 2021
@umariqbal-rs
Copy link
Contributor Author

@tangxifan
I have created edge_switch() api in rr_grap_view.h and removed it from rr_node_impl.h.

inline short edge_switch(RRNodeId id, t_edge_size iedge) const {

Can Please review it and suggest me how we will move forward?

@@ -1860,7 +1860,8 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
} else {
g->set_color(blk_DARKGREEN);
}
switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
switch_type = rr_graph.edge_switch(RRNodeId(inode), iedge);
;
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant ;

auto& device_ctx = g_vpr_ctx.device();

const auto& rr_graph = device_ctx.rr_graph;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you double check the dependencies among rr_node.cpp and rr_graph_storage.cpp and rr_node_impl.h?>
My understanding, edge_switch() is a method of t_rr_node. We do not need to use the RRGraphView API here.

Copy link
Contributor

Choose a reason for hiding this comment

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

edge_switch() is a method of t_rr_node which is being overridden in rr_node_impl.h. We are introducing the APIs in rr_graph_view.h to delete the functions of rr_node_impl.h. Once #1917 is merged, we will move edge_is_configurable() and validate() from rr_node.cpp to rr_graph_view.h as we are trying to shadow the rr_node.cpp by introducing APIs to rr_graph_view.h

Copy link
Contributor

Choose a reason for hiding this comment

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

Make sense. I am fine with this plan.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please leave a comment

/* TODO: This API should be reworked once rr_switch APIs are in RRGraphView. */

@tangxifan
Copy link
Contributor

@umariqbal-rs Please check failures in CI tests

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
I have created edge_sink_node api in rr_graph_view.h

inline RRNodeId edge_sink_node(RRNodeId id, t_edge_size iedge) const {

We need to type cast and we can't type cast int with RRNodeId so I typed casted it like this
int to_rr_node = size_t(rr_graph.edge_sink_node(RRNodeId(rr_node), iedge));

Can you Please review it, Is that ok? So we can move forward.

@tangxifan
Copy link
Contributor

@umariqbal-rs The type cast is correct. No worries.

@umariqbal-rs
Copy link
Contributor Author

That is great. I will complete tomorrow this API.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
Can you Please review it?

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

@umariqbal-rs Just did a deep dive here. See a few places where we can streamline our codes.

@@ -1689,7 +1689,7 @@ static void draw_rr_edges(int inode, ezgl::renderer* g) {
from_ptc_num = rr_graph.node_ptc_num(RRNodeId(inode));

for (t_edge_size iedge = 0, l = device_ctx.rr_nodes[inode].num_edges(); iedge < l; iedge++) {
to_node = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
to_node = size_t(rr_graph.edge_sink_node(RRNodeId(inode), iedge));
Copy link
Contributor

Choose a reason for hiding this comment

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

I just read the codes of this function. It seems that we can eliminate the use of type casting RRNodeId(inode) and RRNodeId(to_node).
In LINE 1675, you can see the rr_node variable is already defined.
In LINE 1678, you can change the data type of to_node from int to RRNodeId

Then in the rest of this function, you just replace

  • RRNodeId(inode) -> rr_node
  • RRNodeId(to_node) -> to_node.

We can do it in a follow-up PR.

Let me know what you think.

Copy link
Contributor Author

@umariqbal-rs umariqbal-rs Dec 9, 2021

Choose a reason for hiding this comment

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

But if we see at

draw_pin_to_pin(inode, to_node, g);

here in this function argument to_node is as int type. Still RRNodeId(to_node) -> to_node Can be done ?
We can do this by defining a new variable like auto to_node_temp=RRNodeId(inode) So we should by this way ?

Copy link
Contributor

Choose a reason for hiding this comment

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

@umariqbal-rs You can try draw_pin_to_pin(inode, size_t(to_node), g);

Copy link
Contributor

Choose a reason for hiding this comment

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

@umariqbal-rs Can you let me know how many times we have to do the type casting? If it is too much, we can stay with what we have.

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
Type casting with size_t(to_node) is more than the RRNodeId(to_node) so We should stay with the what we have.
Or We should do ?

Copy link
Contributor

Choose a reason for hiding this comment

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

We can stay with what we have now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So should I go on running QoR tests?

if (rr_graph.node_type(RRNodeId(ipin_rr_node)) != IPIN) continue;

for (t_edge_size i_ipin_edge = 0; i_ipin_edge < rr_nodes[ipin_rr_node].num_edges(); ++i_ipin_edge) {
if (sink_rr_node == rr_nodes[ipin_rr_node].edge_sink_node(i_ipin_edge)) {
if (size_t(sink_rr_node) == size_t(rr_graph.edge_sink_node(RRNodeId(ipin_rr_node), i_ipin_edge))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In the for loop (starting from LINE 1169), we can change the data type of

  • opin_rr_node from int to RRNodeId
  • ipin_rr_node from int to RRNodeId

I see in LINE 1174, the num_edges() remain using an old API. I believe that you have patched these line in another PR #1917
It means that we should merge #1917 before this PR.
Let me know if this is fine for you or not.

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

@umariqbal-rs Changes look good. Just minor comments left. Can you start QoR tests?

if (node.edge_sink_node(edge_idx) != OPEN) {
if (rr_node_power[node.edge_sink_node(edge_idx)].driver_switch_type == OPEN) {
rr_node_power[node.edge_sink_node(edge_idx)].driver_switch_type = node.edge_switch(edge_idx);
if (size_t(rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx)) != size_t(OPEN)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Using the new API, you do not need the OPEN. This can be simplified as

if (rr_graph.edge_sink_node(RRNodeId(rr_node_idx), edge_idx)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure I will do that on Monday.

auto& device_ctx = g_vpr_ctx.device();

const auto& rr_graph = device_ctx.rr_graph;
Copy link
Contributor

Choose a reason for hiding this comment

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

Make sense. I am fine with this plan.

@tangxifan
Copy link
Contributor

@umariqbal-rs Waiting for the QoR tests. Code changes look good.

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

It seems that @umariqbal-rs you reverted back to old APIs when resolving merging conflicts.

@@ -1166,17 +1166,17 @@ bool directconnect_exists(int src_rr_node, int sink_rr_node) {
VTR_ASSERT(rr_graph.node_type(RRNodeId(src_rr_node)) == SOURCE && rr_graph.node_type(RRNodeId(sink_rr_node)) == SINK);

//TODO: This is a constant depth search, but still may be too slow
for (t_edge_size i_src_edge = 0; i_src_edge < rr_graph.num_edges(RRNodeId(src_rr_node)); ++i_src_edge) {
int opin_rr_node = rr_nodes[src_rr_node].edge_sink_node(i_src_edge);
for (t_edge_size i_src_edge = 0; i_src_edge < rr_nodes[src_rr_node].num_edges(); ++i_src_edge) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
I have encountered a warning

auto& parent_node = rr_nodes[size_t(parent)];

The parent_node is unused here.Its ok I can remove it but than
void expand_dijkstra_neighbours(const t_rr_graph_storage& rr_nodes,

rr_nodes become unused.
If we
static void expand_dijkstra_neighbours(PQ_Entry parent_entry, vtr::vector<RRNodeId, float>& node_visited_costs, vtr::vector<RRNodeId, bool>& node_expanded, std::priority_queue<PQ_Entry>& pq) {

In above function is used like this
auto& rr_graph = device_ctx.rr_nodes;

and also edge_sink_node and edge_switch are not using API from rr_graph_view.h
RRNodeId child_node = rr_graph.edge_sink_node(edge);

Can you suggest me how to remove this warning?

@tangxifan
Copy link
Contributor

@umariqbal-rs The warning can be avoided by deleting LINE 266. The variable parent_node is now unused in the function. It can be safely removed.

Also since this PR will finish all the edge-related APIs, it is safe to remove the workarounds at

const auto& temp_rr_graph = device_ctx.rr_graph; //TODO rename to rr_graph once the rr_graph below is unneeded
auto& rr_graph = device_ctx.rr_nodes;

where you can

  • remove LINE 652
  • rename temp_rr_graph to rr_graph in LINE 651.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
I have deleted parent_node

auto& parent_node = rr_nodes[size_t(parent)];

But still we got unused variable from line 255 rr_nodes
void expand_dijkstra_neighbours(const t_rr_graph_storage& rr_nodes,

How can I remove this variable or avoid this warning? I need your suggestion.

@tangxifan
Copy link
Contributor

@umariqbal-rs Yes. Please remove the unused argument. It may cause large code changes. Can you do a grep on the expand_dijkstra_neighbours? See how many lines will be expected.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
I have already done this and removed. But I got some unknown error like in compute function .

@tangxifan
Copy link
Contributor

@umariqbal-rs Would you mind sharing more details, such as error messages?

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
We have removed warnings.
We can't remove temp_rr_graph from here

const auto& temp_rr_graph = device_ctx.rr_graph; //TODO rename to rr_graph once the rr_graph below is unneeded

because in
for (RREdgeId edge : rr_graph.edge_range(parent)) {
we don't have API of edge_range yet.

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

@umariqbal-rs Some final comments.

auto& device_ctx = g_vpr_ctx.device();

const auto& rr_graph = device_ctx.rr_graph;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please leave a comment

/* TODO: This API should be reworked once rr_switch APIs are in RRGraphView. */

@@ -288,15 +285,13 @@ void expand_dijkstra_neighbours(const t_rr_graph_storage& rr_nodes,
}
}

template void expand_dijkstra_neighbours(const t_rr_graph_storage& rr_nodes,
const PQ_Entry_Delay& parent_entry,
template void expand_dijkstra_neighbours(const PQ_Entry_Delay& parent_entry,
Copy link
Contributor

Choose a reason for hiding this comment

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

We should avoid the use of global variables.
Can you just replace the const t_rr_graph_storage& rr_nodes, with const RRGraphView& rr_graph?

Copy link
Contributor Author

@umariqbal-rs umariqbal-rs Dec 20, 2021

Choose a reason for hiding this comment

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

We have already removed rr_nodes from here. Because that was unused. And if it is used in some other files then edge_range API should be in rr_graph to remove rr_nodes from those files, as I mentioned above in comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Removing the rr_nodes is correct. Can you bring the RRGraphView to the input argument list of this function?

For edge_range, I will read more codes and tell you how to proceed. For this PR, it seems o.k. We will rework it in later PRs. Let me know if you have any question.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK that is fine. Today in morning I will do that. I have already run the QoR tests should I run again after putting this argument.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. We need to rerun the regression because this function is called many times in aglorithms.
Also, feel free share existing QoR test results. I can take a look.

Copy link
Contributor Author

@umariqbal-rs umariqbal-rs Dec 21, 2021

Choose a reason for hiding this comment

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

These are results before adding RRGraphView& rr_graph in arguments.

vtr_reg_qor_chain_depop test
Flow run time -0.1% on average.
critical path delay 0% on average.
Peak memory usage 0.03% on average

titan_quick_qor test:
flow run time 3.65% on average.
critical path delay 0% on average.
Peak memory usage 0% on average

titan_quick_qor.xlsx
vtr_reg_qor_chain_depop.xlsx

Copy link
Contributor

Choose a reason for hiding this comment

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

The QoR result looks good. is it against current master or a specific branch test_basic_sanity?
I think the final QoR should also look fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its against test_basic_sanity.

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

@umariqbal-rs Good to go from my side. Please upload the latest QoR test results. Once CI is green, I will propose to merge. Thank you for hard working.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
It's my pleasure.
CI is already green .In morning I will upload new results.

@tangxifan
Copy link
Contributor

@tangxifan It's my pleasure. CI is already green .In morning I will upload new results.

Yes. Looking forward to the new results.

@umariqbal-rs
Copy link
Contributor Author

umariqbal-rs commented Dec 22, 2021

@tangxifan
vtr_reg_qor_chain_depop test:

Flow run time 1.51% on average.
critical path delay 0% on average.
Peak memory usage 1.57% on average

titan_quick_qor test:

flow run time 12.21% on average.
critical path delay 0% on average.
Peak memory usage 0.02% on average

titan_quick_qor.xlsx
vtr_reg_qor_chain_depop.xlsx

@tangxifan
Copy link
Contributor

@umariqbal-rs Can you also run the test against current master? The 12% flow time overhead looks like a concern.

@umariqbal-rs
Copy link
Contributor Author

@tangxifan
sure I am doing.

@umariqbal-rs
Copy link
Contributor Author

umariqbal-rs commented Dec 23, 2021

@tangxifan
Below are the QoR Results with current master:
vtr_reg_qor_chain_depop test:
Flow run time 2.05% on average.
critical path delay 0% on average.
Peak memory usage -8.83% on average

titan_quick_qor test:

flow run time -11.59% on average.
critical path delay 0% on average.
Peak memory usage 0.02% on average
titan_quick_qor.xlsx
vtr_reg_qor_chain_depop.xlsx

Copy link
Contributor

@tangxifan tangxifan left a comment

Choose a reason for hiding this comment

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

@umariqbal-rs Thanks for the good work.
@vaughnbetz I propose to merge this PR, because

  • Code changes are clean (I have performed 3 rounds of code reviews)
  • QoR tests show no overhead

If you see any issues, please feel free to comment. We will address it in a follow PR.

@tangxifan tangxifan merged commit 1333ba7 into verilog-to-routing:master Dec 23, 2021
@tangxifan tangxifan deleted the edge_switch/edge_sink_node branch December 23, 2021 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation VPR VPR FPGA Placement & Routing Tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants