Skip to content

Commit afc789b

Browse files
added place() method to Placer class
1 parent 2298704 commit afc789b

File tree

5 files changed

+168
-302
lines changed

5 files changed

+168
-302
lines changed

vpr/src/place/place.cpp

Lines changed: 8 additions & 299 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,6 @@ static void generate_post_place_timing_reports(const t_placer_opts& placer_opts,
8080
bool is_flat,
8181
const BlkLocRegistry& blk_loc_registry);
8282

83-
static void print_place_status_header(bool noc_enabled);
84-
85-
static void print_place_status(const t_annealing_state& state,
86-
const t_placer_statistics& stats,
87-
float elapsed_sec,
88-
float cpd,
89-
float sTNS,
90-
float sWNS,
91-
size_t tot_moves,
92-
bool noc_enabled,
93-
const NocCostTerms& noc_cost_terms);
94-
95-
static void print_resources_utilization(const BlkLocRegistry& blk_loc_registry);
96-
97-
static void print_placement_swaps_stats(const t_annealing_state& state, const t_swap_stats& swap_stats);
98-
9983
/**
10084
* @brief Copies the placement location variables into the global placement context.
10185
* @param blk_loc_registry The placement location variables to be copied.
@@ -129,10 +113,6 @@ void try_place(const Netlist<>& net_list,
129113
const auto& timing_ctx = g_vpr_ctx.timing();
130114
auto pre_place_timing_stats = timing_ctx.stats;
131115

132-
133-
float sTNS = NAN;
134-
float sWNS = NAN;
135-
136116
char msg[vtr::bufsize];
137117

138118
/* Placement delay model is independent of the placement and can be shared across
@@ -192,141 +172,6 @@ void try_place(const Netlist<>& net_list,
192172
print_place(nullptr, nullptr, filename.c_str(), blk_loc_registry.block_locs());
193173
}
194174

195-
bool skip_anneal = false;
196-
197-
#ifdef ENABLE_ANALYTIC_PLACE
198-
// Analytic placer: When enabled, skip most of the annealing and go straight to quench
199-
// TODO: refactor goto label.
200-
if (placer_opts.enable_analytic_placer) {
201-
skip_anneal = true;
202-
}
203-
#endif /* ENABLE_ANALYTIC_PLACE */
204-
205-
PlacementAnnealer annealer(placer_opts, placer_state, costs, net_cost_handler, noc_cost_handler,
206-
noc_opts, rng, std::move(move_generator), std::move(move_generator2), place_delay_model.get(),
207-
placer_criticalities.get(), placer_setup_slacks.get(), timing_info.get(), pin_timing_invalidator.get(), move_lim);
208-
209-
const t_annealing_state& annealing_state = annealer.get_annealing_state();
210-
const auto& [swap_stats, move_type_stats, placer_stats] = annealer.get_stats();
211-
212-
if (!skip_anneal) {
213-
//Table header
214-
VTR_LOG("\n");
215-
print_place_status_header(noc_opts.noc);
216-
217-
/* Outer loop of the simulated annealing begins */
218-
do {
219-
vtr::Timer temperature_timer;
220-
221-
annealer.outer_loop_update_timing_info();
222-
223-
if (placer_opts.place_algorithm.is_timing_driven()) {
224-
critical_path = timing_info->least_slack_critical_path();
225-
sTNS = timing_info->setup_total_negative_slack();
226-
sWNS = timing_info->setup_worst_negative_slack();
227-
228-
// see if we should save the current placement solution as a checkpoint
229-
if (placer_opts.place_checkpointing && annealer.get_agent_state() == e_agent_state::LATE_IN_THE_ANNEAL) {
230-
save_placement_checkpoint_if_needed(blk_loc_registry.block_locs(),
231-
placement_checkpoint,
232-
timing_info, costs, critical_path.delay());
233-
}
234-
}
235-
236-
// do a complete inner loop iteration
237-
annealer.placement_inner_loop();
238-
239-
print_place_status(annealing_state, placer_stats, temperature_timer.elapsed_sec(),
240-
critical_path.delay(), sTNS, sWNS, annealer.get_total_iteration(),
241-
noc_opts.noc, costs.noc_cost_terms);
242-
243-
sprintf(msg, "Cost: %g BB Cost %g TD Cost %g Temperature: %g",
244-
costs.cost, costs.bb_cost, costs.timing_cost, annealing_state.t);
245-
update_screen(ScreenUpdatePriority::MINOR, msg, PLACEMENT, timing_info);
246-
247-
//#ifdef VERBOSE
248-
// if (getEchoEnabled()) {
249-
// print_clb_placement("first_iteration_clb_placement.echo");
250-
// }
251-
//#endif
252-
} while (annealer.outer_loop_update_state());
253-
/* Outer loop of the simulated annealing ends */
254-
} //skip_anneal ends
255-
256-
// Start Quench
257-
annealer.start_quench();
258-
259-
auto pre_quench_timing_stats = timing_ctx.stats;
260-
{ /* Quench */
261-
262-
vtr::ScopedFinishTimer temperature_timer("Placement Quench");
263-
264-
annealer.outer_loop_update_timing_info();
265-
266-
/* Run inner loop again with temperature = 0 so as to accept only swaps
267-
* which reduce the cost of the placement */
268-
annealer.placement_inner_loop();
269-
270-
if (placer_opts.place_quench_algorithm.is_timing_driven()) {
271-
critical_path = timing_info->least_slack_critical_path();
272-
sTNS = timing_info->setup_total_negative_slack();
273-
sWNS = timing_info->setup_worst_negative_slack();
274-
}
275-
276-
print_place_status(annealing_state, placer_stats, temperature_timer.elapsed_sec(),
277-
critical_path.delay(), sTNS, sWNS, annealer.get_total_iteration(),
278-
noc_opts.noc, costs.noc_cost_terms);
279-
}
280-
auto post_quench_timing_stats = timing_ctx.stats;
281-
282-
//Final timing analysis
283-
PlaceCritParams crit_params;
284-
crit_params.crit_exponent = annealing_state.crit_exponent;
285-
crit_params.crit_limit = placer_opts.place_crit_limit;
286-
287-
if (placer_opts.place_algorithm.is_timing_driven()) {
288-
perform_full_timing_update(crit_params, place_delay_model.get(), placer_criticalities.get(),
289-
placer_setup_slacks.get(), pin_timing_invalidator.get(),
290-
timing_info.get(), &costs, placer_state);
291-
VTR_LOG("post-quench CPD = %g (ns) \n",
292-
1e9 * timing_info->least_slack_critical_path().delay());
293-
}
294-
295-
//See if our latest checkpoint is better than the current placement solution
296-
if (placer_opts.place_checkpointing)
297-
restore_best_placement(placer_state,
298-
placement_checkpoint, timing_info, costs,
299-
placer_criticalities, placer_setup_slacks, place_delay_model,
300-
pin_timing_invalidator, crit_params, noc_cost_handler);
301-
302-
if (placer_opts.placement_saves_per_temperature >= 1) {
303-
std::string filename = vtr::string_fmt("placement_%03d_%03d.place",
304-
annealing_state.num_temps + 1, 0);
305-
VTR_LOG("Saving final placement to file: %s\n", filename.c_str());
306-
print_place(nullptr, nullptr, filename.c_str(), blk_loc_registry.block_locs());
307-
}
308-
309-
310-
//#ifdef VERBOSE
311-
// if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_END_CLB_PLACEMENT)) {
312-
// print_clb_placement(getEchoFileName(E_ECHO_END_CLB_PLACEMENT));
313-
// }
314-
//#endif
315-
316-
// Update physical pin values
317-
for (const ClusterBlockId block_id : cluster_ctx.clb_nlist.blocks()) {
318-
blk_loc_registry.place_sync_external_block_connections(block_id);
319-
}
320-
321-
check_place(costs,
322-
place_delay_model.get(),
323-
placer_criticalities.get(),
324-
placer_opts.place_algorithm,
325-
noc_opts,
326-
placer_state,
327-
net_cost_handler,
328-
noc_cost_handler);
329-
330175
//Some stats
331176
VTR_LOG("\n");
332177
VTR_LOG("Swaps called: %d\n", swap_stats.num_ts_called);
@@ -339,23 +184,19 @@ void try_place(const Netlist<>& net_list,
339184
critical_path = timing_info->least_slack_critical_path();
340185

341186
if (isEchoFileEnabled(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH)) {
342-
tatum::write_echo(
343-
getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH),
344-
*timing_ctx.graph, *timing_ctx.constraints,
345-
*placement_delay_calc, timing_info->analyzer());
346-
347-
tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(
348-
analysis_opts.echo_dot_timing_graph_node);
349-
write_setup_timing_graph_dot(
350-
getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH)
351-
+ std::string(".dot"),
352-
*timing_info, debug_tnode);
187+
tatum::write_echo(getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH),
188+
*timing_ctx.graph, *timing_ctx.constraints,
189+
*placement_delay_calc, timing_info->analyzer());
190+
191+
tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(analysis_opts.echo_dot_timing_graph_node);
192+
write_setup_timing_graph_dot(getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH) + std::string(".dot"),
193+
*timing_info, debug_tnode);
353194
}
354195

