Skip to content

Commit dac4668

Browse files
Bill-hbrhbrvaughnbetz
authored andcommitted
Moved t_placer_statistics to place_utils.h/cpp and implemented update routines to faciliate code modularization. Added documentation and cleaned up the argument list of related routines.
1 parent 2f1c08d commit dac4668

File tree

3 files changed

+118
-88
lines changed

3 files changed

+118
-88
lines changed

vpr/src/place/place.cpp

Lines changed: 22 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,6 @@ enum e_cost_methods {
8585
CHECK
8686
};
8787

88-
struct t_placer_statistics {
89-
double av_cost, av_bb_cost, av_timing_cost,
90-
sum_of_squares;
91-
int success_sum;
92-
};
93-
9488
constexpr float INVALID_DELAY = std::numeric_limits<float>::quiet_NaN();
9589
constexpr float INVALID_COST = std::numeric_limits<double>::quiet_NaN();
9690

@@ -373,26 +367,18 @@ static void recompute_costs_from_scratch(const t_placer_opts& placer_opts,
373367
const PlacerCriticalities* criticalities,
374368
t_placer_costs* costs);
375369

376-
static void calc_placer_stats(t_placer_statistics& stats, double& std_dev, const t_placer_costs& costs);
377-
378370
static void generate_post_place_timing_reports(const t_placer_opts& placer_opts,
379371
const t_analysis_opts& analysis_opts,
380372
const SetupTimingInfo& timing_info,
381373
const PlacementDelayCalculator& delay_calc);
382374

