Skip to content

[WIP] Congestion modeling in placement stage #3010

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

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
94fe020
add NetCostHandler::estimate_routing_chann_util()
soheilshahrouz Apr 16, 2025
ee12d6d
fix wl contribution in each direction
soheilshahrouz Apr 16, 2025
cd67bf9
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz Apr 16, 2025
15f76fb
write post-placement estimate of routing chann util
soheilshahrouz Apr 16, 2025
757d1f4
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz Apr 17, 2025
45a5c0c
pass the vector by reference to PrefixSum1D constructor
soheilshahrouz Apr 18, 2025
6b563c0
add acc_chanx_util_ and acc_chany_util_ to NetCostHandler
soheilshahrouz Apr 18, 2025
324d958
Merge branch 'temp_remove_place_move_ctx' into temp_place_est_chan_util
soheilshahrouz Apr 19, 2025
9157961
compute chan utilization ratio instead of occupancy
soheilshahrouz Apr 19, 2025
3bee75c
add NetCostHandler::get_net_cube_cong_cost_()
soheilshahrouz Apr 19, 2025
d0908b9
rename ts_net_avg_chann_util_new_ and net_avg_chann_util_
soheilshahrouz Apr 19, 2025
829585e
Merge branch 'temp_remove_place_move_ctx' into temp_place_est_chan_util
soheilshahrouz Apr 19, 2025
3a2afd3
update per net average chan util in get_bb_from_scratch_()
soheilshahrouz Apr 20, 2025
758eb86
add net_cong_cost_ and proposed_net_cong_cost_
soheilshahrouz Apr 20, 2025
a79878a
take congestion cost into account
soheilshahrouz Apr 21, 2025
fff8954
recompute congestion cost in NetCostHandler
soheilshahrouz Apr 21, 2025
a326c98
update congestion cost norm and consider its contribution when comput…
soheilshahrouz Apr 21, 2025
0a2634e
compute average congestion cost in t_placer_statistics
soheilshahrouz Apr 21, 2025
113d548
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz Apr 22, 2025
f3ec24a
compute congestion cost from scratch in comp_bb_cong_cost() and assig…
soheilshahrouz Apr 22, 2025
57b3c86
initialize acc_chanx_util_ and acc_chany_util_ in constructor
soheilshahrouz Apr 23, 2025
01d917e
add --congestion_acceptance_rate_trigger commmand line option and ena…
soheilshahrouz Apr 23, 2025
e5a51b4
added --congestion_chan_util_threshold command line option
soheilshahrouz Apr 23, 2025
cd6215a
make find_subtile_in_location() definition static
soheilshahrouz Apr 24, 2025
8b395aa
include the last column and row in chan?_util_
soheilshahrouz Apr 24, 2025
a41a256
recompute congestion cost when estimating channel utilization
soheilshahrouz Apr 24, 2025
fab92c1
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz May 1, 2025
7f6c496
weigh congestion cost along x/y axis with the length of bb along that…
soheilshahrouz May 1, 2025
06fe567
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz May 16, 2025
5f11b9b
cherrypick calculate_channel_width();
soheilshahrouz May 16, 2025
b1e78f0
calculate channel utilization by using channel width info extracted f…
soheilshahrouz May 16, 2025
ef70be3
Merge branch 'master' into temp_place_est_chan_util
soheilshahrouz May 19, 2025
3d89417
remove distance factor when computing congestion cost for each net
soheilshahrouz May 23, 2025
898c73d
re-normalize timing-tradeoff
soheilshahrouz May 27, 2025
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: 1 addition & 1 deletion libs/libvtrutil/src/vtr_prefix_sum.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class PrefixSum1D {
/**
* @brief Construct the 1D prefix sum from a vector.
*/
PrefixSum1D(std::vector<T> vals, T zero = T())
PrefixSum1D(const std::vector<T>& vals, T zero = T())
: PrefixSum1D(
vals.size(),
[&](size_t x) noexcept {
Expand Down
3 changes: 3 additions & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts)
PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter;

PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff;
PlacerOpts->congestion_factor = Options.place_congestion_factor;
PlacerOpts->congestion_acceptance_rate_trigger = Options.place_congestion_acceptance_rate_trigger;
PlacerOpts->congestion_chan_util_threshold = Options.place_congestion_chan_util_threshold;

/* Depends on PlacerOpts->place_algorithm */
PlacerOpts->delay_offset = Options.place_delay_offset;
Expand Down
20 changes: 17 additions & 3 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2419,12 +2419,26 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
auto& place_timing_grp = parser.add_argument_group("timing-driven placement options");

place_timing_grp.add_argument(args.PlaceTimingTradeoff, "--timing_tradeoff")
.help(
"Trade-off control between delay and wirelength during placement."
" 0.0 focuses completely on wirelength, 1.0 completely on timing")
.help("Trade-off control between delay and wirelength during placement. "
"0.0 focuses completely on wirelength, 1.0 completely on timing")
.default_value("0.5")
.show_in(argparse::ShowIn::HELP_ONLY);

place_timing_grp.add_argument(args.place_congestion_factor, "--congestion_factor")
.help("To be written")
.default_value("0.0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_timing_grp.add_argument(args.place_congestion_acceptance_rate_trigger, "--congestion_acceptance_rate_trigger")
.help("To be written")
.default_value("0.0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_timing_grp.add_argument(args.place_congestion_chan_util_threshold, "--congestion_chan_util_threshold")
.help("To be written")
.default_value("1.0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_timing_grp.add_argument(args.RecomputeCritIter, "--recompute_crit_iter")
.help("Controls how many temperature updates occur between timing analysis during placement")
.default_value("1")
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ struct t_options {

/* Timing-driven placement options only */
argparse::ArgValue<float> PlaceTimingTradeoff;
argparse::ArgValue<float> place_congestion_factor;
argparse::ArgValue<float> place_congestion_acceptance_rate_trigger;
argparse::ArgValue<float> place_congestion_chan_util_threshold;

argparse::ArgValue<int> RecomputeCritIter;
argparse::ArgValue<int> inner_loop_recompute_divider;
argparse::ArgValue<int> quench_recompute_divider;
Expand Down
54 changes: 36 additions & 18 deletions vpr/src/base/stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,6 @@ static void load_channel_occupancies(const Netlist<>& net_list,
vtr::Matrix<int>& chanx_occ,
vtr::Matrix<int>& chany_occ);

/**
* @brief Writes channel occupancy data to a file.
*
* Each row contains:
* - (x, y) coordinate
* - Occupancy count
* - Occupancy percentage (occupancy / capacity)
* - Channel capacity
*
* @param filename Output file path.
* @param occupancy Matrix of occupancy counts.
* @param capacity_list List of channel capacities (per y for chanx, per x for chany).
*/
static void write_channel_occupancy_table(const std::string_view filename,
const vtr::Matrix<int>& occupancy,
const std::vector<int>& capacity_list);

/**
* @brief Figures out maximum, minimum and average number of bends
* and net length in the routing.
Expand Down Expand Up @@ -132,6 +115,41 @@ void routing_stats(const Netlist<>& net_list,
}
}

std::pair<vtr::NdMatrix<int, 3>, vtr::NdMatrix<int, 3>> calculate_channel_width() {
const auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;

auto chanx_width = vtr::NdMatrix<int, 3>({{(size_t)device_ctx.grid.get_num_layers(),
device_ctx.grid.width(),
device_ctx.grid.height()}},
0);

auto chany_width = vtr::NdMatrix<int, 3>({{(size_t)device_ctx.grid.get_num_layers(),
device_ctx.grid.width(),
device_ctx.grid.height()}},
0);

for (RRNodeId node_id : rr_graph.nodes()) {
e_rr_type rr_type = rr_graph.node_type(node_id);

if (rr_type == e_rr_type::CHANX) {
int y = rr_graph.node_ylow(node_id);
int layer = rr_graph.node_layer(node_id);
for (int x = rr_graph.node_xlow(node_id); x <= rr_graph.node_xhigh(node_id); x++) {
chanx_width[layer][x][y]++;
}
} else if (rr_type == e_rr_type::CHANY) {
int x = rr_graph.node_xlow(node_id);
int layer = rr_graph.node_layer(node_id);
for (int y = rr_graph.node_ylow(node_id); y <= rr_graph.node_yhigh(node_id); y++) {
chany_width[layer][x][y]++;
}
}
}

return {chanx_width, chany_width};
}

void length_and_bends_stats(const Netlist<>& net_list, bool is_flat) {
int max_bends = 0;
int total_bends = 0;
Expand Down Expand Up @@ -251,7 +269,7 @@ static void get_channel_occupancy_stats(const Netlist<>& net_list, bool /***/) {
VTR_LOG("\n");
}

static void write_channel_occupancy_table(const std::string_view filename,
void write_channel_occupancy_table(const std::string_view filename,
const vtr::Matrix<int>& occupancy,
const std::vector<int>& capacity_list) {
constexpr int w_coord = 6;
Expand Down
21 changes: 21 additions & 0 deletions vpr/src/base/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <map>
#include <vector>
#include <string_view>

#include "netlist.h"
#include "rr_graph_type.h"

Expand All @@ -23,6 +25,8 @@ void routing_stats(const Netlist<>& net_list,
int wire_to_ipin_switch,
bool is_flat);

std::pair<vtr::NdMatrix<int, 3>, vtr::NdMatrix<int, 3>> calculate_channel_width();

void print_wirelen_prob_dist(bool is_flat);

void print_lambda();
Expand All @@ -49,3 +53,20 @@ void print_resource_usage();
* @param target_device_utilization The target device utilization set by the user
*/
void print_device_utilization(const float target_device_utilization);

/**
* @brief Writes channel occupancy data to a file.
*
* Each row contains:
* - (x, y) coordinate
* - Occupancy count
* - Occupancy percentage (occupancy / capacity)
* - Channel capacity
*
* @param filename Output file path.
* @param occupancy Matrix of occupancy counts.
* @param capacity_list List of channel capacities (per y for chanx, per x for chany).
*/
void write_channel_occupancy_table(const std::string_view filename,
const vtr::Matrix<int>& occupancy,
const std::vector<int>& capacity_list);
3 changes: 3 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,9 @@ struct t_placer_opts {
t_place_algorithm place_quench_algorithm;
t_annealing_sched anneal_sched; ///<Placement option annealing schedule
float timing_tradeoff;
float congestion_factor;
float congestion_acceptance_rate_trigger;
float congestion_chan_util_threshold;
int place_chan_width;
enum e_pad_loc_type pad_loc_type;
std::string constraints_file;
Expand Down
38 changes: 31 additions & 7 deletions vpr/src/place/annealer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,13 @@ PlacementAnnealer::PlacementAnnealer(const t_placer_opts& placer_opts,
, move_stats_file_(nullptr, vtr::fclose)
, outer_crit_iter_count_(1)
, blocks_affected_(placer_state.block_locs().size())
, quench_started_(false) {
, quench_started_(false)
, congestion_modeling_started_(false) {
const auto& device_ctx = g_vpr_ctx.device();

congestion_factor_ = placer_opts_.congestion_factor;
placer_opts_.congestion_factor = 0.;

float first_crit_exponent;
if (placer_opts.place_algorithm.is_timing_driven()) {
first_crit_exponent = placer_opts.td_place_exp_first; /*this will be modified when rlim starts to change */
Expand Down Expand Up @@ -369,9 +373,10 @@ e_move_result PlacementAnnealer::try_swap_(MoveGenerator& move_generator,

/* I'm using negative values of proposed_net_cost as a flag,
* so DO NOT use cost functions that can go negative. */
double delta_c = 0; //Change in cost due to this swap.
double bb_delta_c = 0; //Change in the bounding box (wiring) cost.
double timing_delta_c = 0; //Change in the timing cost (delay * criticality).
double delta_c = 0.; //Change in cost due to this swap.
double bb_delta_c = 0.; //Change in the bounding box (wiring) cost.
double timing_delta_c = 0.; //Change in the timing cost (delay * criticality).
double congestion_delta_c = 0.;

/* Allow some fraction of moves to not be restricted by rlim,
* in the hopes of better escaping local minima. */
Expand Down Expand Up @@ -449,7 +454,7 @@ e_move_result PlacementAnnealer::try_swap_(MoveGenerator& move_generator,
* delays and timing costs and store them in proposed_* data structures.
*/
net_cost_handler_.find_affected_nets_and_update_costs(delay_model_, criticalities_, blocks_affected_,
bb_delta_c, timing_delta_c);
bb_delta_c, timing_delta_c, congestion_delta_c);

if (place_algorithm == e_place_algorithm::CRITICALITY_TIMING_PLACE) {
/* Take delta_c as a combination of timing and wiring cost. In
Expand All @@ -465,8 +470,9 @@ e_move_result PlacementAnnealer::try_swap_(MoveGenerator& move_generator,
placer_opts_.timing_tradeoff,
timing_delta_c,
costs_.timing_cost_norm);
delta_c = (1 - placer_opts_.timing_tradeoff) * bb_delta_c * costs_.bb_cost_norm
+ placer_opts_.timing_tradeoff * timing_delta_c * costs_.timing_cost_norm;
delta_c = (1 - placer_opts_.timing_tradeoff - placer_opts_.congestion_factor) * bb_delta_c * costs_.bb_cost_norm
+ placer_opts_.timing_tradeoff * timing_delta_c * costs_.timing_cost_norm
+ placer_opts_.congestion_factor * congestion_delta_c * costs_.congestion_cost_norm;
} else if (place_algorithm == e_place_algorithm::SLACK_TIMING_PLACE) {
/* For setup slack analysis, we first do a timing analysis to get the newest
* slack values resulted from the proposed block moves. If the move turns out
Expand Down Expand Up @@ -533,6 +539,7 @@ e_move_result PlacementAnnealer::try_swap_(MoveGenerator& move_generator,
if (move_outcome == e_move_result::ACCEPTED) {
costs_.cost += delta_c;
costs_.bb_cost += bb_delta_c;
costs_.congestion_cost += congestion_delta_c;

if (place_algorithm == e_place_algorithm::CRITICALITY_TIMING_PLACE) {
costs_.timing_cost += timing_delta_c;
Expand Down Expand Up @@ -667,6 +674,23 @@ void PlacementAnnealer::outer_loop_update_timing_info() {
outer_crit_iter_count_++;
}

if (congestion_modeling_started_
|| (annealing_state_.rlim / MoveGenerator::first_rlim) < placer_opts_.congestion_acceptance_rate_trigger) {
costs_.congestion_cost = net_cost_handler_.estimate_routing_chann_util();


if (!congestion_modeling_started_) {
VTR_LOG("Congestion modeling started. %f %f\n", placer_opts_.congestion_factor, placer_opts_.timing_tradeoff);
placer_opts_.congestion_factor = congestion_factor_;
placer_opts_.congestion_factor /= 1.f + congestion_factor_;
// placer_opts_.congestion_factor /= 1.f + placer_opts_.congestion_factor;
placer_opts_.timing_tradeoff /= 1.f + congestion_factor_;
VTR_LOG("Congestion modeling started. %f %f\n", placer_opts_.congestion_factor, placer_opts_.timing_tradeoff);
congestion_modeling_started_ = true;
}

}

// Update the cost normalization factors
costs_.update_norm_factors();

Expand Down
6 changes: 5 additions & 1 deletion vpr/src/place/annealer.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,9 @@ class PlacementAnnealer {
float estimate_starting_temperature_();

private:
const t_placer_opts& placer_opts_;
t_placer_opts placer_opts_;
float congestion_factor_;

PlacerState& placer_state_;
const PlaceMacros& place_macros_;
/// Stores different placement cost terms
Expand Down Expand Up @@ -328,6 +330,8 @@ class PlacementAnnealer {
/// Indicates whether the annealer has entered into the quench stage
bool quench_started_;

bool congestion_modeling_started_;

void LOG_MOVE_STATS_HEADER();
void LOG_MOVE_STATS_PROPOSED();
void LOG_MOVE_STATS_OUTCOME(double delta_cost, double delta_bb_cost, double delta_td_cost, const char* outcome, const char* reason);
Expand Down
10 changes: 5 additions & 5 deletions vpr/src/place/initial_placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,11 @@ static bool is_loc_legal(const t_pl_loc& loc,
return legal;
}

bool find_subtile_in_location(t_pl_loc& centroid,
t_logical_block_type_ptr block_type,
const BlkLocRegistry& blk_loc_registry,
const PartitionRegion& pr,
vtr::RngContainer& rng) {
static bool find_subtile_in_location(t_pl_loc& centroid,
t_logical_block_type_ptr block_type,
const BlkLocRegistry& blk_loc_registry,
const PartitionRegion& pr,
vtr::RngContainer& rng) {
//check if the location is on chip and legal, if yes try to update subtile
if (is_loc_on_chip({centroid.x, centroid.y, centroid.layer}) && is_loc_legal(centroid, pr, block_type)) {
//find the compatible subtiles
Expand Down
Loading
Loading