355196
generate_post_place_timing_reports(placer_opts, analysis_opts, *timing_info,
356197
*placement_delay_calc, is_flat, blk_loc_registry);
357198

358-
/* Print critical path delay metrics */
199+
// Print critical path delay metrics
359200
VTR_LOG("\n");
360201
print_setup_timing_summary(*timing_ctx.constraints,
361202
*timing_info->setup_analyzer(), "Placement estimated ", "");
@@ -380,28 +221,9 @@ void try_place(const Netlist<>& net_list,
380221
}
381222

382223
update_screen(ScreenUpdatePriority::MAJOR, msg, PLACEMENT, timing_info);
383-
// Print out swap statistics
384-
print_resources_utilization(blk_loc_registry);
385-
386-
print_placement_swaps_stats(annealing_state, swap_stats);
387-
388-
move_type_stats.print_placement_move_types_stats();
389-
390-
if (noc_opts.noc) {
391-
write_noc_placement_file(noc_opts.noc_placement_file_name, blk_loc_registry.block_locs());
392-
}
393224

394225
free_placement_structs();
395226

396-
print_timing_stats("Placement Quench", post_quench_timing_stats, pre_quench_timing_stats);
397-
print_timing_stats("Placement Total ", timing_ctx.stats, pre_place_timing_stats);
398-
399-
VTR_LOG("update_td_costs: connections %g nets %g sum_nets %g total %g\n",
400-
p_runtime_ctx.f_update_td_costs_connections_elapsed_sec,
401-
p_runtime_ctx.f_update_td_costs_nets_elapsed_sec,
402-
p_runtime_ctx.f_update_td_costs_sum_nets_elapsed_sec,
403-
p_runtime_ctx.f_update_td_costs_total_elapsed_sec);
404-
405227
copy_locs_to_global_state(blk_loc_registry);
406228
}
407229

