Skip to content

[WIP] Per-edge delays #2880

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

Closed
wants to merge 24 commits into from
Closed

[WIP] Per-edge delays #2880

wants to merge 24 commits into from

Conversation

soheilshahrouz
Copy link
Contributor

This PR enables VPR to ingest a file that adds edge-specific delays to switch delays. This way, RR edges that represent the same switch type with the same fanin, can have different delays.

@github-actions github-actions bot added VPR VPR FPGA Placement & Routing Tool libarchfpga Library for handling FPGA Architecture descriptions lang-cpp C/C++ code libvtrutil labels Feb 3, 2025
@soheilshahrouz
Copy link
Contributor Author

A few notes:

  1. In router lookahead construction, I decided to retrieve edge delay from switch type instead of using edge-specific dealys. I feel that using nominal switch delays, assuming they are average of per-edge delays of the same switch type, would make the router lookahead more translation invariant.

  2. I think we should use per-edge delays to compute timing info for a routing tree. For this, RouteTreeNode needs to store the parent edge as well. This change is still to be implemented.

  3. I see that some RouteTree methods like reload_timing_unlocked() and load_route_tree_Tdel() access swtich resistance and capacitance to calculate delay. Should we extent the input file format to enable overriding switch resistance and capacitance in addition to intrinsic delay?

Copy link
Contributor

@vaughnbetz vaughnbetz left a comment

Choose a reason for hiding this comment

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

Some thoughts on how to do this .... good to make a presentation on this for a Thursday meeting.

@@ -1872,6 +1872,20 @@ struct t_rr_switch_inf {
SwitchType type_ = SwitchType::INVALID;
};

struct t_rr_switch_offset_inf {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggest storing all the delay related info here, and not calling this offset (i.e. add in the basic switch delay too, if that's the way the files are supposed to work -- or maybe it's more clear to just override the default delay in a file rather than add to it).

t_rr_switch_offset_inf(const t_rr_switch_inf& switch_inf)
: Tdel(switch_inf.Tdel) {}

auto operator<=>(const t_rr_switch_offset_inf&) const = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Give a comment on what your ordering will be, and why you need it.

rr_switch_inf_.push_back(switch_info);

t_rr_switch_offset_inf switch_offset_info(switch_info);
Copy link
Contributor

Choose a reason for hiding this comment

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

Think of a better long term name -- rr_switch_flyweight? rr_switch_info?

@@ -315,6 +335,9 @@ class RRGraphBuilder {
inline void reserve_switches(size_t num_switches) {
this->rr_switch_inf_.reserve(num_switches);
}
inline void reserve_switch_offse_info(size_t num_offsets) {
Copy link
Contributor

Choose a reason for hiding this comment

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

name mispelt?

@@ -354,6 +360,7 @@ void t_rr_graph_storage::assign_first_edges() {
size_t num_edges = edge_src_node_.size();
VTR_ASSERT(edge_dest_node_.size() == num_edges);
VTR_ASSERT(edge_switch_.size() == num_edges);
VTR_ASSERT(edge_switch_offset_inf_.size() == num_edges);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think one flyweight for edge data would be best, rather than two (switch_inf and edge_switch_offset_inf). Try to store one flyweight id per edge; we can set it up the same way as today during rr-graph building and then update it if the user requests that with an option saying they want a detailed delay file.

@@ -2160,6 +2169,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
RRGraphBuilder* rr_graph_builder_;
RRGraphView* rr_graph_;
vtr::vector<RRSwitchId, t_rr_switch_inf>* rr_switch_inf_;
vtr::vector<RRSwitchOffsetInfoId, t_rr_switch_offset_inf>* rr_switch_offset_inf_;
Copy link
Contributor

Choose a reason for hiding this comment

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

write out the new flyweight I think ... hard not to do that if we merge the flyweight.

@@ -232,6 +232,7 @@ void SetupVPR(const t_options* options,
SetupPackerOpts(*options, packerOpts);
routingArch->write_rr_graph_filename = options->write_rr_graph_file;
routingArch->read_rr_graph_filename = options->read_rr_graph_file;
routingArch->read_rr_edge_delay_offset_filename = options->read_rr_edge_delay_offset_file;
Copy link
Contributor

Choose a reason for hiding this comment

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

probably shouldn't call it offset -- detailed rr_delay file I think

@@ -1623,6 +1623,13 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.metavar("RR_GRAPH_FILE")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.read_rr_edge_delay_offset_file, "--read_rr_edge_delay_offset_file")
Copy link
Contributor

Choose a reason for hiding this comment

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

Offset -> detailed delay

@@ -1416,6 +1416,7 @@ struct t_det_routing_arch {
float R_minW_pmos;

std::string read_rr_graph_filename;
std::string read_rr_edge_delay_offset_filename;
Copy link
Contributor

Choose a reason for hiding this comment

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

delay_offset --> rename

float switch_Tdel = rr_switch_inf_[iswitch].Tdel;
// Instead of looking up the delay from the RR switch type info,
// we call edge_delay() method that returns the exact delay calculated
// by adding edge-specific delays to the nominal delay of switch type
Copy link
Contributor

Choose a reason for hiding this comment

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

Test what the speed impact is of wrapping all the delay calculation functions in accessors, vs. getting an iswitch.
Might also be an opportunity to make the delay calculators more abstract.
Could make a method that returns a tuple of frequently used values in a hot loop if needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also think about whether we should take the Elmore delay model out of the router, and just have a linear delay model that is abstracted (ask for an edge delay, get a delay and you don't know how)

@soheilshahrouz
Copy link
Contributor Author

Superseded by #2930.

@soheilshahrouz soheilshahrouz deleted the per_edge_delay branch April 22, 2025 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang-cpp C/C++ code libarchfpga Library for handling FPGA Architecture descriptions libvtrutil VPR VPR FPGA Placement & Routing Tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants