Skip to content

[WIP] Router Lookahead Profiler #2683

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

Draft
wants to merge 30 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
739029b
Created lookahead profiler (restored changes from previous branch)
Jun 26, 2024
aa5570b
LookaheadProfiler now saves sink node info for efficiency
Jun 26, 2024
c88364a
Merge branch 'master' into feature_router_lookahead_verifier
Aug 12, 2024
d406c57
Refactor
Aug 12, 2024
c86ff7c
Added command-line option for profiler
Aug 12, 2024
ddf34eb
Commented LookaheadProfiler
Aug 12, 2024
0826ad7
More comments
Aug 12, 2024
e8ea974
Moved parse_lookahead_data.py
Aug 12, 2024
0b5a752
Moved, refactored, and commented parse_lookahead_data.py
Aug 12, 2024
cbe1334
Fixed multithreading in parsing script
Aug 13, 2024
80086ff
More refactoring, commenting
Aug 13, 2024
c747096
Fixed linting errors in python script
Aug 14, 2024
e753094
Refactored LookaheadProfiler
Aug 14, 2024
d9f4ee3
Eliminated profile_lookahead parameter in update_from_heap
Aug 14, 2024
dfab0a8
Allowed users to enter a file name for profiler output
Aug 14, 2024
c9801b7
Improved multiprocessing efficiency in script
Aug 14, 2024
7fe0b55
Cleaned a few function calls
Aug 15, 2024
c8b196e
LookaheadProfiler::clear() now uses vtr::release_memory()
Aug 15, 2024
ed4460d
Requirements for script added to requirements.txt
Aug 15, 2024
ab2c731
Updated some regtest seeds and golden results
Aug 15, 2024
2db5325
Merge branch 'master' into feature_router_lookahead_verifier
Aug 15, 2024
17ab565
#ifdef-ed extra heap data and added CI test
Aug 20, 2024
595af59
Merge branch 'master' into feature_router_lookahead_verifier
Aug 20, 2024
2f10ec5
Fixed compilation warnings
Aug 20, 2024
9bcad70
Fixed error in record()
Aug 20, 2024
c05e498
Updated golden results
Aug 21, 2024
643811b
Merge branch 'master' into feature_router_lookahead_verifier
Aug 22, 2024
1c9bb58
More updated golden results
Aug 23, 2024
deddc8a
Disabled RCV support for RouterLookahead, comments
Aug 28, 2024
971eebc
Merge branch 'master' into feature_router_lookahead_verifier
Aug 30, 2024
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
Prev Previous commit
Next Next commit
#ifdef-ed extra heap data and added CI test
  • Loading branch information