@@ -505,119 +327,6 @@ static void update_screen_debug() {
505327
}
506328
#endif
507329

508-
static void print_place_status_header(bool noc_enabled) {
509-
if (!noc_enabled) {
510-
VTR_LOG(
511-
"---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
512-
VTR_LOG(
513-
"Tnum Time T Av Cost Av BB Cost Av TD Cost CPD sTNS sWNS Ac Rate Std Dev R lim Crit Exp Tot Moves Alpha\n");
514-
VTR_LOG(
515-
" (sec) (ns) (ns) (ns) \n");
516-
VTR_LOG(
517-
"---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
518-
} else {
519-
VTR_LOG(
520-
"---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------ -------- -------- --------- ---------\n");
521-
VTR_LOG(
522-
"Tnum Time T Av Cost Av BB Cost Av TD Cost CPD sTNS sWNS Ac Rate Std Dev R lim Crit Exp Tot Moves Alpha Agg. BW Agg. Lat Lat Over. NoC Cong.\n");
523-
VTR_LOG(
524-
" (sec) (ns) (ns) (ns) (bps) (ns) (ns) \n");
525-
VTR_LOG(
526-
"---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------ -------- -------- --------- ---------\n");
527-
}
528-
}
529-
530-
static void print_place_status(const t_annealing_state& state,
531-
const t_placer_statistics& stats,
532-
float elapsed_sec,
533-
float cpd,
534-
float sTNS,
535-
float sWNS,
536-
size_t tot_moves,
537-
bool noc_enabled,
538-
const NocCostTerms& noc_cost_terms) {
539-
VTR_LOG(
540-
"%4zu %6.1f %7.1e "
541-
"%7.3f %10.2f %-10.5g "
542-
"%7.3f % 10.3g % 8.3f "
543-
"%7.3f %7.4f %6.1f %8.2f",
544-
state.num_temps, elapsed_sec, state.t,
545-
stats.av_cost, stats.av_bb_cost, stats.av_timing_cost,
546-
1e9 * cpd, 1e9 * sTNS, 1e9 * sWNS,
547-
stats.success_rate, stats.std_dev, state.rlim, state.crit_exponent);
548-
549-
pretty_print_uint(" ", tot_moves, 9, 3);
550-
551-
VTR_LOG(" %6.3f", state.alpha);
552-
553-
if (noc_enabled) {
554-
VTR_LOG(
555-
" %7.2e %7.2e"
556-
" %8.2e %8.2f",
557-
noc_cost_terms.aggregate_bandwidth, noc_cost_terms.latency,
558-
noc_cost_terms.latency_overrun, noc_cost_terms.congestion);
559-
}
560-
561-
VTR_LOG("\n");
562-
fflush(stdout);
563-
}
564-
565-
static void print_resources_utilization(const BlkLocRegistry& blk_loc_registry) {
566-
const auto& cluster_ctx = g_vpr_ctx.clustering();
567-
const auto& device_ctx = g_vpr_ctx.device();
568-
const auto& block_locs = blk_loc_registry.block_locs();
569-
570-
size_t max_block_name = 0;
571-
size_t max_tile_name = 0;
572-
573-
//Record the resource requirement
574-
std::map<t_logical_block_type_ptr, size_t> num_type_instances;
575-
std::map<t_logical_block_type_ptr, std::map<t_physical_tile_type_ptr, size_t>> num_placed_instances;
576-
577-
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
578-
const t_pl_loc& loc = block_locs[blk_id].loc;
579-
580-
t_physical_tile_type_ptr physical_tile = device_ctx.grid.get_physical_type({loc.x, loc.y, loc.layer});
581-
t_logical_block_type_ptr logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
582-
583-
num_type_instances[logical_block]++;
584-
num_placed_instances[logical_block][physical_tile]++;
585-
586-
max_block_name = std::max(max_block_name, logical_block->name.length());
587-
max_tile_name = std::max(max_tile_name, physical_tile->name.length());
588-
}
589-
590-
VTR_LOG("\n");
591-
VTR_LOG("Placement resource usage:\n");
592-
for (const auto [logical_block_type_ptr, _] : num_type_instances) {
593-
for (const auto [physical_tile_type_ptr, num_instances] : num_placed_instances[logical_block_type_ptr]) {
594-
VTR_LOG(" %-*s implemented as %-*s: %d\n", max_block_name,
595-
logical_block_type_ptr->name.c_str(), max_tile_name,
596-
physical_tile_type_ptr->name.c_str(), num_instances);
597-
}
598-
}
599-
VTR_LOG("\n");
600-
}
601-
602-
static void print_placement_swaps_stats(const t_annealing_state& state, const t_swap_stats& swap_stats) {
603-
size_t total_swap_attempts = swap_stats.num_swap_rejected + swap_stats.num_swap_accepted + swap_stats.num_swap_aborted;
604-
VTR_ASSERT(total_swap_attempts > 0);
605-
606-
size_t num_swap_print_digits = ceil(log10(total_swap_attempts));
607-
float reject_rate = (float)swap_stats.num_swap_rejected / total_swap_attempts;
608-
float accept_rate = (float)swap_stats.num_swap_accepted / total_swap_attempts;
609-
float abort_rate = (float)swap_stats.num_swap_aborted / total_swap_attempts;
610-
VTR_LOG("Placement number of temperatures: %d\n", state.num_temps);
611-
VTR_LOG("Placement total # of swap attempts: %*d\n", num_swap_print_digits,
612-
total_swap_attempts);
613-
VTR_LOG("\tSwaps accepted: %*d (%4.1f %%)\n", num_swap_print_digits,
614-
swap_stats.num_swap_accepted, 100 * accept_rate);
615-
VTR_LOG("\tSwaps rejected: %*d (%4.1f %%)\n", num_swap_print_digits,
616-
swap_stats.num_swap_rejected, 100 * reject_rate);
617-
VTR_LOG("\tSwaps aborted: %*d (%4.1f %%)\n", num_swap_print_digits,
618-
swap_stats.num_swap_aborted, 100 * abort_rate);
619-
}
620-
621330
static void copy_locs_to_global_state(const BlkLocRegistry& blk_loc_registry) {
622331
auto& place_ctx = g_vpr_ctx.mutable_placement();
623332

vpr/src/place/place_checkpoint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void restore_best_placement(PlacerState& placer_state,
4242
t_placer_costs& costs,
4343
std::unique_ptr<PlacerCriticalities>& placer_criticalities,
4444
std::unique_ptr<PlacerSetupSlacks>& placer_setup_slacks,
45-
std::unique_ptr<PlaceDelayModel>& place_delay_model,
45+
std::shared_ptr<PlaceDelayModel>& place_delay_model,
4646
std::unique_ptr<NetPinTimingInvalidator>& pin_timing_invalidator,
4747
PlaceCritParams crit_params,
4848
std::optional<NocCostHandler>& noc_cost_handler) {

vpr/src/place/place_checkpoint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ void restore_best_placement(PlacerState& placer_state,
7474
t_placer_costs& costs,
7575
std::unique_ptr<PlacerCriticalities>& placer_criticalities,
7676
std::unique_ptr<PlacerSetupSlacks>& placer_setup_slacks,
77-
std::unique_ptr<PlaceDelayModel>& place_delay_model,
77+
std::shared_ptr<PlaceDelayModel>& place_delay_model,
7878
std::unique_ptr<NetPinTimingInvalidator>& pin_timing_invalidator,
7979
PlaceCritParams crit_params,
8080
std::optional<NocCostHandler>& noc_cost_handler);

0 commit comments

Comments
 (0)