Skip to content

Add PlacerSetupSlacks interface #1450

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
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f4ea4a1
Added interface for mapping between CLB pins and setup slacks. Refact…
Bill-hbrhbr Jul 23, 2020
c024603
Refactored criticalities update in place.cpp and added setup slacks u…
Bill-hbrhbr Jul 23, 2020
cb6e9a6
Fixe up format and compilation errors
Bill-hbrhbr Jul 23, 2020
63db2e1
Merged 3 update routines into 1 single routine
Bill-hbrhbr Jul 31, 2020
aa7b233
Resolve merge conflicts
Bill-hbrhbr Jul 31, 2020
e8f73c6
Resolve more merge conflicts
Bill-hbrhbr Jul 31, 2020
d80de58
Changed crit_exponent to first_crit_exponent/state.crit_exponent
Bill-hbrhbr Jul 31, 2020
831df44
Created a setup slack matrix that copies data from the PlacerSetupSla…
Bill-hbrhbr Aug 6, 2020
d329911
Provided more complete explanation for the record_setup_slacks routine.
Bill-hbrhbr Aug 6, 2020
225870e
Added placement snapshot functions that facilitates the reversion of …
Bill-hbrhbr Aug 6, 2020
9056301
Merge the master branch into PlacerSetupSlacks (updating vtr flow
Bill-hbrhbr Aug 6, 2020
0e01ed7
Implemented do_setup_slack_cost_analysis: softmax of negative slacks
Bill-hbrhbr Aug 6, 2020
2e212dc
Added single move reversion for setup slack analysis(rather than taki…
Bill-hbrhbr Aug 11, 2020
96e65ba
Corrected the timing update and reversion of setup slack analysis dur…
Bill-hbrhbr Aug 14, 2020
112bde5
Moved four boolean global variables controlling the timing update int…
Bill-hbrhbr Aug 14, 2020
29b55a3
Added vpr option --place_quench_metric to turn on/off setup slack ana…
Bill-hbrhbr Aug 20, 2020
da55abf
Merged t_placer_costs and t_placer_prev_inverse_costs and added
Bill-hbrhbr Aug 21, 2020
92c416a
Reduced down the argument list for starting_t, placement_inner_loop, …
Bill-hbrhbr Aug 22, 2020
870eca6
Moved t_placer_costs and t_annealing_state and related routines to pl…
Bill-hbrhbr Aug 22, 2020
a2685c7
Changed major place.cpp data structures from file scope to global sco…
Bill-hbrhbr Aug 23, 2020
cc4488e
Moved timing update routines from place.cpp to place_timing_update.*.…
Bill-hbrhbr Aug 24, 2020
38f25cc
Enchanced documentation for timing_place.*. Moved chanx, chany 2d arr…
Bill-hbrhbr Aug 25, 2020
74d279c
Added documentation for the timing driven routines used in try_swap()…
Bill-hbrhbr Aug 26, 2020
9f18666
Merge branch 'master' into PlacerSetupSlacks
Bill-hbrhbr Aug 26, 2020
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
256 changes: 176 additions & 80 deletions vpr/src/place/place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ static vtr::vector<ClusterNetId, double> net_timing_cost; //Like connection_timi

static vtr::vector<ClusterNetId, t_bb> bb_coords, bb_num_on_edges;

/* Determines if slacks/criticalities need to be updated */
static bool do_update_criticalities = true;
static bool do_update_setup_slacks = true;

/* Determines if slacks/criticalities need to be recomputed from scratch */
static bool do_recompute_criticalities = true;
static bool do_recompute_setup_slacks = true;

/* The arrays below are used to precompute the inverse of the average *
* number of tracks per channel between [subhigh] and [sublow]. Access *
* them as chan?_place_cost_fac[subhigh][sublow]. They are used to *
Expand Down Expand Up @@ -413,23 +421,35 @@ static double get_net_wirelength_estimate(ClusterNetId net_id, t_bb* bbptr);

static void free_try_swap_arrays();

static void outer_loop_recompute_criticalities(const t_placer_opts& placer_opts,
t_placer_costs* costs,
t_placer_prev_inverse_costs* prev_inverse_costs,
int num_connections,
float crit_exponent,
int* outer_crit_iter_count,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info);
static void outer_loop_update_criticalities(const t_placer_opts& placer_opts,
t_placer_costs* costs,
t_placer_prev_inverse_costs* prev_inverse_costs,
int num_connections,
float crit_exponent,
int* outer_crit_iter_count,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info);

static void update_setup_slacks(PlacerSetupSlacks* setup_slacks,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info);

static void update_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs);

static void recompute_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs);
static void update_setup_slacks_and_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
PlacerSetupSlacks* setup_slacks,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs);

static void placement_inner_loop(float t,
int temp_num,
Expand Down Expand Up @@ -519,6 +539,7 @@ void try_place(const t_placer_opts& placer_opts,
std::shared_ptr<PlacementDelayCalculator> placement_delay_calc;
std::unique_ptr<PlaceDelayModel> place_delay_model;
std::unique_ptr<MoveGenerator> move_generator;
std::unique_ptr<PlacerSetupSlacks> placer_setup_slacks;
std::unique_ptr<PlacerCriticalities> placer_criticalities;
std::unique_ptr<ClusteredPinTimingInvalidator> pin_timing_invalidator;

Expand Down Expand Up @@ -586,6 +607,8 @@ void try_place(const t_placer_opts& placer_opts,

timing_info = make_setup_timing_info(placement_delay_calc, placer_opts.timing_update_type);

placer_setup_slacks = std::make_unique<PlacerSetupSlacks>(cluster_ctx.clb_nlist, netlist_pin_lookup);

placer_criticalities = std::make_unique<PlacerCriticalities>(cluster_ctx.clb_nlist, netlist_pin_lookup);

pin_timing_invalidator = std::make_unique<ClusteredPinTimingInvalidator>(cluster_ctx.clb_nlist,
Expand All @@ -594,12 +617,12 @@ void try_place(const t_placer_opts& placer_opts,
atom_ctx.lookup,
*timing_info->timing_graph());
//Update timing and costs
recompute_criticalities(crit_exponent,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get(),
&costs);
update_criticalities(crit_exponent,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get(),
&costs);

timing_info->set_warn_unconstrained(false); //Don't warn again about unconstrained nodes again during placement

Expand Down Expand Up @@ -750,14 +773,14 @@ void try_place(const t_placer_opts& placer_opts,
costs.cost = 1;
}

outer_loop_recompute_criticalities(placer_opts, &costs, &prev_inverse_costs,
num_connections,
crit_exponent,
&outer_crit_iter_count,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get());
outer_loop_update_criticalities(placer_opts, &costs, &prev_inverse_costs,
num_connections,
crit_exponent,
&outer_crit_iter_count,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get());

placement_inner_loop(t, num_temps, rlim, placer_opts,
move_lim, crit_exponent, inner_recompute_limit, &stats,
Expand Down Expand Up @@ -814,15 +837,15 @@ void try_place(const t_placer_opts& placer_opts,
{ /* Quench */
vtr::ScopedFinishTimer temperature_timer("Placement Quench");

outer_loop_recompute_criticalities(placer_opts, &costs,
&prev_inverse_costs,
num_connections,
crit_exponent,
&outer_crit_iter_count,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get());
outer_loop_update_criticalities(placer_opts, &costs,
&prev_inverse_costs,
num_connections,
crit_exponent,
&outer_crit_iter_count,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get());

t = 0; /* freeze out */

Expand Down Expand Up @@ -888,12 +911,12 @@ void try_place(const t_placer_opts& placer_opts,
VTR_ASSERT(timing_info);

//Update timing and costs
recompute_criticalities(crit_exponent,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get(),
&costs);
update_criticalities(crit_exponent,
place_delay_model.get(),
placer_criticalities.get(),
pin_timing_invalidator.get(),
timing_info.get(),
&costs);

critical_path = timing_info->least_slack_critical_path();

Expand Down Expand Up @@ -946,17 +969,17 @@ void try_place(const t_placer_opts& placer_opts,
VTR_LOG("update_td_costs: connections %g nets %g sum_nets %g total %g\n", f_update_td_costs_connections_elapsed_sec, f_update_td_costs_nets_elapsed_sec, f_update_td_costs_sum_nets_elapsed_sec, f_update_td_costs_total_elapsed_sec);
}

/* Function to recompute the criticalities before the inner loop of the annealing */
static void outer_loop_recompute_criticalities(const t_placer_opts& placer_opts,
t_placer_costs* costs,
t_placer_prev_inverse_costs* prev_inverse_costs,
int num_connections,
float crit_exponent,
int* outer_crit_iter_count,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info) {
/* Function to update the criticalities before the inner loop of the annealing */
static void outer_loop_update_criticalities(const t_placer_opts& placer_opts,
t_placer_costs* costs,
t_placer_prev_inverse_costs* prev_inverse_costs,
int num_connections,
float crit_exponent,
int* outer_crit_iter_count,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info) {
if (placer_opts.place_algorithm != PATH_TIMING_DRIVEN_PLACE)
return;

Expand All @@ -971,12 +994,13 @@ static void outer_loop_recompute_criticalities(const t_placer_opts& placer_opts,
VTR_ASSERT(num_connections > 0);

//Update timing information
recompute_criticalities(crit_exponent,
delay_model,
criticalities,
pin_timing_invalidator,
timing_info,
costs);
update_criticalities(crit_exponent,
delay_model,
criticalities,
pin_timing_invalidator,
timing_info,
costs);

*outer_crit_iter_count = 0;
}
(*outer_crit_iter_count)++;
Expand All @@ -988,19 +1012,85 @@ static void outer_loop_recompute_criticalities(const t_placer_opts& placer_opts,
prev_inverse_costs->timing_cost = min(1 / costs->timing_cost, MAX_INV_TIMING_COST);
}

//Update timing information based on current placement by running STA to get new slacks,
//and calculate updated criticalities and timing costs
static void recompute_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs) {
//Update timing information based on current placement by running STA
//and record the new setup slack information
static void update_setup_slacks(PlacerSetupSlacks* setup_slacks,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info) {
//Run STA to update slacks and adjusted/relaxed criticalities
timing_info->update();

//Update placer's setup slacks
setup_slacks->update_setup_slacks(timing_info, do_recompute_setup_slacks);

//Setup slacks are now in sync with the timing_info
//Can perform incremental updates next time
do_recompute_setup_slacks = false;

//Criticalities are now out of sync with the timing_info
//Must do from scratch recompute next time
do_recompute_criticalities = true;

//Clear invalidation state
pin_timing_invalidator->reset();
}

//Update timing information based on current placement by running STA
//and calculate the updated criticalities and timing costs
//(based on the new setup slacks)
static void update_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs) {
//Run STA to update slacks and adjusted/relaxed criticalities
timing_info->update();

//Update placer's criticalities (e.g. sharpen with crit_exponent)
criticalities->update_criticalities(timing_info, crit_exponent, do_recompute_criticalities);

//Update connection, net and total timing costs based on new criticalities
#ifdef INCR_COMP_TD_COSTS
update_td_costs(delay_model, *criticalities, &costs->timing_cost);
#else
comp_td_costs(delay_model, *criticalities, &costs->timing_cost);
#endif

//Criticalities are now in sync with the timing_info
//Can perform incremental updates next time
do_recompute_criticalities = false;

//Setup slacks are now out of sync with the timing_info
//Must do from scratch recompute next time
do_recompute_setup_slacks = true;

//Clear invalidation state
pin_timing_invalidator->reset();
}

//Update timing information based on current placement by running STA.
//Record the new slack information as well as calculate the updated
Copy link
Contributor

Choose a reason for hiding this comment

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

Should comment on any data that's needed by this routine. Location of block according to block.x,.y etc. and the pin_timing_invalidator? Explain what is necessary before you call this routine.

//criticalities and timing costs (based on the new setup slacks)
//
//If both setup slacks and criticalities need to be updated,
//this routine should be called, instead of individual update routine.
//This is to prevent unnecessary from scratch updates
static void update_setup_slacks_and_criticalities(float crit_exponent,
const PlaceDelayModel* delay_model,
PlacerCriticalities* criticalities,
PlacerSetupSlacks* setup_slacks,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
SetupTimingInfo* timing_info,
t_placer_costs* costs) {
//Run STA to update slacks and adjusted/relaxed criticalities
timing_info->update();

//Update placer'criticalities (e.g. sharpen with crit_exponent)
criticalities->update_criticalities(timing_info, crit_exponent);
//Update placer's setup slacks
setup_slacks->update_setup_slacks(timing_info, do_recompute_setup_slacks);

//Update placer's criticalities (e.g. sharpen with crit_exponent)
criticalities->update_criticalities(timing_info, crit_exponent, do_recompute_criticalities);

//Update connection, net and total timing costs based on new criticalities
#ifdef INCR_COMP_TD_COSTS
Expand All @@ -1009,6 +1099,11 @@ static void recompute_criticalities(float crit_exponent,
comp_td_costs(delay_model, *criticalities, &costs->timing_cost);
#endif

//Both Setup slacks and Criticalities are now in sync with the timing_info
//They can be both incrementally updated next time
do_recompute_setup_slacks = false;
do_recompute_criticalities = false;

//Clear invalidation state
pin_timing_invalidator->reset();
}
Expand Down Expand Up @@ -1084,12 +1179,13 @@ static void placement_inner_loop(float t,
/* Using the delays in connection_delay, do a timing analysis to update slacks and
* criticalities and update the timing cost since it will change.
*/
recompute_criticalities(crit_exponent,
delay_model,
criticalities,
pin_timing_invalidator,
timing_info,
costs);
//Update timing information
update_criticalities(crit_exponent,
delay_model,
criticalities,
pin_timing_invalidator,
timing_info,
costs);
}
inner_crit_iter_count++;
}
Expand All @@ -1103,7 +1199,7 @@ static void placement_inner_loop(float t,

/* Lines below prevent too much round-off error from accumulating
* in the cost over many iterations (due to incremental updates).
* This round-off can lead to error checks failing because the cost
* This round-off can lead to error checks failing because the cost
* is different from what you get when you recompute from scratch.
*/
++(*moves_since_cost_recompute);
Expand Down Expand Up @@ -1894,7 +1990,7 @@ static void update_td_costs(const PlaceDelayModel* delay_model, const PlacerCrit
if (cluster_ctx.clb_nlist.net_is_ignored(clb_net)) continue;

int ipin = clb_nlist.pin_net_index(clb_pin);
VTR_ASSERT_SAFE(ipin >= 0 && ipin < int(clb_nlist.net_pins(clb_net).size()));
VTR_ASSERT_SAFE(ipin >= 1 && ipin < int(clb_nlist.net_pins(clb_net).size()));

double new_timing_cost = comp_td_connection_cost(delay_model, place_crit, clb_net, ipin);

Expand Down
Loading