diff --git a/doc/src/vpr/command_line_usage.rst b/doc/src/vpr/command_line_usage.rst index 36baf34132..0792eb0f27 100644 --- a/doc/src/vpr/command_line_usage.rst +++ b/doc/src/vpr/command_line_usage.rst @@ -810,6 +810,22 @@ If any of init_t, exit_t or alpha_t is specified, the user schedule, with a fixe **Default:** ``circuit`` +.. option:: --anneal_auto_init_t_scale + + A scale on the starting temperature of the anneal for the automatic annealing + schedule. + + When in the automatic annealing schedule, the annealer will select a good + initial temperature based on the quality of the initial placement. This option + allows you to scale that initial temperature up or down by multiplying the + initial temperature by the given scale. Increasing this number + will increase the initial temperature which will have the annealer potentially + explore more of the space at the expense of run time. Depending on the quality + of the initial placement, this may improve or hurt the quality of the final + placement. + + **Default:** ``1.0`` + .. option:: --init_t The starting temperature of the anneal for the manual annealing schedule. diff --git a/vpr/src/analytical_place/detailed_placer.cpp b/vpr/src/analytical_place/detailed_placer.cpp index 58f7b0424a..615493df77 100644 --- a/vpr/src/analytical_place/detailed_placer.cpp +++ b/vpr/src/analytical_place/detailed_placer.cpp @@ -75,6 +75,19 @@ AnnealerDetailedPlacer::AnnealerDetailedPlacer(const BlkLocRegistry& curr_cluste } } + // The solution produced by the AP flow is significantly better than the + // initial placement solution produced by the initial placer in the default + // flow. Even though the annealer auto-selects its initial temperature based + // on the quality of the placement, we found that the initial temperatute was + // still too high and it was hurting quality. This scales down the initial + // temperature auto-selected by the annealer to prevent this and improve + // runtime. + // Here we still scale by whatever the user passed in to scale the initial + // temperature by, but we also scale it down further. This allows AP to scale + // the initial temperature down by default, while still allowing the user + // some control. + float anneal_auto_init_t_scale = vpr_setup.PlacerOpts.place_auto_init_t_scale * 0.5f; + placer_ = std::make_unique((const Netlist<>&)clustered_netlist, curr_clustered_placement, vpr_setup.PlacerOpts, @@ -84,6 +97,7 @@ AnnealerDetailedPlacer::AnnealerDetailedPlacer(const BlkLocRegistry& curr_cluste netlist_pin_lookup_, FlatPlacementInfo(), place_delay_model, + anneal_auto_init_t_scale, g_vpr_ctx.placement().cube_bb, false /*is_flat*/, false /*quiet*/); diff --git a/vpr/src/base/CheckSetup.cpp b/vpr/src/base/CheckSetup.cpp index ae5d43eba4..7e714604ab 100644 --- a/vpr/src/base/CheckSetup.cpp +++ b/vpr/src/base/CheckSetup.cpp @@ -69,6 +69,11 @@ void CheckSetup(const t_packer_opts& packer_opts, NUM_PL_MOVE_TYPES); } + if (placer_opts.place_auto_init_t_scale < 0.0) { + VPR_FATAL_ERROR(VPR_ERROR_OTHER, + "Cannot have negative annealer auto initial temperature scale.\n"); + } + // Rules for doing Analytical Placement if (ap_opts.doAP) { // Make sure that the --place option was not set. diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index b8584958aa..651ae5ccd1 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -703,6 +703,8 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts) PlacerOpts->placer_debug_block = Options.placer_debug_block; PlacerOpts->placer_debug_net = Options.placer_debug_net; + + PlacerOpts->place_auto_init_t_scale = Options.place_auto_init_t_scale.value(); } static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysis_opts) { diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index e8cc36ee04..3c6b206764 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -2200,6 +2200,22 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("circuit") .show_in(argparse::ShowIn::HELP_ONLY); + place_grp.add_argument(args.place_auto_init_t_scale, "--anneal_auto_init_t_scale") + .help( + "A scale on the starting temperature of the anneal for the automatic annealing " + "schedule.\n" + "\n" + "When in the automatic annealing schedule, the annealer will select a good " + "initial temperature based on the quality of the initial placement. This option " + "allows you to scale that initial temperature up or down by multiplying the " + "initial temperature by the given scale. Increasing this number " + "will increase the initial temperature which will have the annealer potentially " + "explore more of the space at the expense of run time. Depending on the quality " + "of the initial placement, this may improve or hurt the quality of the final " + "placement.") + .default_value("1.0") + .show_in(argparse::ShowIn::HELP_ONLY); + place_grp.add_argument(args.PlaceInitT, "--init_t") .help("Initial temperature for manual annealing schedule") .default_value("100.0") diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 614285fb8b..9485c0b765 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -129,6 +129,7 @@ struct t_options { argparse::ArgValue Seed; argparse::ArgValue ShowPlaceTiming; argparse::ArgValue PlaceInnerNum; + argparse::ArgValue place_auto_init_t_scale; argparse::ArgValue PlaceInitT; argparse::ArgValue PlaceExitT; argparse::ArgValue PlaceAlphaT; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 95010ef8e5..71bf0c3458 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1004,8 +1004,9 @@ enum class e_move_type; * @param place_constraint_subtile * True if subtiles should be specified when printing floorplan * constraints. False if not. - * - * + * @param place_auto_init_t_scale + * When the annealer is using the automatic schedule, this option + * scales the initial temperature selected. */ struct t_placer_opts { t_place_algorithm place_algorithm; @@ -1077,6 +1078,8 @@ struct t_placer_opts { std::string allowed_tiles_for_delay_model; e_place_delta_delay_algorithm place_delta_delay_matrix_calculation_method; + + float place_auto_init_t_scale; }; /****************************************************************** diff --git a/vpr/src/place/annealer.cpp b/vpr/src/place/annealer.cpp index 6183fceec6..3422850312 100644 --- a/vpr/src/place/annealer.cpp +++ b/vpr/src/place/annealer.cpp @@ -206,6 +206,7 @@ PlacementAnnealer::PlacementAnnealer(const t_placer_opts& placer_opts, PlacerSetupSlacks* setup_slacks, SetupTimingInfo* timing_info, NetPinTimingInvalidator* pin_timing_invalidator, + float auto_init_t_scale, int move_lim) : placer_opts_(placer_opts) , placer_state_(placer_state) @@ -285,7 +286,8 @@ PlacementAnnealer::PlacementAnnealer(const t_placer_opts& placer_opts, move_type_stats_.rejected_moves.resize({device_ctx.logical_block_types.size(), (int)e_move_type::NUMBER_OF_AUTO_MOVES}, 0); // Update the starting temperature for placement annealing to a more appropriate value - annealing_state_.t = estimate_starting_temperature_(); + VTR_ASSERT_SAFE_MSG(auto_init_t_scale >= 0, "Initial temperature scale cannot be negative."); + annealing_state_.t = estimate_starting_temperature_() * auto_init_t_scale; } float PlacementAnnealer::estimate_starting_temperature_() { diff --git a/vpr/src/place/annealer.h b/vpr/src/place/annealer.h index 368b8c5607..0d098db728 100644 --- a/vpr/src/place/annealer.h +++ b/vpr/src/place/annealer.h @@ -185,6 +185,7 @@ class PlacementAnnealer { PlacerSetupSlacks* setup_slacks, SetupTimingInfo* timing_info, NetPinTimingInvalidator* pin_timing_invalidator, + float auto_init_t_scale, int move_lim); /** diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index f4a370e1df..c5d46b5af3 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -112,7 +112,8 @@ void try_place(const Netlist<>& net_list, ClusteredPinAtomPinsLookup netlist_pin_lookup(cluster_ctx.clb_nlist, atom_ctx.netlist(), pb_gpin_lookup); Placer placer(net_list, {}, placer_opts, analysis_opts, noc_opts, pb_gpin_lookup, netlist_pin_lookup, - flat_placement_info, place_delay_model, mutable_placement.cube_bb, is_flat, /*quiet=*/false); + flat_placement_info, place_delay_model, placer_opts.place_auto_init_t_scale, + mutable_placement.cube_bb, is_flat, /*quiet=*/false); placer.place(); diff --git a/vpr/src/place/placer.cpp b/vpr/src/place/placer.cpp index bc8da5afb4..e3cb33f8e2 100644 --- a/vpr/src/place/placer.cpp +++ b/vpr/src/place/placer.cpp @@ -35,6 +35,7 @@ Placer::Placer(const Netlist<>& net_list, const ClusteredPinAtomPinsLookup& netlist_pin_lookup, const FlatPlacementInfo& flat_placement_info, std::shared_ptr place_delay_model, + float anneal_auto_init_t_scale, bool cube_bb, bool is_flat, bool quiet) @@ -152,6 +153,7 @@ Placer::Placer(const Netlist<>& net_list, annealer_ = std::make_unique(placer_opts_, placer_state_, place_macros, costs_, net_cost_handler_, noc_cost_handler_, noc_opts_, rng_, std::move(move_generator), std::move(move_generator2), place_delay_model_.get(), placer_criticalities_.get(), placer_setup_slacks_.get(), timing_info_.get(), pin_timing_invalidator_.get(), + anneal_auto_init_t_scale, move_lim); } diff --git a/vpr/src/place/placer.h b/vpr/src/place/placer.h index 6fb32cafad..fa923ab0bc 100644 --- a/vpr/src/place/placer.h +++ b/vpr/src/place/placer.h @@ -49,6 +49,7 @@ class Placer { const ClusteredPinAtomPinsLookup& netlist_pin_lookup, const FlatPlacementInfo& flat_placement_info, std::shared_ptr place_delay_model, + float anneal_auto_init_t_scale, bool cube_bb, bool is_flat, bool quiet);