Nathan Shreve committed Aug 20, 2024
commit 17ab565b6f3bebb1a5748dc0d331a91d8f09dab7
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -156,6 +156,11 @@ jobs:
params: '-DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVPR_USE_EZGL=on -DVPR_USE_SERVER=off',
suite: 'vtr_reg_basic'
},
{
name: 'Basic with PROFILE_LOOKAHEAD',
params: '-DVTR_ASSERT_LEVEL=3 -DVPR_PROFILE_LOOKAHEAD=on',
suite: 'vtr_reg_basic'
},
{
name: 'Basic with CAPNPROTO disabled',
params: '-DCMAKE_COMPILE_WARNING_AS_ERROR=on -DVTR_ASSERT_LEVEL=3 -DWITH_BLIFEXPLORER=on -DVTR_ENABLE_CAPNPROTO=off',
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -42,6 +42,9 @@ option(VTR_ENABLE_CAPNPROTO "Enable capnproto binary serialization support in VP
#Allow the user to decide whether to compile the server module
option(VPR_USE_SERVER "Specify whether vpr enables the server mode" ON)

#Allow the user to decide whether to profile the router lookahead
option(VPR_PROFILE_LOOKAHEAD "Specify whether to enable the router LookaheadProfiler" OFF)

#Allow the user to enable/disable VPR analytic placement
#VPR option --enable_analytic_placer is also required for Analytic Placement
option(VPR_ANALYTIC_PLACE "Enable analytic placement in VPR." ON)
12 changes: 11 additions & 1 deletion vpr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -51,6 +51,16 @@ else()
message(STATUS "Server mode is disabled${SERVER_DISABILED_REASON}")
endif()

#Handle router lookahead profiler setup
set(ROUTER_DEFINES "")

if (VPR_PROFILE_LOOKAHEAD)
list(APPEND ROUTER_DEFINES "-DPROFILE_LOOKAHEAD")
message(STATUS "Router lookahead profiler enabled")
else ()
message(STATUS "Router lookahead profiler disabled")
endif ()

#
# Build Configuration
#
@@ -163,7 +173,7 @@ if (VPR_USE_EZGL STREQUAL "on")

endif()

target_compile_definitions(libvpr PUBLIC ${GRAPHICS_DEFINES} ${SERVER_DEFINES})
target_compile_definitions(libvpr PUBLIC ${GRAPHICS_DEFINES} ${SERVER_DEFINES} ${ROUTER_DEFINES})

if(${VTR_ENABLE_CAPNPROTO})
target_link_libraries(libvpr libvtrcapnproto)
10 changes: 5 additions & 5 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
@@ -1749,11 +1749,7 @@ constexpr bool is_src_sink(e_rr_type type) { return (type == SOURCE || type == S
* the expected cost to the target if the timing_driven router
* is being used.
* @param backward_path_cost Total cost of the path up to and including
* this node. Recorded for LookaheadProfiler.
* @param backward_path_delay Total delay in the path up to and including
* this node. Recorded for LookaheadProfiler.
* @param backward_path_congestion Total congestion in the path up to and
* including this node.
* this node.
* @param occ The current occupancy of the associated rr node
*/
struct t_rr_node_route_inf {
@@ -1762,8 +1758,12 @@ struct t_rr_node_route_inf {
float acc_cost;
float path_cost;
float backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd add a brief comment saying why this extra data is needed for PROFILE_LOOKAHEAD, and that we conditionally compile it because this is a hot and large data structure.

///@brief Total delay in the path up to and including this node.
float backward_path_delay;
///@brief Total congestion in the path up to and including this node.
float backward_path_congestion;
#endif

public: //Accessors
short occ() const { return occ_; }
31 changes: 31 additions & 0 deletions vpr/src/route/connection_router.cpp
Original file line number Diff line number Diff line change
@@ -239,12 +239,21 @@ t_heap* ConnectionRouter<Heap>::timing_driven_route_connection_from_heap(RRNodeI
// This is then placed into the traceback so that the correct path is returned
// TODO: This can be eliminated by modifying the actual traceback function in route_timing
if (rcv_path_manager.is_enabled()) {
#ifdef PROFILE_LOOKAHEAD
rcv_path_manager.insert_backwards_path_into_traceback(cheapest->path_data,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is PROFILE_LOOKAHEAD tested with rcv? If not, we could just choose to not support PROFILE_LOOKAHEAD with RCV to simplify the code a little.

cheapest->cost,
cheapest->backward_path_cost,
cheapest->backward_path_delay,
cheapest->backward_path_congestion,
route_ctx);
#else
rcv_path_manager.insert_backwards_path_into_traceback(cheapest->path_data,
cheapest->cost,
cheapest->backward_path_cost,
/*backward_path_delay=*/0.f,
/*backward_path_congestion=*/0.f,
route_ctx);
#endif
}
VTR_LOGV_DEBUG(router_debug_, " Found target %8d (%s)\n", inode, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode, is_flat_).c_str());
break;
@@ -557,8 +566,10 @@ void ConnectionRouter<Heap>::timing_driven_add_to_heap(const t_conn_cost_params&
// Costs initialized to current
next.cost = std::numeric_limits<float>::infinity(); //Not used directly
next.backward_path_cost = current->backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
next.backward_path_delay = current->backward_path_delay;
next.backward_path_congestion = current->backward_path_congestion;
#endif

// path_data variables are initialized to current values
if (rcv_path_manager.is_enabled() && current->path_data) {
@@ -604,8 +615,10 @@ void ConnectionRouter<Heap>::timing_driven_add_to_heap(const t_conn_cost_params&
next_ptr->cost = next.cost;
next_ptr->R_upstream = next.R_upstream;
next_ptr->backward_path_cost = next.backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
next_ptr->backward_path_delay = next.backward_path_delay;
next_ptr->backward_path_congestion = next.backward_path_congestion;
#endif
next_ptr->index = to_node;
next_ptr->set_prev_edge(from_edge);

@@ -793,8 +806,10 @@ void ConnectionRouter<Heap>::evaluate_timing_driven_node_costs(t_heap* to,
//Update the backward cost (upstream already included)
to->backward_path_cost += (1. - cost_params.criticality) * cong_cost; //Congestion cost
to->backward_path_cost += cost_params.criticality * Tdel; //Delay cost
#ifdef PROFILE_LOOKAHEAD
to->backward_path_delay += Tdel;
to->backward_path_congestion += cong_cost;
#endif

if (cost_params.bend_cost != 0.) {
t_rr_type from_type = rr_graph_->node_type(from_node);
@@ -843,8 +858,10 @@ void ConnectionRouter<Heap>::empty_heap_annotating_node_route_inf() {

rr_node_route_inf_[tmp->index].path_cost = tmp->cost;
rr_node_route_inf_[tmp->index].backward_path_cost = tmp->backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
rr_node_route_inf_[tmp->index].backward_path_delay = tmp->backward_path_delay;
rr_node_route_inf_[tmp->index].backward_path_congestion = tmp->backward_path_congestion;
#endif
modified_rr_node_inf_.push_back(tmp->index);

rcv_path_manager.free_path_struct(tmp->path_data);
@@ -905,8 +922,10 @@ void ConnectionRouter<Heap>::add_route_tree_node_to_heap(
const auto& device_ctx = g_vpr_ctx.device();
const RRNodeId inode = rt_node.inode;
float backward_path_cost = cost_params.criticality * rt_node.Tdel;
#ifdef PROFILE_LOOKAHEAD
float backward_path_delay = rt_node.Tdel;
float backward_path_congestion = 0.0;
#endif
float R_upstream = rt_node.R_upstream;

/* Don't push to heap if not in bounding box: no-op for serial router, important for parallel router */
@@ -928,6 +947,7 @@ void ConnectionRouter<Heap>::add_route_tree_node_to_heap(
tot_cost,
describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode, is_flat_).c_str());

#ifdef PROFILE_LOOKAHEAD
Copy link
Contributor

Choose a reason for hiding this comment

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

You could reverse the order of these two pieces of code with an ifndef so the default flow comes first. Small tweak, but might be a little more user friendly.

push_back_node(&heap_,
rr_node_route_inf_,
inode,
@@ -937,6 +957,17 @@ void ConnectionRouter<Heap>::add_route_tree_node_to_heap(
backward_path_delay,
backward_path_congestion,
R_upstream);
#else
push_back_node(&heap_,
rr_node_route_inf_,
inode,
tot_cost,
/*prev_edge=*/RREdgeId::INVALID(),
backward_path_cost,
/*backward_path_delay=*/0.f,
/*backward_path_congestion=*/0.f,
R_upstream);
#endif
} else {
float expected_total_cost = compute_node_cost_using_rcv(cost_params, inode, target_node, rt_node.Tdel, 0, R_upstream);

3 changes: 3 additions & 0 deletions vpr/src/route/connection_router.h
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
#define _CONNECTION_ROUTER_H

#include "connection_router_interface.h"
#include "lookahead_profiler.h"
#include "rr_graph_storage.h"
#include "route_common.h"
#include "router_lookahead.h"
@@ -153,8 +154,10 @@ class ConnectionRouter : public ConnectionRouterInterface {
route_inf->prev_edge = cheapest->prev_edge();
route_inf->path_cost = cheapest->cost;
route_inf->backward_path_cost = cheapest->backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
route_inf->backward_path_delay = cheapest->backward_path_delay;
route_inf->backward_path_congestion = cheapest->backward_path_congestion;
#endif
}

/** Common logic from timing_driven_route_connection_from_route_tree and
2 changes: 2 additions & 0 deletions vpr/src/route/heap_type.cpp
Original file line number Diff line number Diff line change
@@ -27,8 +27,10 @@ HeapStorage::alloc() {
temp_ptr->set_next_heap_item(nullptr);
temp_ptr->cost = 0.;
temp_ptr->backward_path_cost = 0.;
#ifdef PROFILE_LOOKAHEAD
temp_ptr->backward_path_delay = 0.;
temp_ptr->backward_path_congestion = 0.;
#endif
temp_ptr->R_upstream = 0.;
temp_ptr->index = RRNodeId::INVALID();
temp_ptr->path_data = nullptr;
2 changes: 2 additions & 0 deletions vpr/src/route/heap_type.h
Original file line number Diff line number Diff line change
@@ -18,10 +18,12 @@ struct t_heap {
///@brief The "known" cost of the path up to and including this node. Used only by the timing-driven router. In this case, the
///.cost member contains not only the known backward cost but also an expected cost to the target.
float backward_path_cost = 0.;
#ifdef PROFILE_LOOKAHEAD
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggest adding a comment saying the number of instances of this data structure can be large and it is in hot code, so extra data only needed to profile/verify the lookahead is #ifdef'd

///@brief The "known" delay in the path up to and including this node. Recorded for LookaheadProfiler during routing.
float backward_path_delay = 0.;
///@brief The "known" congestion in the path up to and including this node. Recorded for LookaheadProfiler during routing.
float backward_path_congestion = 0.;
#endif
///@brief Used only by the timing-driven router. Stores the upstream resistance to ground from this node, including the resistance
/// of the node itself (device_ctx.rr_nodes[index].R).
float R_upstream = 0.;
22 changes: 17 additions & 5 deletions vpr/src/route/lookahead_profiler.cpp
Original file line number Diff line number Diff line change
@@ -13,12 +13,11 @@ void LookaheadProfiler::set_file_name(const std::string& file_name) {
if (!enabled_)
return;

#ifdef PROFILE_LOOKAHEAD
lookahead_verifier_csv_.open(file_name, std::ios::out);

if (!lookahead_verifier_csv_.is_open()) {
std::string message = "Could not open " + file_name;
VTR_LOG_ERROR(message.c_str());
throw vtr::VtrError(message, "lookahead_profiler.cpp", 21);
throw vtr::VtrError("Could not open " + file_name, "lookahead_profiler.cpp", 21);
}

lookahead_verifier_csv_
@@ -44,6 +43,9 @@ void LookaheadProfiler::set_file_name(const std::string& file_name) {
<< ",predicted congestion"
<< ",criticality"
<< "\n";
#else
throw vtr::VtrError("Profiler enabled, but PROFILE_LOOKAHEAD not defined.", "lookahead_profiler.cpp", 47);
#endif
}

void LookaheadProfiler::record(int iteration,
@@ -60,9 +62,9 @@ void LookaheadProfiler::record(int iteration,
if (!enabled_)
return;

#ifdef PROFILE_LOOKAHEAD
if (!lookahead_verifier_csv_.is_open()) {
VTR_LOG_ERROR("Output file is not open.");
throw vtr::VtrError("Output file is not open.", "lookahead_profiler.cpp", 65);
throw vtr::VtrError("Output file is not open.", "lookahead_profiler.cpp", 67);
}

// The default value in RouteTree::update_from_heap() is -1; only calls which descend from route_net()
@@ -159,6 +161,16 @@ void LookaheadProfiler::record(int iteration,
lookahead_verifier_csv_ << cost_params.criticality; // criticality
lookahead_verifier_csv_ << "\n";
}
#else
throw vtr::VtrError("Profiler enabled, but PROFILE_LOOKAHEAD not defined.", "lookahead_profiler.cpp", 165);
(void)iteration;
(void)target_net_pin_index;
(void)cost_params;
(void)router_lookahead;
(void)net_id;
(void)net_list;
(void)branch_inodes;
#endif
}

void LookaheadProfiler::clear() {
3 changes: 3 additions & 0 deletions vpr/src/route/lookahead_profiler.h
Original file line number Diff line number Diff line change
@@ -11,6 +11,9 @@
* @brief A class which records information used to profile the router lookahead: most importantly,
* the actual cost (delay and congestion) from nodes to the sink to which they have been routed, as
* well as the lookahead's estimation of this cost.
*
* @warning
* To use the LookaheadProfiler, you must build VPR with #define PROFILE_LOOKAHEAD.
*/
class LookaheadProfiler {
public:
4 changes: 4 additions & 0 deletions vpr/src/route/route_common.cpp
Original file line number Diff line number Diff line change
@@ -289,8 +289,10 @@ void reset_path_costs(const std::vector<RRNodeId>& visited_rr_nodes) {
for (auto node : visited_rr_nodes) {
route_ctx.rr_node_route_inf[node].path_cost = std::numeric_limits<float>::infinity();
route_ctx.rr_node_route_inf[node].backward_path_cost = std::numeric_limits<float>::infinity();
#ifdef PROFILE_LOOKAHEAD
route_ctx.rr_node_route_inf[node].backward_path_delay = std::numeric_limits<float>::infinity();
route_ctx.rr_node_route_inf[node].backward_path_congestion = std::numeric_limits<float>::infinity();
#endif
route_ctx.rr_node_route_inf[node].prev_edge = RREdgeId::INVALID();
}
}
@@ -428,8 +430,10 @@ void reset_rr_node_route_structs() {
node_inf.acc_cost = 1.0;
node_inf.path_cost = std::numeric_limits<float>::infinity();
node_inf.backward_path_cost = std::numeric_limits<float>::infinity();
#ifdef PROFILE_LOOKAHEAD
node_inf.backward_path_delay = std::numeric_limits<float>::infinity();
node_inf.backward_path_congestion = std::numeric_limits<float>::infinity();
#endif
node_inf.set_occ(0);
}
}
5 changes: 5 additions & 0 deletions vpr/src/route/route_common.h
Original file line number Diff line number Diff line change
@@ -173,8 +173,13 @@ t_heap* prepare_to_add_node_to_heap(
hptr->cost = total_cost;
hptr->set_prev_edge(prev_edge);
hptr->backward_path_cost = backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
hptr->backward_path_delay = backward_path_delay;
hptr->backward_path_congestion = backward_path_congestion;
#else
(void)backward_path_delay;
(void)backward_path_congestion;
#endif
hptr->R_upstream = R_upstream;
return hptr;
}
5 changes: 5 additions & 0 deletions vpr/src/route/route_path_manager.cpp
Original file line number Diff line number Diff line change
@@ -53,8 +53,13 @@ void PathManager::insert_backwards_path_into_traceback(t_heap_path* path_data,
route_ctx.rr_node_route_inf[node_2].prev_edge = edge;
route_ctx.rr_node_route_inf[node_2].path_cost = cost;
route_ctx.rr_node_route_inf[node_2].backward_path_cost = backward_path_cost;
#ifdef PROFILE_LOOKAHEAD
route_ctx.rr_node_route_inf[node_2].backward_path_delay = backward_path_delay;
route_ctx.rr_node_route_inf[node_2].backward_path_congestion = backward_path_congestion;
#else
(void)backward_path_delay;
(void)backward_path_congestion;
#endif
}
}