383375
static void print_place_status_header();
384-
static void print_place_status(const size_t num_temps,
385-
const float elapsed_sec,
386-
const float t,
387-
const float alpha,
376+
static void print_place_status(const t_annealing_state& state,
388377
const t_placer_statistics& stats,
389-
const float cpd,
390-
const float sTNS,
391-
const float sWNS,
392-
const float acc_rate,
393-
const float std_dev,
394-
const float rlim,
395-
const float crit_exponent,
378+
float elapsed_sec,
379+
float cpd,
380+
float sTNS,
381+
float sWNS,
396382
size_t tot_moves);
397383
static void print_resources_utilization();
398384

@@ -431,7 +417,6 @@ void try_place(const t_placer_opts& placer_opts,
431417
float sTNS = NAN;
432418
float sWNS = NAN;
433419

434-
double std_dev;
435420
char msg[vtr::bufsize];
436421
t_placer_statistics stats;
437422

@@ -697,10 +682,6 @@ void try_place(const t_placer_opts& placer_opts,
697682
placer_opts.place_algorithm);
698683

699684
tot_iter += state.move_lim;
700-
701-
state.success_rate = ((float)stats.success_sum) / state.move_lim;
702-
calc_placer_stats(stats, std_dev, costs);
703-
704685
++state.num_temps;
705686

706687
if (placer_opts.place_algorithm.is_timing_driven()) {
@@ -709,12 +690,7 @@ void try_place(const t_placer_opts& placer_opts,
709690
sWNS = timing_info->setup_worst_negative_slack();
710691
}
711692

712-
print_place_status(state.num_temps,
713-
temperature_timer.elapsed_sec(),
714-
state.t, state.alpha,
715-
stats,
716-
critical_path.delay(), sTNS, sWNS,
717-
state.success_rate, std_dev, state.rlim, state.crit_exponent, tot_iter);
693+
print_place_status(state, stats, temperature_timer.elapsed_sec(), critical_path.delay(), sTNS, sWNS, tot_iter);
718694

719695
sprintf(msg, "Cost: %g BB Cost %g TD Cost %g Temperature: %g",
720696
costs.cost, costs.bb_cost, costs.timing_cost, state.t);
@@ -725,7 +701,7 @@ void try_place(const t_placer_opts& placer_opts,
725701
print_clb_placement("first_iteration_clb_placement.echo");
726702
}
727703
#endif
728-
} while (state.outer_loop_update(costs, placer_opts, annealing_sched));
704+
} while (state.outer_loop_update(stats.success_rate, costs, placer_opts, annealing_sched));
729705
/* Outer loop of the simmulated annealing ends */
730706

731707
#ifdef ENABLE_ANALYTIC_PLACE
@@ -770,21 +746,13 @@ void try_place(const t_placer_opts& placer_opts,
770746
tot_iter += state.move_lim;
771747
++state.num_temps;
772748

773-
state.success_rate = ((float)stats.success_sum) / state.move_lim;
774-
calc_placer_stats(stats, std_dev, costs);
775-
776749
if (placer_opts.place_quench_algorithm.is_timing_driven()) {
777750
critical_path = timing_info->least_slack_critical_path();
778751
sTNS = timing_info->setup_total_negative_slack();
779752
sWNS = timing_info->setup_worst_negative_slack();
780753
}
781754

782-
float quench_elapsed_sec = temperature_timer.elapsed_sec();
783-
print_place_status(state.num_temps,
784-
quench_elapsed_sec,
785-
state.t, state.alpha, stats,
786-
critical_path.delay(), sTNS, sWNS,
787-
state.success_rate, std_dev, state.rlim, state.crit_exponent, tot_iter);
755+
print_place_status(state, stats, temperature_timer.elapsed_sec(), critical_path.delay(), sTNS, sWNS, tot_iter);
788756
}
789757
auto post_quench_timing_stats = timing_ctx.stats;
790758

@@ -938,11 +906,7 @@ static void placement_inner_loop(const t_annealing_state* state,
938906

939907
int inner_placement_save_count = 0; //How many times have we dumped placement to a file this temperature?
940908

941-
stats->av_cost = 0.;
942-
stats->av_bb_cost = 0.;
943-
stats->av_timing_cost = 0.;
944-
stats->sum_of_squares = 0.;
945-
stats->success_sum = 0;
909+
stats->reset();
946910

947911
inner_crit_iter_count = 1;
948912

@@ -963,11 +927,7 @@ static void placement_inner_loop(const t_annealing_state* state,
963927

964928
if (swap_result == ACCEPTED) {
965929
/* Move was accepted. Update statistics that are useful for the annealing schedule. */
966-
stats->success_sum++;
967-
stats->av_cost += costs->cost;
968-
stats->av_bb_cost += costs->bb_cost;
969-
stats->av_timing_cost += costs->timing_cost;
970-
stats->sum_of_squares += (costs->cost) * (costs->cost);
930+
stats->single_swap_update(*costs);
971931
num_swap_accepted++;
972932
} else if (swap_result == ABORTED) {
973933
num_swap_aborted++;
@@ -1025,6 +985,9 @@ static void placement_inner_loop(const t_annealing_state* state,
1025985
++inner_placement_save_count;
1026986
}
1027987
}
988+
989+
/* Calculate the success_rate and std_dev of the costs. */
990+
stats->calc_iteration_stats(*costs, state->move_lim);
1028991
}
1029992

1030993
static void recompute_costs_from_scratch(const t_placer_opts& placer_opts,
@@ -2653,20 +2616,6 @@ static void free_try_swap_arrays() {
26532616
g_vpr_ctx.mutable_placement().compressed_block_grids.clear();
26542617
}
26552618

2656-
static void calc_placer_stats(t_placer_statistics& stats, double& std_dev, const t_placer_costs& costs) {
2657-
if (stats.success_sum == 0) {
2658-
stats.av_cost = costs.cost;
2659-
stats.av_bb_cost = costs.bb_cost;
2660-
stats.av_timing_cost = costs.timing_cost;
2661-
} else {
2662-
stats.av_cost /= stats.success_sum;
2663-
stats.av_bb_cost /= stats.success_sum;
2664-
stats.av_timing_cost /= stats.success_sum;
2665-
}
2666-
2667-
std_dev = get_std_dev(stats.success_sum, stats.sum_of_squares, stats.av_cost);
2668-
}
2669-
26702619
static void generate_post_place_timing_reports(const t_placer_opts& placer_opts,
26712620
const t_analysis_opts& analysis_opts,
26722621
const SetupTimingInfo& timing_info,
@@ -2700,18 +2649,12 @@ static void print_place_status_header() {
27002649
VTR_LOG("---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
27012650
}
27022651

2703-
static void print_place_status(const size_t num_temps,
2704-
const float elapsed_sec,
2705-
const float t,
2706-
const float alpha,
2652+
static void print_place_status(const t_annealing_state& state,
27072653
const t_placer_statistics& stats,
2708-
const float cpd,
2709-
const float sTNS,
2710-
const float sWNS,
2711-
const float acc_rate,
2712-
const float std_dev,
2713-
const float rlim,
2714-
const float crit_exponent,
2654+
float elapsed_sec,
2655+
float cpd,
2656+
float sTNS,
2657+
float sWNS,
27152658
size_t tot_moves) {
27162659
VTR_LOG(
27172660
"%4zu "
@@ -2720,16 +2663,16 @@ static void print_place_status(const size_t num_temps,
27202663
"%7.3f %10.2f %-10.5g "
27212664
"%7.3f % 10.3g % 8.3f "
27222665
"%7.3f %7.4f %6.1f %8.2f",
2723-
num_temps,
2666+
state.num_temps,
27242667
elapsed_sec,
2725-
t,
2668+
state.t,
27262669
stats.av_cost, stats.av_bb_cost, stats.av_timing_cost,
27272670
1e9 * cpd, 1e9 * sTNS, 1e9 * sWNS,
2728-
acc_rate, std_dev, rlim, crit_exponent);
2671+
stats.success_rate, stats.std_dev, state.rlim, state.crit_exponent);
27292672

27302673
pretty_print_uint(" ", tot_moves, 9, 3);
27312674

2732-
VTR_LOG(" %6.3f\n", alpha);
2675+
VTR_LOG(" %6.3f\n", state.alpha);
27332676
fflush(stdout);
27342677
}
27352678

vpr/src/place/place_util.cpp

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ int get_initial_move_lim(const t_placer_opts& placer_opts, const t_annealing_sch
146146
*
147147
* @return True->continues the annealing. False->exits the annealing.
148148
*/
149-
bool t_annealing_state::outer_loop_update(const t_placer_costs& costs,
149+
bool t_annealing_state::outer_loop_update(float success_rate,
150+
const t_placer_costs& costs,
150151
const t_placer_opts& placer_opts,
151152
const t_annealing_sched& annealing_sched) {
152153
#ifndef NO_GRAPHICS
@@ -197,7 +198,7 @@ bool t_annealing_state::outer_loop_update(const t_placer_costs& costs,
197198
}
198199

199200
/* Update move lim. */
200-
update_move_lim(annealing_sched.success_target);
201+
update_move_lim(annealing_sched.success_target, success_rate);
201202
} else {
202203
VTR_ASSERT_SAFE(annealing_sched.type == AUTO_SCHED);
203204
/* Automatically adjust alpha according to success rate. */
@@ -219,7 +220,7 @@ bool t_annealing_state::outer_loop_update(const t_placer_costs& costs,
219220
}
220221

221222
/* Update the range limiter. */
222-
update_rlim();
223+
update_rlim(success_rate);
223224

224225
/* If using timing driven algorithm, update the crit_exponent. */
225226
if (placer_opts.place_algorithm.is_timing_driven()) {
@@ -236,7 +237,7 @@ bool t_annealing_state::outer_loop_update(const t_placer_costs& costs,
236237
* Use a floating point rlim to allow gradual transitions at low temps.
237238
* The range is bounded by 1 (FINAL_RLIM) and the grid size (UPPER_RLIM).
238239
*/
239-
void t_annealing_state::update_rlim() {
240+
void t_annealing_state::update_rlim(float success_rate) {
240241
rlim *= (1. - 0.44 + success_rate);
241242
rlim = std::min(rlim, UPPER_RLIM);
242243
rlim = std::max(rlim, FINAL_RLIM);
@@ -271,12 +272,44 @@ void t_annealing_state::update_crit_exponent(const t_placer_opts& placer_opts) {
271272
*
272273
* The value is bounded between 1 and move_lim_max.
273274
*/
274-
void t_annealing_state::update_move_lim(float success_target) {
275+
void t_annealing_state::update_move_lim(float success_target, float success_rate) {
275276
move_lim = move_lim_max * (success_target / success_rate);
276277
move_lim = std::min(move_lim, move_lim_max);
277278
move_lim = std::max(move_lim, 1);
278279
}
279280

281+
void t_placer_statistics::reset() {
282+
av_cost = 0.;
283+
av_bb_cost = 0.;
284+
av_timing_cost = 0.;
285+
sum_of_squares = 0.;
286+
success_sum = 0;
287+
success_rate = 0.;
288+
std_dev = 0.;
289+
}
290+
291+
void t_placer_statistics::single_swap_update(const t_placer_costs& costs) {
292+
success_sum++;
293+
av_cost += costs.cost;
294+
av_bb_cost += costs.bb_cost;
295+
av_timing_cost += costs.timing_cost;
296+
sum_of_squares += (costs.cost) * (costs.cost);
297+
}
298+
299+
void t_placer_statistics::calc_iteration_stats(const t_placer_costs& costs, int move_lim) {
300+
if (success_sum == 0) {
301+
av_cost = costs.cost;
302+
av_bb_cost = costs.bb_cost;
303+
av_timing_cost = costs.timing_cost;
304+
} else {
305+
av_cost /= success_sum;
306+
av_bb_cost /= success_sum;
307+
av_timing_cost /= success_sum;
308+
}
309+
success_rate = success_sum / float(move_lim);
310+
std_dev = get_std_dev(success_sum, sum_of_squares, av_cost);
311+
}
312+
280313
/**
281314
* @brief Returns the standard deviation of data set x.
282315
*

vpr/src/place/place_util.h

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ class t_annealing_state {
117117
float crit_exponent;
118118
int move_lim;
119119
int move_lim_max;
120-
float success_rate;
121120

122121
private:
123122
float UPPER_RLIM;
@@ -132,14 +131,69 @@ class t_annealing_state {
132131
float first_crit_exponent);
133132

134133
public: //Mutator
135-
bool outer_loop_update(const t_placer_costs& costs,
134+
bool outer_loop_update(float success_rate,
135+
const t_placer_costs& costs,
136136
const t_placer_opts& placer_opts,
137137
const t_annealing_sched& annealing_sched);
138138

139139
private: //Mutator
140-
inline void update_rlim();
140+
inline void update_rlim(float success_rate);
141141
inline void update_crit_exponent(const t_placer_opts& placer_opts);
142-
inline void update_move_lim(float success_target);
142+
inline void update_move_lim(float success_target, float success_rate);
143+
};
144+
145+
/**
146+
* @brief Stores statistics produced by a single annealing iteration.
147+
*
148+
* This structure is refreshed at the beginning of every annealing loop
149+
* by calling reset(). Whenever a block swap move is accepted, this
150+
* structure calls single_swap_update() to update its variables. At the
151+
* end of the current iteration, it calls calc_iteration_stats() to
152+
* summarize the results (success_rate & std_dev of the total costs).
153+
*
154+
* In terms of calculating statistics for total cost, we mean that we
155+
* operate upon the set of placer cost values gathered after every
156+
* accepted block move.
157+
*
158+
* @param av_cost
159+
* Average total cost. Cost formulation depends on
160+
* the place algorithm currently being used.
161+
* @param av_bb_cost
162+
* Average bounding box (wiring) cost.
163+
* @param av_timing_cost
164+
* Average timing cost (delay * criticality).
165+
* @param sum_of_squares
166+
* Sum of squares of the total cost.
167+
* @param success_num
168+
* Number of accepted block swaps for the current iteration.
169+
* @param success_rate
170+
* num_accepted / total_trials for the current iteration.
171+
* @param std_dev
172+
* Standard deviation of the total cost.
173+
*
174+
*/
175+
class t_placer_statistics {
176+
public:
177+
double av_cost;
178+
double av_bb_cost;
179+
double av_timing_cost;
180+
double sum_of_squares;
181+
int success_sum;
182+
float success_rate;
183+
double std_dev;
184+
185+
public: //Constructor
186+
t_placer_statistics() { reset(); }
187+
188+
public: //Mutator
189+
///@brief Clear all data fields.
190+
void reset();
191+
192+
///@brief Update stats when a single swap move has been accepted.
193+
void calc_iteration_stats(const t_placer_costs& costs, int move_lim);
194+
195+
///@brief Calculate placer success rate and cost std_dev for this iteration.
196+
void single_swap_update(const t_placer_costs& costs);
143197
};
144198

145199
///@brief Initialize the placer's block-grid dual direction mapping.

0 commit comments

Comments
 (0)