From c86ff7c82c3fa8f7b220e080c4bffddbde53babc Mon Sep 17 00:00:00 2001 From: Nathan Shreve Date: Mon, 12 Aug 2024 15:24:29 -0400 Subject: [PATCH] Added command-line option for profiler --- utils/route_diag/src/main.cpp | 9 ++- vpr/src/base/SetupVPR.cpp | 1 + vpr/src/base/read_options.cpp | 8 +++ vpr/src/base/read_options.h | 1 + vpr/src/base/vpr_types.h | 1 + vpr/src/route/lookahead_profiler.cpp | 61 +++++++++++-------- vpr/src/route/lookahead_profiler.h | 13 ++-- vpr/src/route/route_net.tpp | 29 +++++++-- vpr/src/route/route_tree.cpp | 38 +++++++++--- vpr/src/route/route_tree.h | 21 ++++++- vpr/src/route/router_delay_profiling.cpp | 18 +++++- .../route/router_lookahead_compressed_map.cpp | 2 +- vpr/test/test_connection_router.cpp | 9 ++- 13 files changed, 159 insertions(+), 52 deletions(-) diff --git a/utils/route_diag/src/main.cpp b/utils/route_diag/src/main.cpp index a15d176337d..bf658bb731c 100644 --- a/utils/route_diag/src/main.cpp +++ b/utils/route_diag/src/main.cpp @@ -130,7 +130,14 @@ static void do_one_route(const Netlist<>& net_list, VTR_ASSERT(cheapest.index == sink_node); vtr::optional rt_node_of_sink; - std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, OPEN, nullptr, router_opts.flat_routing, router.get_router_lookahead(), cost_params, -1, net_list, conn_params.net_id_); + std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, + OPEN, + nullptr, + router_opts.flat_routing, + router.get_router_lookahead(), + cost_params, + net_list, + conn_params.net_id_); //find delay float net_delay = rt_node_of_sink.value().Tdel; diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 2e7d273c267..47fb3290709 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -473,6 +473,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->router_debug_sink_rr = Options.router_debug_sink_rr; RouterOpts->router_debug_iteration = Options.router_debug_iteration; RouterOpts->lookahead_type = Options.router_lookahead_type; + RouterOpts->router_lookahead_profiling = Options.router_lookahead_profiler; RouterOpts->max_convergence_count = Options.router_max_convergence_count; RouterOpts->reconvergence_cpd_threshold = Options.router_reconvergence_cpd_threshold; RouterOpts->initial_timing = Options.router_initial_timing; diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 9e737b78d57..bb271251f11 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -2626,6 +2626,14 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("map") .show_in(argparse::ShowIn::HELP_ONLY); + route_timing_grp.add_argument(args.router_lookahead_profiler, "--router_lookahead_profiler") + .help( + "For every routed sink, records the cost, delay, and congestion estimated by the router lookahead and the " + "actual cost, delay, and congestion, from every node along each route to the sink. These results, along with many " + "other attributes of the node, are recorded into lookahead_verifier_info.csv.") + .default_value("off") + .show_in(argparse::ShowIn::HELP_ONLY); + route_timing_grp.add_argument(args.router_max_convergence_count, "--router_max_convergence_count") .help( "Controls how many times the router is allowed to converge to a legal routing before halting." diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index de98e9c3ca8..68b6157fc5d 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -238,6 +238,7 @@ struct t_options { argparse::ArgValue router_debug_sink_rr; argparse::ArgValue router_debug_iteration; argparse::ArgValue router_lookahead_type; + argparse::ArgValue router_lookahead_profiler; argparse::ArgValue router_max_convergence_count; argparse::ArgValue router_reconvergence_cpd_threshold; argparse::ArgValue router_update_lower_bound_delays; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 0caa0260d94..41356a3750c 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1458,6 +1458,7 @@ struct t_router_opts { int router_debug_sink_rr; int router_debug_iteration; e_router_lookahead lookahead_type; + bool router_lookahead_profiling; int max_convergence_count; float reconvergence_cpd_threshold; e_router_initial_timing initial_timing; diff --git a/vpr/src/route/lookahead_profiler.cpp b/vpr/src/route/lookahead_profiler.cpp index a172ed10438..e9a302e303f 100644 --- a/vpr/src/route/lookahead_profiler.cpp +++ b/vpr/src/route/lookahead_profiler.cpp @@ -11,36 +11,14 @@ #include "vpr_utils.h" #include "re_cluster_util.h" -LookaheadProfiler::LookaheadProfiler() { +LookaheadProfiler::LookaheadProfiler() + : is_empty(true) { lookahead_verifier_csv.open("lookahead_verifier_info.csv", std::ios::out); if (!lookahead_verifier_csv.is_open()) { - VTR_LOG_ERROR("Could not open lookahead_verifier_info.csv", "error"); + VTR_LOG_WARN("Could not open lookahead_verifier_info.csv"); + return; } - - lookahead_verifier_csv - << "iteration no." - << ",source node" - << ",sink node" - << ",sink block name" - << ",sink atom block model" - << ",sink cluster block type" - << ",sink cluster tile height" - << ",sink cluster tile width" - << ",current node" - << ",node type" - << ",node length" - << ",num. nodes from sink" - << ",delta x" - << ",delta y" - << ",actual cost" - << ",actual delay" - << ",actual congestion" - << ",predicted cost" - << ",predicted delay" - << ",predicted congestion" - << ",criticality" - << std::endl; } void LookaheadProfiler::record(int iteration, @@ -54,6 +32,37 @@ void LookaheadProfiler::record(int iteration, const auto& rr_graph = device_ctx.rr_graph; auto& route_ctx = g_vpr_ctx.routing(); + if (!lookahead_verifier_csv.is_open()) + return; + + if (is_empty) { + lookahead_verifier_csv + << "iteration no." + << ",source node" + << ",sink node" + << ",sink block name" + << ",sink atom block model" + << ",sink cluster block type" + << ",sink cluster tile height" + << ",sink cluster tile width" + << ",current node" + << ",node type" + << ",node length" + << ",num. nodes from sink" + << ",delta x" + << ",delta y" + << ",actual cost" + << ",actual delay" + << ",actual congestion" + << ",predicted cost" + << ",predicted delay" + << ",predicted congestion" + << ",criticality" + << std::endl; + + is_empty = false; + } + if (iteration < 1) return; diff --git a/vpr/src/route/lookahead_profiler.h b/vpr/src/route/lookahead_profiler.h index 6a75632ced0..8d1c6c0e3f9 100644 --- a/vpr/src/route/lookahead_profiler.h +++ b/vpr/src/route/lookahead_profiler.h @@ -1,7 +1,3 @@ -// -// Created by shrevena on 08/06/24. -// - #ifndef VTR_LOOKAHEAD_PROFILER_H #define VTR_LOOKAHEAD_PROFILER_H @@ -15,10 +11,17 @@ class LookaheadProfiler { public: LookaheadProfiler(); - void record(int iteration, int target_net_pin_index, const t_conn_cost_params& cost_params, const RouterLookahead& router_lookahead, const ParentNetId& net_id, const Netlist<>& net_list, std::vector branch_inodes); + void record(int iteration, + int target_net_pin_index, + const t_conn_cost_params& cost_params, + const RouterLookahead& router_lookahead, + const ParentNetId& net_id, + const Netlist<>& net_list, + std::vector branch_inodes); private: std::ofstream lookahead_verifier_csv; + bool is_empty; std::unordered_map atom_block_names; std::unordered_map atom_block_models; std::unordered_map cluster_block_types; diff --git a/vpr/src/route/route_net.tpp b/vpr/src/route/route_net.tpp index 9674b2d5d73..188e09e0a44 100644 --- a/vpr/src/route/route_net.tpp +++ b/vpr/src/route/route_net.tpp @@ -190,7 +190,8 @@ inline NetResultFlags route_net(ConnectionRouter& router, spatial_route_tree_lookup, router_stats, is_flat, - itry); + itry, + router_opts); if (flags.success == false) return flags; @@ -298,7 +299,8 @@ inline NetResultFlags pre_route_to_clock_root(ConnectionRouter& router, SpatialRouteTreeLookup& spatial_rt_lookup, RouterStats& router_stats, bool is_flat, - int itry) { + int itry, + const t_router_opts& router_opts) { const auto& device_ctx = g_vpr_ctx.device(); auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& m_route_ctx = g_vpr_ctx.mutable_routing(); @@ -354,8 +356,16 @@ inline NetResultFlags pre_route_to_clock_root(ConnectionRouter& router, * points. Therefore, we can set the net pin index of the sink node to * * OPEN (meaning illegal) as it is not meaningful for this sink. */ vtr::optional new_branch, new_sink; - std::tie(new_branch, new_sink) = tree.update_from_heap(&cheapest, OPEN, ((high_fanout) ? &spatial_rt_lookup : nullptr), is_flat, router.get_router_lookahead(), cost_params, itry, net_list, - conn_params.net_id_); + std::tie(new_branch, new_sink) = tree.update_from_heap(&cheapest, + OPEN, + ((high_fanout) ? &spatial_rt_lookup : nullptr), + is_flat, + router.get_router_lookahead(), + cost_params, + net_list, + conn_params.net_id_, + itry, + router_opts.router_lookahead_profiling); VTR_ASSERT_DEBUG(!high_fanout || validate_route_tree_spatial_lookup(tree.root(), spatial_rt_lookup)); @@ -483,7 +493,16 @@ inline NetResultFlags route_sink(ConnectionRouter& router, profiling::sink_criticality_end(cost_params.criticality); vtr::optional new_branch, new_sink; - std::tie(new_branch, new_sink) = tree.update_from_heap(&cheapest, target_pin, ((high_fanout) ? &spatial_rt_lookup : nullptr), is_flat, router.get_router_lookahead(), cost_params, itry, net_list, conn_params.net_id_); + std::tie(new_branch, new_sink) = tree.update_from_heap(&cheapest, + target_pin, + ((high_fanout) ? &spatial_rt_lookup : nullptr), + is_flat, + router.get_router_lookahead(), + cost_params, + net_list, + conn_params.net_id_, + itry, + router_opts.router_lookahead_profiling); VTR_ASSERT_DEBUG(!high_fanout || validate_route_tree_spatial_lookup(tree.root(), spatial_rt_lookup)); diff --git a/vpr/src/route/route_tree.cpp b/vpr/src/route/route_tree.cpp index c56d52184a6..226d5b315d9 100644 --- a/vpr/src/route/route_tree.cpp +++ b/vpr/src/route/route_tree.cpp @@ -486,13 +486,22 @@ void RouteTree::print(void) const { * This routine returns a tuple: RouteTreeNode of the branch it adds to the route tree and * RouteTreeNode of the SINK it adds to the routing. */ std::tuple, vtr::optional> -RouteTree::update_from_heap(t_heap* hptr, int target_net_pin_index, SpatialRouteTreeLookup* spatial_rt_lookup, bool is_flat, const RouterLookahead& router_lookahead, const t_conn_cost_params cost_params, const int itry, const Netlist<>& net_list, const ParentNetId& net_id) { +RouteTree::update_from_heap(t_heap* hptr, + int target_net_pin_index, + SpatialRouteTreeLookup* spatial_rt_lookup, + bool is_flat, + const RouterLookahead& router_lookahead, + const t_conn_cost_params cost_params, + const Netlist<>& net_list, + const ParentNetId& net_id, + const int itry, + bool profile_lookahead) { /* Lock the route tree for writing. At least on Linux this shouldn't have an impact on single-threaded code */ std::unique_lock write_lock(_write_mutex); //Create a new subtree from the target in hptr to existing routing vtr::optional start_of_new_subtree_rt_node, sink_rt_node; - std::tie(start_of_new_subtree_rt_node, sink_rt_node) = add_subtree_from_heap(hptr, target_net_pin_index, is_flat, router_lookahead, cost_params, itry, net_list, net_id); + std::tie(start_of_new_subtree_rt_node, sink_rt_node) = add_subtree_from_heap(hptr, target_net_pin_index, is_flat, router_lookahead, cost_params, itry, net_list, net_id, profile_lookahead); if (!start_of_new_subtree_rt_node) return {vtr::nullopt, *sink_rt_node}; @@ -515,7 +524,15 @@ RouteTree::update_from_heap(t_heap* hptr, int target_net_pin_index, SpatialRoute * to the SINK indicated by hptr. Returns the first (most upstream) new rt_node, * and the rt_node of the new SINK. Traverses up from SINK */ std::tuple, vtr::optional> -RouteTree::add_subtree_from_heap(t_heap* hptr, int target_net_pin_index, bool is_flat, const RouterLookahead& router_lookahead, const t_conn_cost_params cost_params, const int itry, const Netlist<>& net_list, const ParentNetId& net_id) { +RouteTree::add_subtree_from_heap(t_heap* hptr, + int target_net_pin_index, + bool is_flat, + const RouterLookahead& router_lookahead, + const t_conn_cost_params cost_params, + const int itry, + const Netlist<>& net_list, + const ParentNetId& net_id, + bool profile_lookahead) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; auto& route_ctx = g_vpr_ctx.routing(); @@ -549,12 +566,15 @@ RouteTree::add_subtree_from_heap(t_heap* hptr, int target_net_pin_index, bool is } new_branch_iswitches.push_back(new_iswitch); - g_vpr_ctx.mutable_routing().lookahead_profiler.record(itry, - target_net_pin_index, - cost_params, - router_lookahead, - net_id, - net_list, std::vector()); + if (profile_lookahead) { + g_vpr_ctx.mutable_routing().lookahead_profiler.record(itry, + target_net_pin_index, + cost_params, + router_lookahead, + net_id, + net_list, + new_branch_inodes); + } /* Build the new tree branch starting from the existing node we found */ RouteTreeNode* last_node = _rr_node_to_rt_node[new_inode]; diff --git a/vpr/src/route/route_tree.h b/vpr/src/route/route_tree.h index 8278f87ed41..cafdcedf802 100644 --- a/vpr/src/route/route_tree.h +++ b/vpr/src/route/route_tree.h @@ -358,7 +358,16 @@ class RouteTree { * RouteTreeNode of the SINK it adds to the routing. * Locking operation: only one thread can update_from_heap() a RouteTree at a time. */ std::tuple, vtr::optional> - update_from_heap(t_heap* hptr, int target_net_pin_index, SpatialRouteTreeLookup* spatial_rt_lookup, bool is_flat, const RouterLookahead& router_lookahead, const t_conn_cost_params cost_params, const int itry, const Netlist<>& net_list, const ParentNetId& net_id); + update_from_heap(t_heap* hptr, + int target_net_pin_index, + SpatialRouteTreeLookup* spatial_rt_lookup, + bool is_flat, + const RouterLookahead& router_lookahead, + t_conn_cost_params cost_params, + const Netlist<>& net_list, + const ParentNetId& net_id, + int itry = -1, + bool profile_lookahead = false); /** Reload timing values (R_upstream, C_downstream, Tdel). * Can take a RouteTreeNode& to do an incremental update. @@ -492,7 +501,15 @@ class RouteTree { private: std::tuple, vtr::optional> - add_subtree_from_heap(t_heap* hptr, int target_net_pin_index, bool is_flat, const RouterLookahead& router_lookahead, const t_conn_cost_params cost_params, const int itry, const Netlist<>& net_list, const ParentNetId& net_id); + add_subtree_from_heap(t_heap* hptr, + int target_net_pin_index, + bool is_flat, + const RouterLookahead& router_lookahead, + const t_conn_cost_params cost_params, + const int itry, + const Netlist<>& net_list, + const ParentNetId& net_id, + bool profile_lookahead); void add_non_configurable_nodes(RouteTreeNode* rt_node, bool reached_by_non_configurable_edge, diff --git a/vpr/src/route/router_delay_profiling.cpp b/vpr/src/route/router_delay_profiling.cpp index cf559cad321..32d49256acf 100644 --- a/vpr/src/route/router_delay_profiling.cpp +++ b/vpr/src/route/router_delay_profiling.cpp @@ -121,7 +121,14 @@ bool RouterDelayProfiler::calculate_delay(RRNodeId source_node, VTR_ASSERT(cheapest.index == sink_node); vtr::optional rt_node_of_sink; - std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, OPEN, nullptr, is_flat_, router_.get_router_lookahead(), cost_params, -1, net_list_, conn_params.net_id_); + std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, + OPEN, + nullptr, + is_flat_, + router_.get_router_lookahead(), + cost_params, + net_list_, + conn_params.net_id_); //find delay *net_delay = rt_node_of_sink->Tdel; @@ -208,7 +215,14 @@ vtr::vector calculate_all_path_delays_from_rr_node(RRNodeId src //Build the routing tree to get the delay tree = RouteTree(RRNodeId(src_rr_node)); vtr::optional rt_node_of_sink; - std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&shortest_paths[sink_rr_node], OPEN, nullptr, router_opts.flat_routing, router.get_router_lookahead(), cost_params, -1, net_list, conn_params.net_id_); + std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&shortest_paths[sink_rr_node], + OPEN, + nullptr, + router_opts.flat_routing, + router.get_router_lookahead(), + cost_params, + net_list, + conn_params.net_id_); VTR_ASSERT(rt_node_of_sink->inode == RRNodeId(sink_rr_node)); diff --git a/vpr/src/route/router_lookahead_compressed_map.cpp b/vpr/src/route/router_lookahead_compressed_map.cpp index e9060cd0425..aed3319e8c9 100644 --- a/vpr/src/route/router_lookahead_compressed_map.cpp +++ b/vpr/src/route/router_lookahead_compressed_map.cpp @@ -422,7 +422,7 @@ float CompressedMapLookahead::get_expected_cost(RRNodeId current_node, RRNodeId } } -std::pair CompressedMapLookahead::get_expected_delay_and_cong(RRNodeId from_node, RRNodeId to_node, const t_conn_cost_params& params, float) const { +std::pair CompressedMapLookahead::get_expected_delay_and_cong(RRNodeId from_node, RRNodeId to_node, const t_conn_cost_params& /*params*/, float) const { auto& device_ctx = g_vpr_ctx.device(); auto& rr_graph = device_ctx.rr_graph; diff --git a/vpr/test/test_connection_router.cpp b/vpr/test/test_connection_router.cpp index 9fc3671285f..952333322d5 100644 --- a/vpr/test/test_connection_router.cpp +++ b/vpr/test/test_connection_router.cpp @@ -87,7 +87,14 @@ static float do_one_route(RRNodeId source_node, // Get the delay vtr::optional rt_node_of_sink; - std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, OPEN, nullptr, router_opts.flat_routing, router.get_router_lookahead(), cost_params, -1, net_list, conn_params.net_id_); + std::tie(std::ignore, rt_node_of_sink) = tree.update_from_heap(&cheapest, + OPEN, + nullptr, + router_opts.flat_routing, + router.get_router_lookahead(), + cost_params, + net_list, + conn_params.net_id_); delay = rt_node_of_sink.value().Tdel; }