From 58413b7ee737dd30bd12174f6877b1b9435be08a Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 11:09:28 -0400 Subject: [PATCH 1/9] call clean_floorplanning_context_post_place() outside try_place() --- vpr/src/base/place_and_route.cpp | 2 ++ vpr/src/base/setup_vpr.cpp | 2 +- vpr/src/base/vpr_api.cpp | 12 +++++++----- vpr/src/place/place.cpp | 26 +++++++++++--------------- vpr/src/place/place_constraints.cpp | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/vpr/src/base/place_and_route.cpp b/vpr/src/base/place_and_route.cpp index 138d411539d..b7145f3ef09 100644 --- a/vpr/src/base/place_and_route.cpp +++ b/vpr/src/base/place_and_route.cpp @@ -360,6 +360,8 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list, } } + g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place(); + // End binary search verification. // Restore the best placement (if necessary), the best routing, and the // best channel widths for final drawing and statistics output. diff --git a/vpr/src/base/setup_vpr.cpp b/vpr/src/base/setup_vpr.cpp index 4f2cc967bca..4148bdeac4b 100644 --- a/vpr/src/base/setup_vpr.cpp +++ b/vpr/src/base/setup_vpr.cpp @@ -683,7 +683,7 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->delay_model_type = Options.place_delay_model; PlacerOpts->delay_model_reducer = Options.place_delay_model_reducer; - PlacerOpts->place_freq = PLACE_ONCE; /* DEFAULT */ + PlacerOpts->place_freq = PLACE_ALWAYS; /* DEFAULT */ PlacerOpts->post_place_timing_report_file = Options.post_place_timing_report_file; diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index dcd0d2394c9..7ba9580ef9d 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -726,7 +726,7 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) { auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); const AtomContext& atom_ctx = g_vpr_ctx.atom(); - /* Ensure we have a clean start with void net remapping information */ + // Ensure we have a clean start with void net remapping information cluster_ctx.post_routing_clb_pin_nets.clear(); cluster_ctx.pre_routing_net_pin_mapping.clear(); @@ -735,7 +735,7 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) { vpr_setup.FileNameOpts.verify_file_digests, vpr_setup.PackerOpts.pack_verbosity); - /* Load the mapping between clusters and their atoms */ + // Load the mapping between clusters and their atoms init_clb_atoms_lookup(cluster_ctx.atoms_lookup, atom_ctx, cluster_ctx.clb_nlist); process_constant_nets(g_vpr_ctx.mutable_atom().mutable_netlist(), @@ -749,14 +749,14 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) { report_packing_pin_usage(ofs, g_vpr_ctx); } - // Ater the clustered netlist has been loaded, update the floorplanning + // After the clustered netlist has been loaded, update the floorplanning // constraints with the new information. g_vpr_ctx.mutable_floorplanning().update_floorplanning_context_post_pack(); /* Sanity check the resulting netlist */ check_netlist(vpr_setup.PackerOpts.pack_verbosity); - // Independently verify the clusterings to ensure the clustering can be + // Independently verify the clustering to ensure the clustering can be // used for the rest of the VPR flow. unsigned num_errors = verify_clustering(g_vpr_ctx); if (num_errors == 0) { @@ -768,7 +768,7 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) { num_errors); } - /* Output the netlist stats to console and optionally to file. */ + // Output the netlist stats to console and optionally to file. writeClusteredNetlistStats(vpr_setup.FileNameOpts.write_block_usage); // print the total number of used physical blocks for each @@ -887,6 +887,8 @@ void vpr_place(const Netlist<>& net_list, g_vpr_ctx.atom().flat_placement_info(), is_flat); + g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place(); + auto& filename_opts = vpr_setup.FileNameOpts; auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& block_locs = g_vpr_ctx.placement().block_locs(); diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index c5d46b5af3f..6f2ebb89e0f 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -38,10 +38,9 @@ void try_place(const Netlist<>& net_list, const FlatPlacementInfo& flat_placement_info, bool is_flat) { - /* Currently, the functions that require is_flat as their parameter and are called during placement should - * receive is_flat as false. For example, if the RR graph of router lookahead is built here, it should be as - * if is_flat is false, even if is_flat is set to true from the command line. - */ + // Currently, the functions that require is_flat as their parameter and are called during placement should + // receive is_flat as false. For example, if the RR graph of router lookahead is built here, it should be as + // if is_flat is false, even if is_flat is set to true from the command line VTR_ASSERT(!is_flat); const auto& device_ctx = g_vpr_ctx.device(); const auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -74,9 +73,9 @@ void try_place(const Netlist<>& net_list, normalize_noc_cost_weighting_factor(const_cast(noc_opts)); } - /* Placement delay model is independent of the placement and can be shared across - * multiple placers if we are performing parallel annealing. - * So, it is created and initialized once. */ + // Placement delay model is independent of the placement and can be shared across + // multiple placers if we are performing parallel annealing. + // So, it is created and initialized once. */ std::shared_ptr place_delay_model; if (placer_opts.place_algorithm.is_timing_driven()) { @@ -101,9 +100,8 @@ void try_place(const Netlist<>& net_list, */ mutable_placement.lock_loc_vars(); - /* Start measuring placement time. The measured execution time will be printed - * when this object goes out of scope at the end of this function. - */ + // Start measuring placement time. The measured execution time will be printed + // when this object goes out of scope at the end of this function. vtr::ScopedStartFinishTimer placement_timer("Placement"); // Enables fast look-up pb graph pins from block pin indices @@ -117,17 +115,15 @@ void try_place(const Netlist<>& net_list, placer.place(); - /* The placer object has its own copy of block locations and doesn't update - * the global context directly. We need to copy its internal data structures - * to the global placement context before it goes out of scope. - */ + // The placer object has its own copy of block locations and doesn't update + // the global context directly. We need to copy its internal data structures + // to the global placement context before it goes out of scope. placer.update_global_state(); // Clean the variables in the placement context. This will deallocate memory // used by variables which were allocated in the placement context and are // never used outside of placement. mutable_placement.clean_placement_context_post_place(); - mutable_floorplanning.clean_floorplanning_context_post_place(); } #ifdef VERBOSE diff --git a/vpr/src/place/place_constraints.cpp b/vpr/src/place/place_constraints.cpp index ef867ce5b1a..fdad4813cb2 100644 --- a/vpr/src/place/place_constraints.cpp +++ b/vpr/src/place/place_constraints.cpp @@ -209,7 +209,7 @@ void load_cluster_constraints() { floorplanning_ctx.cluster_constraints.resize(cluster_ctx.clb_nlist.blocks().size()); - for (auto cluster_id : cluster_ctx.clb_nlist.blocks()) { + for (ClusterBlockId cluster_id : cluster_ctx.clb_nlist.blocks()) { const std::unordered_set& atoms = cluster_ctx.atoms_lookup[cluster_id]; PartitionRegion empty_pr; floorplanning_ctx.cluster_constraints[cluster_id] = empty_pr; From d8ebd1818c84eb148a14c0ada7cac3251cb4a686 Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 13:48:45 -0400 Subject: [PATCH 2/9] snake case, comment style, and typos --- vpr/src/base/read_options.cpp | 46 +++++++++++++-------------- vpr/src/base/read_options.h | 51 +++++++++++++++--------------- vpr/src/base/setup_vpr.cpp | 20 ++++++------ vpr/src/base/vpr_api.cpp | 3 +- vpr/src/pack/verify_clustering.cpp | 2 +- vpr/src/place/place.cpp | 29 ++++++++--------- 6 files changed, 75 insertions(+), 76 deletions(-) diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 57c449b6d26..401f6f09fc4 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -2177,7 +2177,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); @@ -2195,7 +2195,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); @@ -2226,17 +2226,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") @@ -2259,7 +2259,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(args.PlaceAlgorithm, "--place_algorithm") + place_grp.add_argument(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" @@ -2269,7 +2269,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.PlaceQuenchAlgorithm, "--place_quench_algorithm") + place_grp.add_argument(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" @@ -2281,7 +2281,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 " @@ -2483,14 +2483,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); @@ -3449,11 +3449,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); } } @@ -3467,7 +3467,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" @@ -3478,18 +3478,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 @@ -3498,9 +3498,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 diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index f846867af77..ece3e391629 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -9,7 +9,7 @@ #include "argparse.hpp" struct t_options { - /* File names */ + // File names argparse::ArgValue ArchFile; argparse::ArgValue CircuitName; argparse::ArgValue NetFile; @@ -49,7 +49,7 @@ struct t_options { argparse::ArgValue write_block_usage; - /* Stage Options */ + // Stage Options argparse::ArgValue do_packing; argparse::ArgValue do_legalize; argparse::ArgValue do_placement; @@ -58,13 +58,13 @@ struct t_options { argparse::ArgValue do_analysis; argparse::ArgValue do_power; - /* Graphics Options */ + // Graphics Options argparse::ArgValue show_graphics; ///eractive graphics? argparse::ArgValue GraphPause; argparse::ArgValue save_graphics; argparse::ArgValue graphics_commands; - /* General options */ + // General options argparse::ArgValue show_help; argparse::ArgValue show_version; argparse::ArgValue show_arch_resources; @@ -86,11 +86,11 @@ struct t_options { argparse::ArgValue allow_dangling_combinational_nodes; argparse::ArgValue terminate_if_timing_fails; - /* Server options */ + // Server options argparse::ArgValue is_server_mode_enabled; argparse::ArgValue server_port_num; - /* Atom netlist options */ + // Atom netlist options argparse::ArgValue absorb_buffer_luts; argparse::ArgValue const_gen_inference; argparse::ArgValue sweep_dangling_primary_ios; @@ -99,7 +99,7 @@ struct t_options { argparse::ArgValue sweep_constant_primary_outputs; argparse::ArgValue netlist_verbosity; - /* Analytical Placement options */ + // Analytical Placement options argparse::ArgValue ap_analytical_solver; argparse::ArgValue ap_partial_legalizer; argparse::ArgValue ap_full_legalizer; @@ -111,7 +111,7 @@ struct t_options { argparse::ArgValue ap_high_fanout_threshold; argparse::ArgValue ap_generate_mass_report; - /* Clustering options */ + // Clustering options argparse::ArgValue connection_driven_clustering; argparse::ArgValue allow_unrelated_clustering; argparse::ArgValue timing_gain_weight; @@ -126,19 +126,20 @@ struct t_options { argparse::ArgValue pack_feasible_block_array_size; argparse::ArgValue> pack_high_fanout_threshold; argparse::ArgValue pack_verbosity; - /* Placement options */ - argparse::ArgValue Seed; - argparse::ArgValue ShowPlaceTiming; - argparse::ArgValue PlaceInnerNum; + + // Placement options + argparse::ArgValue seed; + argparse::ArgValue show_place_timing; + argparse::ArgValue place_inner_num; argparse::ArgValue place_auto_init_t_scale; - argparse::ArgValue PlaceInitT; - argparse::ArgValue PlaceExitT; - argparse::ArgValue PlaceAlphaT; + argparse::ArgValue place_init_t; + argparse::ArgValue place_exit_t; + argparse::ArgValue place_alpha_t; argparse::ArgValue anneal_sched_type; - argparse::ArgValue PlaceAlgorithm; - argparse::ArgValue PlaceQuenchAlgorithm; + argparse::ArgValue place_algorithm; + argparse::ArgValue place_quench_algorithm; argparse::ArgValue pad_loc_type; - argparse::ArgValue PlaceChanWidth; + argparse::ArgValue place_chan_width; argparse::ArgValue place_rlim_escape_fraction; argparse::ArgValue place_move_stats_file; argparse::ArgValue placement_saves_per_temperature; @@ -167,7 +168,7 @@ struct t_options { argparse::ArgValue placer_debug_block; argparse::ArgValue placer_debug_net; - /*NoC Options*/ + // NoC Options argparse::ArgValue noc; argparse::ArgValue noc_flows_file; argparse::ArgValue noc_routing_algorithm; @@ -185,9 +186,9 @@ struct t_options { argparse::ArgValue noc_sat_routing_log_search_progress; argparse::ArgValue noc_placement_file_name; - /* Timing-driven placement options only */ - argparse::ArgValue PlaceTimingTradeoff; - argparse::ArgValue RecomputeCritIter; + // Timing-driven placement options only + argparse::ArgValue place_timing_tradeoff; + argparse::ArgValue recompute_crit_iter; argparse::ArgValue inner_loop_recompute_divider; argparse::ArgValue quench_recompute_divider; argparse::ArgValue place_exp_first; @@ -202,7 +203,7 @@ struct t_options { argparse::ArgValue place_delay_model_reducer; argparse::ArgValue allowed_tiles_for_delay_model; - /* Router Options */ + // Router Options argparse::ArgValue check_rr_graph; argparse::ArgValue max_router_iterations; argparse::ArgValue first_iter_pres_fac; @@ -232,7 +233,7 @@ struct t_options { argparse::ArgValue route_verbosity; argparse::ArgValue custom_3d_sb_fanin_fanout; - /* Timing-driven router options only */ + // Timing-driven router options only argparse::ArgValue astar_fac; argparse::ArgValue astar_offset; argparse::ArgValue router_profiler_astar_fac; @@ -267,7 +268,7 @@ struct t_options { argparse::ArgValue router_initial_timing; argparse::ArgValue router_heap; - /* Analysis options */ + // Analysis options argparse::ArgValue full_stats; argparse::ArgValue Generate_Post_Synthesis_Netlist; argparse::ArgValue Generate_Post_Implementation_Merged_Netlist; diff --git a/vpr/src/base/setup_vpr.cpp b/vpr/src/base/setup_vpr.cpp index 4148bdeac4b..8f3b6f0b4c8 100644 --- a/vpr/src/base/setup_vpr.cpp +++ b/vpr/src/base/setup_vpr.cpp @@ -542,17 +542,17 @@ static void setup_router_opts(const t_options& Options, t_router_opts* RouterOpt static void setup_anneal_sched(const t_options& Options, t_annealing_sched* AnnealSched) { - AnnealSched->alpha_t = Options.PlaceAlphaT; + AnnealSched->alpha_t = Options.place_alpha_t; if (AnnealSched->alpha_t >= 1 || AnnealSched->alpha_t <= 0) { VPR_FATAL_ERROR(VPR_ERROR_OTHER, "alpha_t must be between 0 and 1 exclusive.\n"); } - AnnealSched->exit_t = Options.PlaceExitT; + AnnealSched->exit_t = Options.place_exit_t; if (AnnealSched->exit_t <= 0) { VPR_FATAL_ERROR(VPR_ERROR_OTHER, "exit_t must be greater than 0.\n"); } - AnnealSched->init_t = Options.PlaceInitT; + AnnealSched->init_t = Options.place_init_t; if (AnnealSched->init_t <= 0) { VPR_FATAL_ERROR(VPR_ERROR_OTHER, "init_t must be greater than 0.\n"); } @@ -561,7 +561,7 @@ static void setup_anneal_sched(const t_options& Options, VPR_FATAL_ERROR(VPR_ERROR_OTHER, "init_t must be greater or equal to than exit_t.\n"); } - AnnealSched->inner_num = Options.PlaceInnerNum; + AnnealSched->inner_num = Options.place_inner_num; if (AnnealSched->inner_num <= 0) { VPR_FATAL_ERROR(VPR_ERROR_OTHER, "inner_num must be greater than 0.\n"); } @@ -657,8 +657,8 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->td_place_exp_last = Options.place_exp_last; - PlacerOpts->place_algorithm = Options.PlaceAlgorithm; - PlacerOpts->place_quench_algorithm = Options.PlaceQuenchAlgorithm; + PlacerOpts->place_algorithm = Options.place_algorithm; + PlacerOpts->place_quench_algorithm = Options.place_quench_algorithm; PlacerOpts->constraints_file = Options.constraints_file; @@ -668,11 +668,11 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->pad_loc_type = Options.pad_loc_type; - PlacerOpts->place_chan_width = Options.PlaceChanWidth; + PlacerOpts->place_chan_width = Options.place_chan_width; - PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter; + PlacerOpts->recompute_crit_iter = Options.recompute_crit_iter; - PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff; + PlacerOpts->timing_tradeoff = Options.place_timing_tradeoff; /* Depends on PlacerOpts->place_algorithm */ PlacerOpts->delay_offset = Options.place_delay_offset; @@ -721,7 +721,7 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->floorplan_num_vertical_partitions = Options.floorplan_num_vertical_partitions; PlacerOpts->place_quench_only = Options.place_quench_only; - PlacerOpts->seed = Options.Seed; + PlacerOpts->seed = Options.seed; PlacerOpts->placer_debug_block = Options.placer_debug_block; PlacerOpts->placer_debug_net = Options.placer_debug_net; diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index 7ba9580ef9d..d3a8ec901c3 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -753,7 +753,7 @@ void vpr_load_packing(const t_vpr_setup& vpr_setup, const t_arch& arch) { // constraints with the new information. g_vpr_ctx.mutable_floorplanning().update_floorplanning_context_post_pack(); - /* Sanity check the resulting netlist */ + // Sanity check the resulting netlist check_netlist(vpr_setup.PackerOpts.pack_verbosity); // Independently verify the clustering to ensure the clustering can be @@ -887,7 +887,6 @@ void vpr_place(const Netlist<>& net_list, g_vpr_ctx.atom().flat_placement_info(), is_flat); - g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place(); auto& filename_opts = vpr_setup.FileNameOpts; auto& cluster_ctx = g_vpr_ctx.clustering(); diff --git a/vpr/src/pack/verify_clustering.cpp b/vpr/src/pack/verify_clustering.cpp index ec08e10a40b..93f925ef68b 100644 --- a/vpr/src/pack/verify_clustering.cpp +++ b/vpr/src/pack/verify_clustering.cpp @@ -406,7 +406,7 @@ unsigned verify_clustering(const ClusteredNetlist& clb_nlist, // Return here since this error can cause serious issues below. return num_errors; } - // Check conssitency between which clusters the atom's think thet are in and + // Check consistency between which clusters the atom's think thet are in and // which atoms the clusters think they have. num_errors += check_clustering_atom_consistency(clb_nlist, atom_nlist, diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 6f2ebb89e0f..467dbed31f9 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -59,16 +59,16 @@ void try_place(const Netlist<>& net_list, VTR_LOG("Bounding box mode is %s\n", (mutable_placement.cube_bb ? "Cube" : "Per-layer")); VTR_LOG("\n"); - /* To make sure the importance of NoC-related cost terms compared to - * BB and timing cost is determine only through NoC placement weighting factor, - * we normalize NoC-related cost weighting factors so that they add up to 1. - * With this normalization, NoC-related cost weighting factors only determine - * the relative importance of NoC cost terms with respect to each other, while - * the importance of total NoC cost to conventional placement cost is determined - * by NoC placement weighting factor. - * FIXME: This should not be modifying the NoC Opts here, this normalization - * should occur when these Opts are loaded in. - */ + + // To make sure the importance of NoC-related cost terms compared to + // BB and timing cost is determine only through NoC placement weighting factor, + // we normalize NoC-related cost weighting factors so that they add up to 1. + // With this normalization, NoC-related cost weighting factors only determine + // the relative importance of NoC cost terms with respect to each other, while + // the importance of total NoC cost to conventional placement cost is determined + // by NoC placement weighting factor. + // FIXME: This should not be modifying the NoC Opts here, this normalization + // should occur when these Opts are loaded in. if (noc_opts.noc) { normalize_noc_cost_weighting_factor(const_cast(noc_opts)); } @@ -94,10 +94,9 @@ void try_place(const Netlist<>& net_list, } } - /* Make the global instance of BlkLocRegistry inaccessible through the getter methods of the - * placement context. This is done to make sure that the placement stage only accesses its - * own local instances of BlkLocRegistry. - */ + // Make the global instance of BlkLocRegistry inaccessible through the getter methods of the + // placement context. This is done to make sure that the placement stage only accesses its + // own local instances of BlkLocRegistry. mutable_placement.lock_loc_vars(); // Start measuring placement time. The measured execution time will be printed @@ -150,7 +149,7 @@ static void update_screen_debug(); //Performs a major (i.e. interactive) placement screen update. //This function with no arguments is useful for calling from a debugger to -//look at the intermediate implemetnation state. +//look at the intermediate implementation state. static void update_screen_debug() { update_screen(ScreenUpdatePriority::MAJOR, "DEBUG", PLACEMENT, nullptr); } From b8604c6f058aaabab114bea692576f7c1315f59a Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 13:49:16 -0400 Subject: [PATCH 3/9] call pdate_floorplanning_context_post_pack() at the start of placement if cluster_constraints.empty() --- vpr/src/base/place_and_route.cpp | 2 -- vpr/src/place/place.cpp | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vpr/src/base/place_and_route.cpp b/vpr/src/base/place_and_route.cpp index b7145f3ef09..138d411539d 100644 --- a/vpr/src/base/place_and_route.cpp +++ b/vpr/src/base/place_and_route.cpp @@ -360,8 +360,6 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list, } } - g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place(); - // End binary search verification. // Restore the best placement (if necessary), the best routing, and the // best channel widths for final drawing and statistics output. diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 467dbed31f9..6133c89fff1 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -51,6 +51,10 @@ void try_place(const Netlist<>& net_list, // Initialize the variables in the placement context. mutable_placement.init_placement_context(placer_opts, directs); + if (mutable_floorplanning.cluster_constraints.empty()) { + mutable_floorplanning.update_floorplanning_context_post_pack(); + } + // Update the floorplanning constraints with the macro information from the // placement context. mutable_floorplanning.update_floorplanning_context_pre_place(*mutable_placement.place_macros); @@ -123,6 +127,7 @@ void try_place(const Netlist<>& net_list, // used by variables which were allocated in the placement context and are // never used outside of placement. mutable_placement.clean_placement_context_post_place(); + mutable_floorplanning.clean_floorplanning_context_post_place(); } #ifdef VERBOSE From 88b8c1030f29c3e62439f4293c2439cbec47f991 Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 15:21:46 -0400 Subject: [PATCH 4/9] enum class e_place_freq --- vpr/src/base/ShowSetup.cpp | 15 +++++++-------- vpr/src/base/place_and_route.cpp | 8 ++++---- vpr/src/base/setup_vpr.cpp | 2 +- vpr/src/base/vpr_types.h | 16 +++++++++------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index 2e8d36e5f2c..0a10a017772 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -495,20 +495,19 @@ 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"); + case e_place_freq::ALWAYS: + VTR_LOG("ALWAYS\n"); break; - case PLACE_NEVER: - VTR_LOG("PLACE_NEVER\n"); + case e_place_freq::NEVER: + VTR_LOG("NEVER\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: diff --git a/vpr/src/base/place_and_route.cpp b/vpr/src/base/place_and_route.cpp index 138d411539d..6381eb39dc3 100644 --- a/vpr/src/base/place_and_route.cpp +++ b/vpr/src/base/place_and_route.cpp @@ -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, @@ -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, @@ -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(), @@ -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 diff --git a/vpr/src/base/setup_vpr.cpp b/vpr/src/base/setup_vpr.cpp index 8f3b6f0b4c8..09728e969bb 100644 --- a/vpr/src/base/setup_vpr.cpp +++ b/vpr/src/base/setup_vpr.cpp @@ -683,7 +683,7 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->delay_model_type = Options.place_delay_model; PlacerOpts->delay_model_reducer = Options.place_delay_model_reducer; - PlacerOpts->place_freq = PLACE_ALWAYS; /* DEFAULT */ + PlacerOpts->place_freq = e_place_freq::ALWAYS; /* DEFAULT */ PlacerOpts->post_place_timing_report_file = Options.post_place_timing_report_file; diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 41da9a6d085..726b8c3e02d 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -375,23 +375,25 @@ constexpr int NUM_PL_MOVE_TYPES = 7; constexpr int NUM_PL_NONTIMING_MOVE_TYPES = 3; /* Timing data structures end */ + +// Annealing schedule enum class e_sched_type { AUTO_SCHED, USER_SCHED }; -/* Annealing schedule */ + +// What's on screen? enum pic_type { NO_PICTURE, PLACEMENT, ROUTING }; -/* What's on screen? */ -enum pfreq { - PLACE_NEVER, - PLACE_ONCE, - PLACE_ALWAYS +enum class e_place_freq { + NEVER, + ONCE, + ALWAYS }; ///@brief Power data for t_netlist structure @@ -1032,7 +1034,7 @@ struct t_placer_opts { std::string constraints_file; std::string write_initial_place_file; std::string read_initial_place_file; - enum pfreq place_freq; + e_place_freq place_freq; int recompute_crit_iter; int inner_loop_recompute_divider; int quench_recompute_divider; From eff6743a986bbe1462720d7627e7ce7e770658b0 Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 15:35:32 -0400 Subject: [PATCH 5/9] remove e_place_freq::NEVER --- vpr/src/base/ShowSetup.cpp | 3 --- vpr/src/base/vpr_types.h | 1 - 2 files changed, 4 deletions(-) diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index 0a10a017772..858bd3198ce 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -501,9 +501,6 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts) { case e_place_freq::ALWAYS: VTR_LOG("ALWAYS\n"); break; - case e_place_freq::NEVER: - VTR_LOG("NEVER\n"); - break; default: VTR_LOG_ERROR("Unknown Place Freq\n"); } diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 726b8c3e02d..e9c49f4f281 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -391,7 +391,6 @@ enum pic_type { }; enum class e_place_freq { - NEVER, ONCE, ALWAYS }; From 4192107a41b750c72af372403f195427a6ee4ecb Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 15:36:24 -0400 Subject: [PATCH 6/9] add --place_frequency to read_options --- vpr/src/base/read_options.cpp | 37 +++++++++++++++++++++++++++++++++++ vpr/src/base/read_options.h | 1 + vpr/src/base/setup_vpr.cpp | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 401f6f09fc4..eb1daa4063d 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -618,6 +618,37 @@ struct ParsePlaceBoundingBox { } }; +struct ParsePlacementFreq { + ConvertedValue from_str(const std::string& str) { + ConvertedValue 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 to_str(e_place_freq val) { + ConvertedValue 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 default_choices() { + return {"once", "always"}; + } +}; + struct ParsePlaceAgentAlgorithm { ConvertedValue from_str(const std::string& str) { ConvertedValue conv_value; @@ -2343,6 +2374,12 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .choices({"auto_bb", "cube_bb", "per_layer_bb"}) .show_in(argparse::ShowIn::HELP_ONLY); + place_grp.add_argument(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(args.RL_agent_placement, "--RL_agent_placement") .help( "Uses a Reinforcement Learning (RL) agent in choosing the appropriate move type in placement." diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index ece3e391629..d364354ecfc 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -148,6 +148,7 @@ struct t_options { argparse::ArgValue> place_static_move_prob; argparse::ArgValue place_high_fanout_net; argparse::ArgValue place_bounding_box_mode; + argparse::ArgValue place_placement_freq; argparse::ArgValue RL_agent_placement; argparse::ArgValue place_agent_multistate; diff --git a/vpr/src/base/setup_vpr.cpp b/vpr/src/base/setup_vpr.cpp index 09728e969bb..f010181d82e 100644 --- a/vpr/src/base/setup_vpr.cpp +++ b/vpr/src/base/setup_vpr.cpp @@ -683,7 +683,7 @@ static void setup_placer_opts(const t_options& Options, t_placer_opts* PlacerOpt PlacerOpts->delay_model_type = Options.place_delay_model; PlacerOpts->delay_model_reducer = Options.place_delay_model_reducer; - PlacerOpts->place_freq = e_place_freq::ALWAYS; /* DEFAULT */ + PlacerOpts->place_freq = Options.place_placement_freq; PlacerOpts->post_place_timing_report_file = Options.post_place_timing_report_file; From 7c3210094495b80ef2b02c71d77aa68b941a2ebb Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 16:00:11 -0400 Subject: [PATCH 7/9] update command_line_usage.rst to add --place_frequency --- doc/src/vpr/command_line_usage.rst | 13 ++++++++++++- vpr/src/base/read_options.cpp | 6 +++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/src/vpr/command_line_usage.rst b/doc/src/vpr/command_line_usage.rst index b3d482e048a..fe1b46f83b6 100644 --- a/doc/src/vpr/command_line_usage.rst +++ b/doc/src/vpr/command_line_usage.rst @@ -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 Tells VPR how many tracks a channel of relative width 1 is expected to need to complete routing of this circuit. @@ -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 + 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. @@ -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 - 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 diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index eb1daa4063d..6d013d8b9ed 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -2365,9 +2365,9 @@ 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") From c816b60225f01bec33d9840b7dcf2a9a286285d7 Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 16:37:55 -0400 Subject: [PATCH 8/9] make format --- vpr/src/base/vpr_api.cpp | 1 - vpr/src/base/vpr_types.h | 1 - vpr/src/place/place.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index d3a8ec901c3..17c6df68327 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -887,7 +887,6 @@ void vpr_place(const Netlist<>& net_list, g_vpr_ctx.atom().flat_placement_info(), is_flat); - auto& filename_opts = vpr_setup.FileNameOpts; auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& block_locs = g_vpr_ctx.placement().block_locs(); diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index e9c49f4f281..70449e6fb47 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -382,7 +382,6 @@ enum class e_sched_type { USER_SCHED }; - // What's on screen? enum pic_type { NO_PICTURE, diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 6133c89fff1..9e573623385 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -63,7 +63,6 @@ void try_place(const Netlist<>& net_list, VTR_LOG("Bounding box mode is %s\n", (mutable_placement.cube_bb ? "Cube" : "Per-layer")); VTR_LOG("\n"); - // To make sure the importance of NoC-related cost terms compared to // BB and timing cost is determine only through NoC placement weighting factor, // we normalize NoC-related cost weighting factors so that they add up to 1. From 4e3f4bbab750379599f2fb41cdced7160c73fbfd Mon Sep 17 00:00:00 2001 From: Soheil Shahrouz Date: Mon, 21 Jul 2025 19:04:13 -0400 Subject: [PATCH 9/9] fix the issue with choices for --place_frequency --- vpr/src/base/read_options.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 6d013d8b9ed..e8d208922bb 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -2377,7 +2377,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio place_grp.add_argument(args.place_placement_freq, "--place_frequency") .help("Run placement every time or only once during channel width search.") .default_value("once") - .choices({"once, always"}) + .choices({"once", "always"}) .show_in(argparse::ShowIn::HELP_ONLY); place_grp.add_argument(args.RL_agent_placement, "--RL_agent_placement")