Skip to content

Add --place_freq command line option #3204

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 9 commits into
base: master
Choose a base branch
from
Open
13 changes: 12 additions & 1 deletion doc/src/vpr/command_line_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,16 @@ If any of init_t, exit_t or alpha_t is specified, the user schedule, with a fixe

**Default:** ``auto_bb``

.. option:: --place_frequency {once | always}

Specifies how often placement is performed during the minimum channel width search.

``once``: Placement is run only once at the beginning of the channel width search. This reduces runtime but may not benefit from congestion-aware optimizations.

``always``: Placement is rerun for each channel width trial. This might improve routability at the cost of increased runtime.

**Default:** ``once``

.. option:: --place_chan_width <int>

Tells VPR how many tracks a channel of relative width 1 is expected to need to complete routing of this circuit.
Expand Down Expand Up @@ -1869,6 +1879,7 @@ The following options are only valid when the router is in timing-driven mode (t
**Default:** ``0.5``

.. option:: --router_initial_acc_cost_chan_congestion_weight <float>

Weight applied to the excess channel utilization (above threshold) when computing the initial accumulated cost (acc_cost)of routing resources.

Higher values make the router more sensitive to early congestion.
Expand Down Expand Up @@ -1907,7 +1918,7 @@ The following options are only valid when the router is in timing-driven mode (t

.. option:: --router_first_iter_timing_report <file>

Name of the timing report file to generate after the first routing iteration completes (not generated if unspecfied).
Name of the timing report file to generate after the first routing iteration completes (not generated if unspecified).

.. option:: --router_debug_net <int>

Expand Down
14 changes: 5 additions & 9 deletions vpr/src/base/ShowSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,20 +495,16 @@ static void ShowRouterOpts(const t_router_opts& RouterOpts) {
static void ShowPlacerOpts(const t_placer_opts& PlacerOpts) {
VTR_LOG("PlacerOpts.place_freq: ");
switch (PlacerOpts.place_freq) {
case PLACE_ONCE:
VTR_LOG("PLACE_ONCE\n");
case e_place_freq::ONCE:
VTR_LOG("ONCE\n");
break;
case PLACE_ALWAYS:
VTR_LOG("PLACE_ALWAYS\n");
break;
case PLACE_NEVER:
VTR_LOG("PLACE_NEVER\n");
case e_place_freq::ALWAYS:
VTR_LOG("ALWAYS\n");
break;
default:
VTR_LOG_ERROR("Unknown Place Freq\n");
}
if ((PLACE_ONCE == PlacerOpts.place_freq)
|| (PLACE_ALWAYS == PlacerOpts.place_freq)) {
if (PlacerOpts.place_freq == e_place_freq::ONCE || PlacerOpts.place_freq == e_place_freq::ALWAYS) {
VTR_LOG("PlacerOpts.place_algorithm: ");
switch (PlacerOpts.place_algorithm.get()) {
case e_place_algorithm::BOUNDING_BOX_PLACE:
Expand Down
8 changes: 4 additions & 4 deletions vpr/src/base/place_and_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
break;
}

if (placer_opts.place_freq == PLACE_ALWAYS) {
if (placer_opts.place_freq == e_place_freq::ALWAYS) {
placer_opts.place_chan_width = current;
try_place(placement_net_list,
placer_opts,
Expand Down Expand Up @@ -312,7 +312,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
fflush(stdout);
if (current < 1)
break;
if (placer_opts.place_freq == PLACE_ALWAYS) {
if (placer_opts.place_freq == e_place_freq::ALWAYS) {
placer_opts.place_chan_width = current;
try_place(placement_net_list, placer_opts, router_opts, analysis_opts, noc_opts,
arch->Chans, det_routing_arch, segment_inf,
Expand Down Expand Up @@ -341,7 +341,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list,
route_ctx.clb_opins_used_locally,
saved_clb_opins_used_locally);

if (placer_opts.place_freq == PLACE_ALWAYS) {
if (placer_opts.place_freq == e_place_freq::ALWAYS) {
auto& cluster_ctx = g_vpr_ctx.clustering();
// Cluster-based net_list is used for placement
std::string placement_id = print_place(filename_opts.NetFile.c_str(), cluster_ctx.clb_nlist.netlist_id().c_str(),
Expand Down Expand Up @@ -417,7 +417,7 @@ t_chan_width setup_chan_width(const t_router_opts& router_opts,
if (router_opts.fixed_channel_width == NO_FIXED_CHANNEL_WIDTH) {
auto& device_ctx = g_vpr_ctx.device();

auto type = find_most_common_tile_type(device_ctx.grid);
t_physical_tile_type_ptr type = find_most_common_tile_type(device_ctx.grid);

width_fac = 4 * type->num_pins;
// this is 2x the value that binary search starts
Expand Down
89 changes: 63 additions & 26 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,37 @@ struct ParsePlaceBoundingBox {
}
};

struct ParsePlacementFreq {
ConvertedValue<e_place_freq> from_str(const std::string& str) {
ConvertedValue<e_place_freq> conv_value;
if (str == "once") {
conv_value.set_value(e_place_freq::ONCE);
} else if (str == "always") {
conv_value.set_value(e_place_freq::ALWAYS);
} else {
std::stringstream msg;
msg << "Invalid conversion from '" << str << "' to e_place_freq (expected one of: " << argparse::join(default_choices(), ", ") << ")";
conv_value.set_error(msg.str());
}
return conv_value;
}

ConvertedValue<std::string> to_str(e_place_freq val) {
ConvertedValue<std::string> conv_value;
if (val == e_place_freq::ONCE) {
conv_value.set_value("once");
} else {
VTR_ASSERT(val == e_place_freq::ALWAYS);
conv_value.set_value("always");
}
return conv_value;
}

std::vector<std::string> default_choices() {
return {"once", "always"};
}
};

struct ParsePlaceAgentAlgorithm {
ConvertedValue<e_agent_algorithm> from_str(const std::string& str) {
ConvertedValue<e_agent_algorithm> conv_value;
Expand Down Expand Up @@ -2177,7 +2208,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio

auto& place_grp = parser.add_argument_group("placement options");

place_grp.add_argument(args.Seed, "--seed")
place_grp.add_argument(args.seed, "--seed")
.help("Placement random number generator seed")
.default_value("1")
.show_in(argparse::ShowIn::HELP_ONLY);
Expand All @@ -2195,7 +2226,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.default_value("astar")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.PlaceInnerNum, "--inner_num")
place_grp.add_argument(args.place_inner_num, "--inner_num")
.help("Controls number of moves per temperature: inner_num * num_blocks ^ (4/3)")
.default_value("0.5")
.show_in(argparse::ShowIn::HELP_ONLY);
Expand Down Expand Up @@ -2226,17 +2257,17 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.default_value("1.0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.PlaceInitT, "--init_t")
place_grp.add_argument(args.place_init_t, "--init_t")
.help("Initial temperature for manual annealing schedule")
.default_value("100.0")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.PlaceExitT, "--exit_t")
place_grp.add_argument(args.place_exit_t, "--exit_t")
.help("Temperature at which annealing which terminate for manual annealing schedule")
.default_value("0.01")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.PlaceAlphaT, "--alpha_t")
place_grp.add_argument(args.place_alpha_t, "--alpha_t")
.help(
"Temperature scaling factor for manual annealing schedule."
" Old temperature is multiplied by alpha_t")
Expand All @@ -2259,7 +2290,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.default_value("")
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.PlaceAlgorithm, "--place_algorithm")
place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.place_algorithm, "--place_algorithm")
.help(
"Controls which placement algorithm is used. Valid options:\n"
" * bounding_box: Focuses purely on minimizing the bounding box wirelength of the circuit. Turns off timing analysis if specified.\n"
Expand All @@ -2269,7 +2300,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.choices({"bounding_box", "criticality_timing", "slack_timing"})
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.PlaceQuenchAlgorithm, "--place_quench_algorithm")
place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.place_quench_algorithm, "--place_quench_algorithm")
.help(
"Controls which placement algorithm is used during placement quench.\n"
"If specified, it overrides the option --place_algorithm during placement quench.\n"
Expand All @@ -2281,7 +2312,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.choices({"bounding_box", "criticality_timing", "slack_timing"})
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument(args.PlaceChanWidth, "--place_chan_width")
place_grp.add_argument(args.place_chan_width, "--place_chan_width")
.help(
"Sets the assumed channel width during placement. "
"If --place_chan_width is unspecified, but --route_chan_width is specified the "
Expand Down Expand Up @@ -2334,15 +2365,21 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
"Specifies the type of bounding box to be used in 3D architectures.\n"
"\n"
"MODE options:\n"
" auto_bb : Automatically determine the appropriate bounding box based on the connections between layers.\n"
" cube_bb : Use 3D bounding boxes.\n"
" per_layer_bb : Use per-layer bounding boxes.\n"
" auto_bb : Automatically determine the appropriate bounding box based on the connections between layers.\n"
" cube_bb : Use 3D bounding boxes.\n"
" per_layer_bb : Use per-layer bounding boxes.\n"
"\n"
"Choose one of the available modes to define the behavior of bounding boxes in your 3D architecture. The default mode is 'automatic'.")
.default_value("auto_bb")
.choices({"auto_bb", "cube_bb", "per_layer_bb"})
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument<e_place_freq, ParsePlacementFreq>(args.place_placement_freq, "--place_frequency")
.help("Run placement every time or only once during channel width search.")
.default_value("once")
.choices({"once", "always"})
.show_in(argparse::ShowIn::HELP_ONLY);

place_grp.add_argument<bool, ParseOnOff>(args.RL_agent_placement, "--RL_agent_placement")
.help(
"Uses a Reinforcement Learning (RL) agent in choosing the appropriate move type in placement."
Expand Down Expand Up @@ -2483,14 +2520,14 @@ 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")
place_timing_grp.add_argument(args.place_timing_tradeoff, "--timing_tradeoff")
.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.RecomputeCritIter, "--recompute_crit_iter")
place_timing_grp.add_argument(args.recompute_crit_iter, "--recompute_crit_iter")
.help("Controls how many temperature updates occur between timing analysis during placement")
.default_value("1")
.show_in(argparse::ShowIn::HELP_ONLY);
Expand Down Expand Up @@ -3449,11 +3486,11 @@ void set_conditional_defaults(t_options& args) {
*/

//Which placement algorithm to use?
if (args.PlaceAlgorithm.provenance() != Provenance::SPECIFIED) {
if (args.place_algorithm.provenance() != Provenance::SPECIFIED) {
if (args.timing_analysis) {
args.PlaceAlgorithm.set(e_place_algorithm::CRITICALITY_TIMING_PLACE, Provenance::INFERRED);
args.place_algorithm.set(e_place_algorithm::CRITICALITY_TIMING_PLACE, Provenance::INFERRED);
} else {
args.PlaceAlgorithm.set(e_place_algorithm::BOUNDING_BOX_PLACE, Provenance::INFERRED);
args.place_algorithm.set(e_place_algorithm::BOUNDING_BOX_PLACE, Provenance::INFERRED);
}
}

Expand All @@ -3467,7 +3504,7 @@ void set_conditional_defaults(t_options& args) {
// Check for correct options combinations
// If you are running WLdriven placement, the RL reward function should be
// either basic or nonPenalizing basic
if (args.RL_agent_placement && (args.PlaceAlgorithm == e_place_algorithm::BOUNDING_BOX_PLACE || !args.timing_analysis)) {
if (args.RL_agent_placement && (args.place_algorithm == e_place_algorithm::BOUNDING_BOX_PLACE || !args.timing_analysis)) {
if (args.place_reward_fun.value() != "basic" && args.place_reward_fun.value() != "nonPenalizing_basic") {
VTR_LOG_WARN(
"To use RLPlace for WLdriven placements, the reward function should be basic or nonPenalizing_basic.\n"
Expand All @@ -3478,18 +3515,18 @@ void set_conditional_defaults(t_options& args) {
}

//Which placement algorithm to use during placement quench?
if (args.PlaceQuenchAlgorithm.provenance() != Provenance::SPECIFIED) {
args.PlaceQuenchAlgorithm.set(args.PlaceAlgorithm, Provenance::INFERRED);
if (args.place_quench_algorithm.provenance() != Provenance::SPECIFIED) {
args.place_quench_algorithm.set(args.place_algorithm, Provenance::INFERRED);
}

//Place chan width follows Route chan width if unspecified
if (args.PlaceChanWidth.provenance() != Provenance::SPECIFIED && args.RouteChanWidth.provenance() == Provenance::SPECIFIED) {
args.PlaceChanWidth.set(args.RouteChanWidth.value(), Provenance::INFERRED);
if (args.place_chan_width.provenance() != Provenance::SPECIFIED && args.RouteChanWidth.provenance() == Provenance::SPECIFIED) {
args.place_chan_width.set(args.RouteChanWidth.value(), Provenance::INFERRED);
}

//Do we calculate timing info during placement?
if (args.ShowPlaceTiming.provenance() != Provenance::SPECIFIED) {
args.ShowPlaceTiming.set(args.timing_analysis, Provenance::INFERRED);
if (args.show_place_timing.provenance() != Provenance::SPECIFIED) {
args.show_place_timing.set(args.timing_analysis, Provenance::INFERRED);
}

//Slave quench recompute divider of inner loop recompute divider unless specified
Expand All @@ -3498,9 +3535,9 @@ void set_conditional_defaults(t_options& args) {
}

//Which schedule?
if (args.PlaceInitT.provenance() == Provenance::SPECIFIED // Any of these flags select a manual schedule
|| args.PlaceExitT.provenance() == Provenance::SPECIFIED
|| args.PlaceAlphaT.provenance() == Provenance::SPECIFIED) {
if (args.place_init_t.provenance() == Provenance::SPECIFIED // Any of these flags select a manual schedule
|| args.place_exit_t.provenance() == Provenance::SPECIFIED
|| args.place_alpha_t.provenance() == Provenance::SPECIFIED) {
args.anneal_sched_type.set(e_sched_type::USER_SCHED, Provenance::INFERRED);
} else {
args.anneal_sched_type.set(e_sched_type::AUTO_SCHED, Provenance::INFERRED); // Otherwise use the automatic schedule
Expand Down
Loading