Skip to content

Print out info/report on overused rr-nodes at the end of a failed routing iteration #1455

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 13 commits into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 2 additions & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)

RouterOpts->check_route = Options.check_route;
RouterOpts->timing_update_type = Options.timing_update_type;

RouterOpts->max_reported_overused_rr_nodes = Options.max_reported_overused_rr_nodes;
}

static void SetupAnnealSched(const t_options& Options,
Expand Down
6 changes: 6 additions & 0 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,12 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
.default_value("off")
.show_in(argparse::ShowIn::HELP_ONLY);

route_grp.add_argument(args.max_reported_overused_rr_nodes, "--max_reported_overused_rr_nodes")
.help(
"Maximum number of overused RR nodes printed when the routing fails")
.default_value("20")
.show_in(argparse::ShowIn::HELP_ONLY);

auto& route_timing_grp = parser.add_argument_group("timing-driven routing options");

route_timing_grp.add_argument(args.astar_fac, "--astar_fac")
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ struct t_options {
argparse::ArgValue<bool> read_rr_edge_metadata;
argparse::ArgValue<bool> exit_after_first_routing_iteration;
argparse::ArgValue<e_check_route_option> check_route;
argparse::ArgValue<int> max_reported_overused_rr_nodes;

/* Timing-driven router options only */
argparse::ArgValue<float> astar_fac;
Expand Down
2 changes: 2 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,8 @@ struct t_router_opts {

e_check_route_option check_route;
e_timing_update_type timing_update_type;

int max_reported_overused_rr_nodes;
};

struct t_analysis_opts {
Expand Down
107 changes: 107 additions & 0 deletions vpr/src/route/route_timing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ static void print_route_status(int itry,
std::shared_ptr<const SetupHoldTimingInfo> timing_info,
float est_success_iteration);

static void print_overused_nodes_status(const t_router_opts& router_opts, const OveruseInfo& overuse_info);
static void print_overused_nodes_header();
static void print_single_overused_node_status(int overuse_index, int inode);

static void print_router_criticality_histogram(const SetupTimingInfo& timing_info,
const ClusteredPinAtomPinsLookup& netlist_pin_lookup);

Expand Down Expand Up @@ -715,6 +719,8 @@ bool try_timing_driven_route_tmpl(const t_router_opts& router_opts,
VTR_LOG("Successfully routed after %d routing iterations.\n", itry);
} else {
VTR_LOG("Routing failed.\n");
//If the routing fails, print the overused info
print_overused_nodes_status(router_opts, overuse_info);
#ifdef VTR_ENABLE_DEBUG_LOGGING
if (f_router_debug) print_invalid_routing_info();
#endif
Expand Down Expand Up @@ -1669,6 +1675,107 @@ static void print_route_status(int itry, double elapsed_sec, float pres_fac, int
fflush(stdout);
}

static void print_overused_nodes_status(const t_router_opts& router_opts, const OveruseInfo& overuse_info) {
//Display upper limit
if (int(overuse_info.overused_nodes) > router_opts.max_reported_overused_rr_nodes) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that if the number of overused nodes is larger than the threshold, we will do nothing.
Should we still report the overuse status and leave a message that the listed nodes are limited by the thresholds set by users.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we'll log the overuse info if the number is small as well as produce an overuse info report file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks! That would be perfect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I assume you want all the nets at the congested node as well? Do you want the report to be indexed by the congested nets or the overused RR nodes?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. Showing all the congested nets will be helpful. I prefer to be indexed by the overused RR Nodes, where we can see what nets share the same the node.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added the nets to the report. You can checkout the report by specifying --generate_rr_node_overuse_report on. I will deal with the strong Id issue soon.

Copy link
Contributor

Choose a reason for hiding this comment

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

Adding the congested nets is a good idea. In addition to printing their ids, I think we should also print their names and the type of driving block. E.g.
net #83 (processor|alu|reset) driven by a block of type CLB
as that can help locate them in the netlist and see patterns faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I forgot about printing more detailed info on the nets. Working on this right now

return;
}

//Print overuse info header
print_overused_nodes_header();

//Print overuse info body
const auto& device_ctx = g_vpr_ctx.device();
const auto& route_ctx = g_vpr_ctx.routing();

int overuse_index = 0;
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
int overuse = route_ctx.rr_node_route_inf[inode].occ() - device_ctx.rr_nodes[inode].capacity();

if (overuse > 0) {
print_single_overused_node_status(overuse_index, inode);
overuse_index++;
}
}

VTR_LOG("Total number of overused nodes: %d\n", overuse_info.overused_nodes);
VTR_LOG("\n");
}

static void print_overused_nodes_header() {
VTR_LOG("\nRouting Failure Diagnostics: Printing Overused Nodes Information\n");
VTR_LOG("------ ------- ---------- --------- -------- ------------ ------- ------- ------- ------- ------- ------- ------------ -----------------\n");
VTR_LOG(" No. Inode Occupancy Capacity RR Node Direction Side PTC Xlow Ylow Xhigh Yhigh Resistance Capacitance\n");
VTR_LOG(" type NUM \n");
VTR_LOG("------ ------- ---------- --------- -------- ------------ ------- ------- ------- ------- ------- ------- ------------ -----------------\n");
}

static void print_single_overused_node_status(int overuse_index, int inode) {
const auto& device_ctx = g_vpr_ctx.device();
const auto& route_ctx = g_vpr_ctx.routing();

//Determines if direction or side is available for printing
auto node_type = device_ctx.rr_nodes[inode].type();

//Overuse #
VTR_LOG("%6d", overuse_index);

//Inode
VTR_LOG(" %7d", inode);

//Occupancy
VTR_LOG(" %10d", route_ctx.rr_node_route_inf[inode].occ());

//Capacity
VTR_LOG(" %9d", device_ctx.rr_nodes[inode].capacity());

//RR node type
VTR_LOG(" %8s", device_ctx.rr_nodes[inode].type_string());

//Direction
if (node_type == e_rr_type::CHANX || node_type == e_rr_type::CHANY) {
VTR_LOG(" %12s", device_ctx.rr_nodes[inode].direction_string());
} else {
VTR_LOG(" %12s", "N/A");
}

//Side
if (node_type == e_rr_type::IPIN || node_type == e_rr_type::OPIN) {
VTR_LOG(" %7s", device_ctx.rr_nodes[inode].side_string());
} else {
VTR_LOG(" %7s", "N/A");
}

//PTC number
VTR_LOG(" %7d", device_ctx.rr_nodes[inode].ptc_num());

//X_low
VTR_LOG(" %7d", device_ctx.rr_nodes[inode].xlow());

//Y_low
VTR_LOG(" %7d", device_ctx.rr_nodes[inode].ylow());

//X_high
VTR_LOG(" %7d", device_ctx.rr_nodes[inode].xhigh());

//Y_high
VTR_LOG(" %7d", device_ctx.rr_nodes[inode].yhigh());

//Resistance
constexpr int RESISTANCE_OP_DIGITS = 12;
constexpr int RESISTANCE_OP_SCI_PRECISION = 2;
pretty_print_float(" ", device_ctx.rr_nodes[inode].R(), RESISTANCE_OP_DIGITS, RESISTANCE_OP_SCI_PRECISION);

//Capacitance
constexpr int CAPACITANCE_OP_DIGITS = 17;
constexpr int CAPACITANCE_OP_SCI_PRECISION = 14;
pretty_print_float(" ", device_ctx.rr_nodes[inode].C(), CAPACITANCE_OP_DIGITS, CAPACITANCE_OP_SCI_PRECISION);

VTR_LOG("\n");

fflush(stdout);
}

static void print_router_criticality_histogram(const SetupTimingInfo& timing_info, const ClusteredPinAtomPinsLookup& netlist_pin_lookup) {
print_histogram(create_criticality_histogram(timing_info, netlist_pin_lookup, 10));
}
Expand Down