From 826cc37067bdbed95b65b70361dd3b42609cf101 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Wed, 1 Feb 2023 19:46:43 -0500 Subject: [PATCH 1/8] Enabling unrelated clustering by block type --- vpr/src/base/ShowSetup.cpp | 11 +-- vpr/src/base/read_options.cpp | 88 ++++----------------- vpr/src/base/read_options.h | 2 +- vpr/src/base/vpr_types.cpp | 30 +++++++ vpr/src/base/vpr_types.h | 49 +++++++++++- vpr/src/pack/cluster.cpp | 11 ++- vpr/src/pack/cluster.h | 2 +- vpr/src/pack/pack.cpp | 143 +++++++++++++++++++++++++++++----- 8 files changed, 226 insertions(+), 110 deletions(-) diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index c4856e38e51..284caf229a1 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -730,16 +730,7 @@ static void ShowAnalysisOpts(const t_analysis_opts& AnalysisOpts) { } static void ShowPackerOpts(const t_packer_opts& PackerOpts) { - VTR_LOG("PackerOpts.allow_unrelated_clustering: "); - if (PackerOpts.allow_unrelated_clustering == e_unrelated_clustering::ON) { - VTR_LOG("true\n"); - } else if (PackerOpts.allow_unrelated_clustering == e_unrelated_clustering::OFF) { - VTR_LOG("false\n"); - } else if (PackerOpts.allow_unrelated_clustering == e_unrelated_clustering::AUTO) { - VTR_LOG("auto\n"); - } else { - VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown packer allow_unrelated_clustering\n"); - } + VTR_LOG("PackerOpts.allow_unrelated_clustering: %s\n", vtr::join(PackerOpts.allow_unrelated_clustering, " ").c_str()); VTR_LOG("PackerOpts.alpha_clustering: %f\n", PackerOpts.alpha); VTR_LOG("PackerOpts.beta_clustering: %f\n", PackerOpts.beta); VTR_LOG("PackerOpts.cluster_seed_type: "); diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 8fd63ab9bed..2754b384757 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -9,7 +9,6 @@ #include "vtr_log.h" #include "vtr_util.h" #include "vtr_path.h" -#include using argparse::ConvertedValue; using argparse::Provenance; @@ -648,44 +647,6 @@ struct ParseClockModeling { } }; -struct ParseUnrelatedClustering { - ConvertedValue from_str(std::string str) { - ConvertedValue conv_value; - if (str == "on") - conv_value.set_value(e_unrelated_clustering::ON); - else if (str == "off") - conv_value.set_value(e_unrelated_clustering::OFF); - else if (str == "auto") - conv_value.set_value(e_unrelated_clustering::AUTO); - else { - std::stringstream msg; - msg << "Invalid conversion from '" - << str - << "' to e_unrelated_clustering (expected one of: " - << argparse::join(default_choices(), ", ") << ")"; - conv_value.set_error(msg.str()); - } - return conv_value; - } - - ConvertedValue to_str(e_unrelated_clustering val) { - ConvertedValue conv_value; - if (val == e_unrelated_clustering::ON) - conv_value.set_value("on"); - else if (val == e_unrelated_clustering::OFF) - conv_value.set_value("off"); - else { - VTR_ASSERT(val == e_unrelated_clustering::AUTO); - conv_value.set_value("auto"); - } - return conv_value; - } - - std::vector default_choices() { - return {"on", "off", "auto"}; - } -}; - struct ParseBalanceBlockTypeUtil { ConvertedValue from_str(std::string str) { ConvertedValue conv_value; @@ -1629,14 +1590,24 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); - pack_grp.add_argument(args.allow_unrelated_clustering, "--allow_unrelated_clustering") + pack_grp.add_argument(args.allow_unrelated_clustering, "--allow_unrelated_clustering") .help( "Controls whether primitives with no attraction to a cluster can be packed into it.\n" "Turning unrelated clustering on can increase packing density (fewer blocks are used), but at the cost of worse routability.\n" - " * on : Unrelated clustering enabled\n" - " * off : Unrelated clustering disabled\n" - " * auto: Dynamically enabled/disabled (based on density)\n") - .default_value("auto") + "This option can take multiple specifications in several\n" + "formats:\n" + "* auto (i.e. 'auto'): Dynamically enabled/disabled (based on density)\n" + "* on : Unrelated clustering enabled\n" + "* off : Unrelated clustering disabled\n" + "* Specified for a certain block type: (e.g. 'clb:on')\n" + "These can be used in combination. For example:\n" + " '--allow_unrelated_clustering auto io:on'\n" + "would turn on unrelated clustering for io blocks and\n" + "dynamically determine enable/disable unrelated clustering,\n" + "for all all other blocks.\n") + + .nargs('+') + .default_value({"auto"}) .show_in(argparse::ShowIn::HELP_ONLY); pack_grp.add_argument(args.alpha_clustering, "--alpha_clustering") @@ -1773,19 +1744,6 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg .default_value("on") .show_in(argparse::ShowIn::HELP_ONLY); - pack_grp.add_argument(args.pack_num_moves, "--pack_num_moves") - .help( - "The number of moves that can be tried in packing stage") - .default_value("100000") - .show_in(argparse::ShowIn::HELP_ONLY); - - pack_grp.add_argument(args.pack_move_type, "--pack_move_type") - .help( - "The move type used in packing." - "The available values are: randomSwap, semiDirectedSwap, semiDirectedSameTypeSwap") - .default_value("semiDirectedSwap") - .show_in(argparse::ShowIn::HELP_ONLY); - auto& place_grp = parser.add_argument_group("placement options"); place_grp.add_argument(args.Seed, "--seed") @@ -2014,8 +1972,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg place_grp.add_argument(args.place_reward_fun, "--place_reward_fun") .help( "The reward function used by placement RL agent." - "The available values are: basic, nonPenalizing_basic, runtime_aware, WLbiased_runtime_aware" - "The latter two are only available for timing-driven placement.") + "The available values are: basic, nonPenalizing_basic, runtime_aware, WLbiased_runtime_aware") .default_value("WLbiased_runtime_aware") .show_in(argparse::ShowIn::HELP_ONLY); @@ -2764,19 +2721,6 @@ 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 == 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" - "you can specify the reward function using --place_reward_fun.\n" - "Setting the placement reward function to \"basic\"\n"); - args.place_reward_fun.set("basic", Provenance::INFERRED); - } - } - //Which placement algorithm to use during placement quench? if (args.PlaceQuenchAlgorithm.provenance() != Provenance::SPECIFIED) { args.PlaceQuenchAlgorithm.set(args.PlaceAlgorithm, Provenance::INFERRED); diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 70846dd347d..7c087c283eb 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -82,7 +82,7 @@ struct t_options { /* Clustering options */ argparse::ArgValue connection_driven_clustering; - argparse::ArgValue allow_unrelated_clustering; + argparse::ArgValue> allow_unrelated_clustering; argparse::ArgValue alpha_clustering; argparse::ArgValue beta_clustering; argparse::ArgValue timing_driven_clustering; diff --git a/vpr/src/base/vpr_types.cpp b/vpr/src/base/vpr_types.cpp index c6c688e97c3..d8d59a4dd28 100644 --- a/vpr/src/base/vpr_types.cpp +++ b/vpr/src/base/vpr_types.cpp @@ -23,6 +23,36 @@ void t_ext_pin_util_targets::set_default_pin_util(t_ext_pin_util default_target) defaults_ = default_target; } +t_allow_unrelated_clustering::t_allow_unrelated_clustering(enum e_unrel_clust_stat default_stat, enum e_unrel_clust_mode default_mode) { + default_.first = default_stat; + default_.second = default_mode; +} +enum e_unrel_clust_stat t_allow_unrelated_clustering::get_block_status(std::string block_type_name) const{ + auto itr = overrides_.find(block_type_name); + if (itr != overrides_.end()) { + std::pair status = itr->second; + return status.first; + } + return default_.first; +} + +enum e_unrel_clust_mode t_allow_unrelated_clustering::get_block_mode(std::string block_type_name) const{ + auto itr = overrides_.find(block_type_name); + if (itr != overrides_.end()) { + std::pair status = itr->second; + return status.second; + } + return default_.second; +} + +void t_allow_unrelated_clustering::set_block_status(std::string block_type_name, std::pair status) { + overrides_[block_type_name] = status; +} +void t_allow_unrelated_clustering::set_default_status(std::pair status) { + default_ = status; +} + + t_pack_high_fanout_thresholds::t_pack_high_fanout_thresholds(int threshold) : default_(threshold) {} diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 7dee95fd2ea..5c54d0d5cc8 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -133,12 +133,17 @@ enum class e_const_gen_inference { COMB_SEQ /// overrides_; }; +class t_allow_unrelated_clustering { + public: + t_allow_unrelated_clustering() = default; + t_allow_unrelated_clustering(enum e_unrel_clust_stat status, enum e_unrel_clust_mode mode); + /** + * @brief Returns the unrelated clustering status for the specified block type + */ + enum e_unrel_clust_stat get_block_status(std::string block_type_name) const; + /** + * @brief Returns the unrelated clustering mode for the specified block type + */ + enum e_unrel_clust_mode get_block_mode(std::string block_type_name) const; + + public: + /** + * @brief Sets the unrelated clustering status for the specified block type + * + * The unrelated clustering status is represented as a pair of booleans. + * The first boolean incidcates whether unrelated clustering is turned on or off. + * The second variable indicates whether the status of the variable is provided + * by the user(bool = false) or user let it to be automatically determined by VPR(bool = ture). + * If provided by the user, the status cannot be overriden later, otherwise + * it can be adjusted by VPR throughout the flow as necessary. + */ + void set_block_status(std::string block_type_name, std::pair status); + /** + * @brief Sets the default value for unrelated clustering status + * + */ + void set_default_status(std::pair status); + + private: + std::pair default_; + std::map> overrides_; +}; + class t_pack_high_fanout_thresholds { public: t_pack_high_fanout_thresholds() = default; @@ -840,7 +881,7 @@ struct t_packer_opts { float inter_cluster_net_delay; float target_device_utilization; bool auto_compute_inter_cluster_net_delay; - e_unrelated_clustering allow_unrelated_clustering; + std::vector allow_unrelated_clustering; bool connection_driven; int pack_verbosity; bool enable_pin_feasibility_filter; diff --git a/vpr/src/pack/cluster.cpp b/vpr/src/pack/cluster.cpp index 4f1382a990d..fbe23ccfb30 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -91,7 +91,7 @@ std::map do_clustering(const t_packer_opts& pa int num_models, const std::unordered_set& is_clock, const std::unordered_map& expected_lowest_cost_pb_gnode, - bool allow_unrelated_clustering, + t_allow_unrelated_clustering allow_unrelated_clustering, bool balance_block_type_utilization, std::vector* lb_type_rr_graphs, const t_ext_pin_util_targets& ext_pin_util_targets, @@ -300,11 +300,16 @@ std::map do_clustering(const t_packer_opts& pa /*it doesn't make sense to do a timing analysis here since there* *is only one atom block clustered it would not change anything */ } + bool allow_unrel_clust_cur_blk = false; + if (allow_unrelated_clustering.get_block_status(cluster_ctx.clb_nlist.block_type(clb_index)->name) == e_unrel_clust_stat::ON) { + allow_unrel_clust_cur_blk = true; + } + cur_cluster_placement_stats_ptr = &(helper_ctx.cluster_placement_stats[cluster_ctx.clb_nlist.block_type(clb_index)->index]); cluster_stats.num_unrelated_clustering_attempts = 0; next_molecule = get_molecule_for_cluster(cluster_ctx.clb_nlist.block_pb(clb_index), attraction_groups, - allow_unrelated_clustering, + allow_unrel_clust_cur_blk, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, packer_opts.feasible_block_array_size, @@ -351,7 +356,7 @@ std::map do_clustering(const t_packer_opts& pa detailed_routing_stage, attraction_groups, clb_inter_blk_nets, - allow_unrelated_clustering, + allow_unrel_clust_cur_blk, high_fanout_threshold, is_clock, timing_info, diff --git a/vpr/src/pack/cluster.h b/vpr/src/pack/cluster.h index a9f2c1df689..f542f7c3753 100644 --- a/vpr/src/pack/cluster.h +++ b/vpr/src/pack/cluster.h @@ -18,7 +18,7 @@ std::map do_clustering(const t_packer_opts& pa int num_models, const std::unordered_set& is_clock, const std::unordered_map& expected_lowest_cost_pb_gnode, - bool allow_unrelated_clustering, + t_allow_unrelated_clustering allow_unrelated_clustering, bool balance_block_type_utilization, std::vector* lb_type_rr_graphs, const t_ext_pin_util_targets& ext_pin_util_targets, diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index a1868c80778..d1138becc83 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -27,11 +27,15 @@ /* #define DUMP_PB_GRAPH 1 */ /* #define DUMP_BLIF_INPUT 1 */ -static bool try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name); +static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name); static t_ext_pin_util_targets parse_target_external_pin_util(std::vector specs); static std::string target_external_pin_util_to_string(const t_ext_pin_util_targets& ext_pin_utils); +static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs); +std::pair parse_unrel_clust_from_str(std::string str); +static bool block_type_found(std::string block_type_name); + static t_pack_high_fanout_thresholds parse_high_fanout_thresholds(std::vector specs); static std::string high_fanout_thresholds_to_string(const t_pack_high_fanout_thresholds& hf_thresholds); @@ -119,12 +123,8 @@ bool try_pack(t_packer_opts* packer_opts, VTR_LOG("Packing with pin utilization targets: %s\n", target_external_pin_util_to_string(helper_ctx.target_external_pin_util).c_str()); VTR_LOG("Packing with high fanout thresholds: %s\n", high_fanout_thresholds_to_string(high_fanout_thresholds).c_str()); - bool allow_unrelated_clustering = false; - if (packer_opts->allow_unrelated_clustering == e_unrelated_clustering::ON) { - allow_unrelated_clustering = true; - } else if (packer_opts->allow_unrelated_clustering == e_unrelated_clustering::OFF) { - allow_unrelated_clustering = false; - } + t_allow_unrelated_clustering allow_unrelated_clustering = parse_unrelated_clustering_stat(packer_opts->allow_unrelated_clustering); + bool balance_block_type_util = false; if (packer_opts->balance_block_type_utilization == e_balance_block_type_util::ON) { @@ -156,7 +156,7 @@ bool try_pack(t_packer_opts* packer_opts, clustering_data); //Try to size/find a device - bool fits_on_device = try_size_device_grid(*arch, helper_ctx.num_used_type_instances, packer_opts->target_device_utilization, packer_opts->device_layout); + std::vector overused_blocks = try_size_device_grid(*arch, helper_ctx.num_used_type_instances, packer_opts->target_device_utilization, packer_opts->device_layout); /* We use this bool to determine the cause for the clustering not being dense enough. If the clustering * is not dense enough and there are floorplan constraints, it is presumed that the constraints are the cause @@ -164,22 +164,38 @@ bool try_pack(t_packer_opts* packer_opts, */ bool floorplan_not_fitting = (floorplan_regions_overfull || g_vpr_ctx.mutable_floorplanning().constraints.get_num_partitions() > 0); - if (fits_on_device && !floorplan_regions_overfull) { + if (overused_blocks.empty() && !floorplan_regions_overfull) { break; //Done } else if (pack_iteration == 1 && !floorplan_not_fitting) { //1st pack attempt was unsucessful (i.e. not dense enough) and we have control of unrelated clustering // //Turn it on to increase packing density - if (packer_opts->allow_unrelated_clustering == e_unrelated_clustering::AUTO) { - VTR_ASSERT(allow_unrelated_clustering == false); - allow_unrelated_clustering = true; + std::vector fixed_blocks; + for(auto& overused_block : overused_blocks) { + e_unrel_clust_mode block_mode = allow_unrelated_clustering.get_block_mode(overused_block); + if(block_mode == e_unrel_clust_mode::FIXED){ + // The user has explicitly set unrelated clustering status for this block type + // so we can't change it + fixed_blocks.push_back(overused_block); + } + else{ + allow_unrelated_clustering.set_block_status(overused_block, std::make_pair(e_unrel_clust_stat::ON, block_mode)); + } } if (packer_opts->balance_block_type_utilization == e_balance_block_type_util::AUTO) { VTR_ASSERT(balance_block_type_util == false); balance_block_type_util = true; } - VTR_LOG("Packing failed to fit on device. Re-packing with: unrelated_logic_clustering=%s balance_block_type_util=%s\n", - (allow_unrelated_clustering ? "true" : "false"), + + if(fixed_blocks.size() > 0){ + std::stringstream msg; + msg << "Packing failed to fit on device.\n" + << "The following block types were overused, but unrelated clustering was disabled for them:\n" + << vtr::join(fixed_blocks, ",").c_str() << "\n"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + VTR_LOG("Packing failed to fit on device. Re-packing with: unrelated_logic_clustering=true for block types=[%s] balance_block_type_util=%s\n", + vtr::join(overused_blocks, ",").c_str(), (balance_block_type_util ? "true" : "false")); /* * When running with tight floorplan constraints, some regions may become overfull with clusters (i.e. @@ -342,7 +358,7 @@ std::unordered_set alloc_and_load_is_clock(bool global_clocks) { return (is_clock); } -static bool try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name) { +static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name) { auto& device_ctx = g_vpr_ctx.mutable_device(); //Build the device @@ -352,8 +368,7 @@ static bool try_size_device_grid(const t_arch& arch, const std::map overused_block_types; float device_utilization = calculate_device_utilization(grid, num_type_instances); VTR_LOG("Device Utilization: %.2f (target %.2f)\n", device_utilization, target_device_utilization); @@ -378,13 +393,103 @@ static bool try_size_device_grid(const t_arch& arch, const std::map 1.) { - fits_on_device = false; + std::string block_name(type.name); + overused_block_types.push_back(block_name); } VTR_LOG("\tBlock Utilization: %.2f Type: %s\n", util, type.name); } VTR_LOG("\n"); + return overused_block_types; +} + +std::pair parse_unrel_clust_from_str(std::string str) { + std::pair conv_value; + if (str == "on"){ + conv_value.first = e_unrel_clust_stat::ON; + conv_value.second = e_unrel_clust_mode::FIXED; + } + else if (str == "off"){ + conv_value.first = e_unrel_clust_stat::OFF; + conv_value.second = e_unrel_clust_mode::FIXED; + } + else if (str == "auto"){ + conv_value.first = e_unrel_clust_stat::OFF; + conv_value.second = e_unrel_clust_mode::AUTO; + } + else { + std::stringstream msg; + msg << "Invalid conversion from '" + << str + << "' to e_unrel_clust_stat (expected one of: " + << "on, off, auto" << ")"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + return conv_value; +} +static bool block_type_found(std::string block_type_name) { + const DeviceContext& device_ctx = g_vpr_ctx.device(); + auto logical_block_types = device_ctx.logical_block_types; + + for(auto block_type : logical_block_types) { + if (strcmp(block_type.name, block_type_name.c_str()) == 0) { + return true; + } + } + return false; +} + +static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs) { + // If no options is specified by the user, unrelated clustering is turned off at first and the mode is set to auto + t_allow_unrelated_clustering urel_clust_stat(e_unrel_clust_stat::OFF,e_unrel_clust_mode::AUTO); + + bool default_set = false; + std::set seen_block_types; + + for (auto spec : specs) { + auto block_value = vtr::split(spec, ":"); + + std::string block_type; + std::pair block_status; + if (block_value.size() == 2) { + block_type = block_value[0]; + block_status = parse_unrel_clust_from_str(block_value[1]); + } else if (block_value.size() == 1) { + block_status = parse_unrel_clust_from_str(block_value[0]); + } else { + std::stringstream msg; + msg << "Invalid unrelated clustering status specification '" << spec << "' (expected at most one ':' between block name and values"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + + + if (block_type.empty()) { + //Default value + if (default_set) { + std::stringstream msg; + msg << "Only one default unrelated clustering status should be specified"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + urel_clust_stat.set_default_status(block_status); + default_set = true; + } + else if(!block_type_found(block_type)){ + std::stringstream msg; + msg << "Block type '" << block_type << "' not found"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + else { + if (seen_block_types.count(block_type)) { + std::stringstream msg; + msg << "Only one unrelated clustering status should be specified for block type '" << block_type << "'"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + + urel_clust_stat.set_block_status(block_type, block_status); + seen_block_types.insert(block_type); + } + } - return fits_on_device; + return urel_clust_stat; } static t_ext_pin_util_targets parse_target_external_pin_util(std::vector specs) { From 6034bf60d6794089c3eeb76a13c4adad75cd3867 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Thu, 2 Feb 2023 15:01:22 -0500 Subject: [PATCH 2/8] make format --- vpr/src/base/read_options.cpp | 2 +- vpr/src/base/vpr_types.cpp | 5 ++--- vpr/src/base/vpr_types.h | 3 +-- vpr/src/pack/pack.cpp | 35 ++++++++++++++--------------------- 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 2754b384757..94dda4edb04 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1605,7 +1605,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg "would turn on unrelated clustering for io blocks and\n" "dynamically determine enable/disable unrelated clustering,\n" "for all all other blocks.\n") - + .nargs('+') .default_value({"auto"}) .show_in(argparse::ShowIn::HELP_ONLY); diff --git a/vpr/src/base/vpr_types.cpp b/vpr/src/base/vpr_types.cpp index d8d59a4dd28..e0bc1d6944d 100644 --- a/vpr/src/base/vpr_types.cpp +++ b/vpr/src/base/vpr_types.cpp @@ -27,7 +27,7 @@ t_allow_unrelated_clustering::t_allow_unrelated_clustering(enum e_unrel_clust_st default_.first = default_stat; default_.second = default_mode; } -enum e_unrel_clust_stat t_allow_unrelated_clustering::get_block_status(std::string block_type_name) const{ +enum e_unrel_clust_stat t_allow_unrelated_clustering::get_block_status(std::string block_type_name) const { auto itr = overrides_.find(block_type_name); if (itr != overrides_.end()) { std::pair status = itr->second; @@ -36,7 +36,7 @@ enum e_unrel_clust_stat t_allow_unrelated_clustering::get_block_status(std::stri return default_.first; } -enum e_unrel_clust_mode t_allow_unrelated_clustering::get_block_mode(std::string block_type_name) const{ +enum e_unrel_clust_mode t_allow_unrelated_clustering::get_block_mode(std::string block_type_name) const { auto itr = overrides_.find(block_type_name); if (itr != overrides_.end()) { std::pair status = itr->second; @@ -52,7 +52,6 @@ void t_allow_unrelated_clustering::set_default_status(std::pairallow_unrelated_clustering); - bool balance_block_type_util = false; if (packer_opts->balance_block_type_utilization == e_balance_block_type_util::ON) { balance_block_type_util = true; @@ -171,14 +170,13 @@ bool try_pack(t_packer_opts* packer_opts, // //Turn it on to increase packing density std::vector fixed_blocks; - for(auto& overused_block : overused_blocks) { + for (auto& overused_block : overused_blocks) { e_unrel_clust_mode block_mode = allow_unrelated_clustering.get_block_mode(overused_block); - if(block_mode == e_unrel_clust_mode::FIXED){ + if (block_mode == e_unrel_clust_mode::FIXED) { // The user has explicitly set unrelated clustering status for this block type // so we can't change it fixed_blocks.push_back(overused_block); - } - else{ + } else { allow_unrelated_clustering.set_block_status(overused_block, std::make_pair(e_unrel_clust_stat::ON, block_mode)); } } @@ -187,7 +185,7 @@ bool try_pack(t_packer_opts* packer_opts, balance_block_type_util = true; } - if(fixed_blocks.size() > 0){ + if (fixed_blocks.size() > 0) { std::stringstream msg; msg << "Packing failed to fit on device.\n" << "The following block types were overused, but unrelated clustering was disabled for them:\n" @@ -404,24 +402,22 @@ static std::vector try_size_device_grid(const t_arch& arch, const s std::pair parse_unrel_clust_from_str(std::string str) { std::pair conv_value; - if (str == "on"){ + if (str == "on") { conv_value.first = e_unrel_clust_stat::ON; conv_value.second = e_unrel_clust_mode::FIXED; - } - else if (str == "off"){ + } else if (str == "off") { conv_value.first = e_unrel_clust_stat::OFF; conv_value.second = e_unrel_clust_mode::FIXED; - } - else if (str == "auto"){ + } else if (str == "auto") { conv_value.first = e_unrel_clust_stat::OFF; conv_value.second = e_unrel_clust_mode::AUTO; - } - else { + } else { std::stringstream msg; msg << "Invalid conversion from '" << str << "' to e_unrel_clust_stat (expected one of: " - << "on, off, auto" << ")"; + << "on, off, auto" + << ")"; VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); } return conv_value; @@ -430,7 +426,7 @@ static bool block_type_found(std::string block_type_name) { const DeviceContext& device_ctx = g_vpr_ctx.device(); auto logical_block_types = device_ctx.logical_block_types; - for(auto block_type : logical_block_types) { + for (auto block_type : logical_block_types) { if (strcmp(block_type.name, block_type_name.c_str()) == 0) { return true; } @@ -440,7 +436,7 @@ static bool block_type_found(std::string block_type_name) { static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs) { // If no options is specified by the user, unrelated clustering is turned off at first and the mode is set to auto - t_allow_unrelated_clustering urel_clust_stat(e_unrel_clust_stat::OFF,e_unrel_clust_mode::AUTO); + t_allow_unrelated_clustering urel_clust_stat(e_unrel_clust_stat::OFF, e_unrel_clust_mode::AUTO); bool default_set = false; std::set seen_block_types; @@ -461,7 +457,6 @@ static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector< VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); } - if (block_type.empty()) { //Default value if (default_set) { @@ -471,13 +466,11 @@ static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector< } urel_clust_stat.set_default_status(block_status); default_set = true; - } - else if(!block_type_found(block_type)){ + } else if (!block_type_found(block_type)) { std::stringstream msg; msg << "Block type '" << block_type << "' not found"; VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); - } - else { + } else { if (seen_block_types.count(block_type)) { std::stringstream msg; msg << "Only one unrelated clustering status should be specified for block type '" << block_type << "'"; From 919f1df871e94116a29a5b8933bd98ac0d83ea94 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Fri, 3 Feb 2023 16:16:43 -0500 Subject: [PATCH 3/8] Updating the documentation --- doc/src/vpr/command_line_usage.rst | 18 ++++++++++++++++-- vpr/src/base/read_options.cpp | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/doc/src/vpr/command_line_usage.rst b/doc/src/vpr/command_line_usage.rst index f589969d8ef..7a48066f6df 100644 --- a/doc/src/vpr/command_line_usage.rst +++ b/doc/src/vpr/command_line_usage.rst @@ -471,16 +471,30 @@ For people not working on CAD, you can probably leave all the options to their d **Default**: ``on`` -.. option:: --allow_unrelated_clustering {on | off | auto} +.. option:: --allow_unrelated_clustering {on | off | auto | :{on|off|auto}} Controls whether primitives with no attraction to a cluster may be packed into it. Unrelated clustering can increase packing density (decreasing the number of blocks required to implement the circuit), but can significantly impact routability. + + * ``auto`` Dynamically enabled/disabled (based on density). + + * ``on`` Unrelated clustering enabled. + + * ``off`` Unrelated clustering disabled. - When set to ``auto`` VPR automatically decides whether to enable unrelated clustring based on the targetted device and achieved packing density. + * ``:{on|off|auto}`` Specify the unrelated clustering status for a specific block type. **Default**: ``auto`` + This option can also take multiple space-separated values. + + For example:: + + --allow_unrelated_clustering auto io:on + + would turn on unrelated clustering for io blocks and dynamically determine enable/disable unrelated clustering for all other blocks. + .. option:: --alpha_clustering A parameter that weights the optimization of timing vs area. diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 94dda4edb04..7b4e26b8fd6 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1604,7 +1604,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg " '--allow_unrelated_clustering auto io:on'\n" "would turn on unrelated clustering for io blocks and\n" "dynamically determine enable/disable unrelated clustering,\n" - "for all all other blocks.\n") + "for all other blocks.\n") .nargs('+') .default_value({"auto"}) From 55c929be4c8a03c6d176a969fc9e6e42cbac7d30 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Fri, 10 Feb 2023 19:15:20 -0500 Subject: [PATCH 4/8] Add more comments --- vpr/src/base/vpr_types.h | 27 +++++++++++++++++++-------- vpr/src/pack/pack.cpp | 8 +++++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 700727afcbb..0939a53baeb 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -134,8 +134,8 @@ enum class e_const_gen_inference { }; enum class e_unrel_clust_stat { - OFF, - ON + OFF, /// status); /** @@ -244,7 +247,15 @@ class t_allow_unrelated_clustering { void set_default_status(std::pair status); private: + /** + * @brief The default value of unrelated clustering status for all block types + */ std::pair default_; + /** + * @brief Overrides the default value of unrelated clustering status for specific block types. Each entry + * is associated with a certain block type and determines whether unrelated cluster is on or off, + * and whether its status is set by the user or automatically determined by VPR. + */ std::map> overrides_; }; diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index 3575e515ce0..e6312948b9f 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -32,6 +32,7 @@ static std::vector try_size_device_grid(const t_arch& arch, const s static t_ext_pin_util_targets parse_target_external_pin_util(std::vector specs); static std::string target_external_pin_util_to_string(const t_ext_pin_util_targets& ext_pin_utils); +/* parse_unrelated_clustering_stat parses the status of unrelated clustering from a list of specifications provided as an input. */ static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs); std::pair parse_unrel_clust_from_str(std::string str); static bool block_type_found(std::string block_type_name); @@ -188,7 +189,7 @@ bool try_pack(t_packer_opts* packer_opts, if (fixed_blocks.size() > 0) { std::stringstream msg; msg << "Packing failed to fit on device.\n" - << "The following block types were overused, but unrelated clustering was disabled for them:\n" + << "The following block types were overused, but unrelated clustering cannot be changed for them:\n" << vtr::join(fixed_blocks, ",").c_str() << "\n"; VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); } @@ -357,6 +358,11 @@ std::unordered_set alloc_and_load_is_clock(bool global_clocks) { } static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name) { + /* Checks whether the packed circuit can fit on the target device + num_type_instances: lists the number of used blocks for each pb_type */ + + /* The function returns a list of block types that were overutilized. + Therefore, if the design fits on the device the returning list will be empty */ auto& device_ctx = g_vpr_ctx.mutable_device(); //Build the device From a29adb24b8cd9b3e9733d8e8339d86ed251846c3 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Fri, 10 Feb 2023 23:46:20 -0500 Subject: [PATCH 5/8] Refactor the try_pack function --- vpr/src/pack/pack.cpp | 241 ++++++++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 100 deletions(-) diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index e6312948b9f..8011f29c498 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -27,6 +27,7 @@ /* #define DUMP_PB_GRAPH 1 */ /* #define DUMP_BLIF_INPUT 1 */ +/* Checks whether the packed circuit can fit on the target device */ static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name); static t_ext_pin_util_targets parse_target_external_pin_util(std::vector specs); @@ -40,6 +41,14 @@ static bool block_type_found(std::string block_type_name); static t_pack_high_fanout_thresholds parse_high_fanout_thresholds(std::vector specs); static std::string high_fanout_thresholds_to_string(const t_pack_high_fanout_thresholds& hf_thresholds); +bool determine_packing_status(int pack_iteration, + t_packer_opts* packer_opts, + bool floorplan_regions_overfull, + std::vector overused_blocks, + t_allow_unrelated_clustering& allow_unrelated_clustering, + bool& balance_block_type_util, + AttractionInfo& attraction_groups); + bool try_pack(t_packer_opts* packer_opts, const t_analysis_opts* analysis_opts, const t_arch* arch, @@ -158,106 +167,17 @@ bool try_pack(t_packer_opts* packer_opts, //Try to size/find a device std::vector overused_blocks = try_size_device_grid(*arch, helper_ctx.num_used_type_instances, packer_opts->target_device_utilization, packer_opts->device_layout); - /* We use this bool to determine the cause for the clustering not being dense enough. If the clustering - * is not dense enough and there are floorplan constraints, it is presumed that the constraints are the cause - * of the floorplan not fitting, so attraction groups are turned on for later iterations. - */ - bool floorplan_not_fitting = (floorplan_regions_overfull || g_vpr_ctx.mutable_floorplanning().constraints.get_num_partitions() > 0); - - if (overused_blocks.empty() && !floorplan_regions_overfull) { - break; //Done - } else if (pack_iteration == 1 && !floorplan_not_fitting) { - //1st pack attempt was unsucessful (i.e. not dense enough) and we have control of unrelated clustering - // - //Turn it on to increase packing density - std::vector fixed_blocks; - for (auto& overused_block : overused_blocks) { - e_unrel_clust_mode block_mode = allow_unrelated_clustering.get_block_mode(overused_block); - if (block_mode == e_unrel_clust_mode::FIXED) { - // The user has explicitly set unrelated clustering status for this block type - // so we can't change it - fixed_blocks.push_back(overused_block); - } else { - allow_unrelated_clustering.set_block_status(overused_block, std::make_pair(e_unrel_clust_stat::ON, block_mode)); - } - } - if (packer_opts->balance_block_type_utilization == e_balance_block_type_util::AUTO) { - VTR_ASSERT(balance_block_type_util == false); - balance_block_type_util = true; - } - - if (fixed_blocks.size() > 0) { - std::stringstream msg; - msg << "Packing failed to fit on device.\n" - << "The following block types were overused, but unrelated clustering cannot be changed for them:\n" - << vtr::join(fixed_blocks, ",").c_str() << "\n"; - VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); - } - VTR_LOG("Packing failed to fit on device. Re-packing with: unrelated_logic_clustering=true for block types=[%s] balance_block_type_util=%s\n", - vtr::join(overused_blocks, ",").c_str(), - (balance_block_type_util ? "true" : "false")); - /* - * When running with tight floorplan constraints, some regions may become overfull with clusters (i.e. - * the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we - * cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more - * densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end - * of every iteration if any floorplan regions are overfull. In the first iteration, we run - * with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration, - * we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way - * until the last iteration, when we create attraction groups for every partition, if needed. - */ - } else if (pack_iteration == 1 && floorplan_not_fitting) { - VTR_LOG("Floorplan regions are overfull: trying to pack again using cluster attraction groups. \n"); - attraction_groups.create_att_groups_for_overfull_regions(); - attraction_groups.set_att_group_pulls(1); - - } else if (pack_iteration >= 2 && pack_iteration < 5 && floorplan_not_fitting) { - if (pack_iteration == 2) { - VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n"); - attraction_groups.create_att_groups_for_overfull_regions(); - VTR_LOG("Pack iteration is %d\n", pack_iteration); - } else if (pack_iteration == 3) { - attraction_groups.create_att_groups_for_all_regions(); - VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n"); - VTR_LOG("Pack iteration is %d\n", pack_iteration); - } else if (pack_iteration == 4) { - attraction_groups.create_att_groups_for_all_regions(); - VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration and higher target pin utilization. \n"); - VTR_LOG("Pack iteration is %d\n", pack_iteration); - attraction_groups.set_att_group_pulls(4); - t_ext_pin_util pin_util(1.0, 1.0); - helper_ctx.target_external_pin_util.set_block_pin_util("clb", pin_util); - } - - } else { - //Unable to pack densely enough: Give Up - - if (floorplan_regions_overfull) { - VPR_FATAL_ERROR(VPR_ERROR_OTHER, - "Failed to find pack clusters densely enough to fit in the designated floorplan regions.\n" - "The floorplan regions may need to be expanded to run successfully. \n"); - } - - //No suitable device found - std::string resource_reqs; - std::string resource_avail; - auto& grid = g_vpr_ctx.device().grid; - for (auto iter = helper_ctx.num_used_type_instances.begin(); iter != helper_ctx.num_used_type_instances.end(); ++iter) { - if (iter != helper_ctx.num_used_type_instances.begin()) { - resource_reqs += ", "; - resource_avail += ", "; - } - - resource_reqs += std::string(iter->first->name) + ": " + std::to_string(iter->second); - - int num_instances = 0; - for (auto type : iter->first->equivalent_tiles) - num_instances += grid.num_instances(type); - - resource_avail += std::string(iter->first->name) + ": " + std::to_string(num_instances); - } - - VPR_FATAL_ERROR(VPR_ERROR_OTHER, "Failed to find device which satisifies resource requirements required: %s (available %s)", resource_reqs.c_str(), resource_avail.c_str()); + bool packing_done = determine_packing_status(pack_iteration, + packer_opts, + floorplan_regions_overfull, + overused_blocks, + allow_unrelated_clustering, + balance_block_type_util, + attraction_groups); + + if(packing_done) + { + break; } //Reset clustering for re-packing @@ -357,6 +277,127 @@ std::unordered_set alloc_and_load_is_clock(bool global_clocks) { return (is_clock); } + +/* This function determines whether packing is done or not. If returned true, the packer will exit. + If packing fails it will print out a message explaining the cause of failure and and take the appropriate action to try to resolve it. + If no further action can be taken in case of failure, this function will throw an error*/ +bool determine_packing_status(int pack_iteration, + t_packer_opts* packer_opts, + bool floorplan_regions_overfull, + std::vector overused_blocks, + t_allow_unrelated_clustering& allow_unrelated_clustering, + bool& balance_block_type_util, + AttractionInfo& attraction_groups){ + + auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); + + /* We use this bool to determine the cause for the clustering not being dense enough. If the clustering + * is not dense enough and there are floorplan constraints, it is presumed that the constraints are the cause + * of the floorplan not fitting, so attraction groups are turned on for later iterations. + */ + bool floorplan_not_fitting = (floorplan_regions_overfull || g_vpr_ctx.mutable_floorplanning().constraints.get_num_partitions() > 0); + + if (overused_blocks.empty() && !floorplan_regions_overfull) { + return true; //Done + } else if (pack_iteration == 1 && !floorplan_not_fitting) { + //1st pack attempt was unsucessful (i.e. not dense enough) and we have control of unrelated clustering + // + //Turn it on to increase packing density + std::vector fixed_blocks; + for (auto& overused_block : overused_blocks) { + e_unrel_clust_mode block_mode = allow_unrelated_clustering.get_block_mode(overused_block); + if (block_mode == e_unrel_clust_mode::FIXED) { + // The user has explicitly set unrelated clustering status for this block type + // so we can't change it + fixed_blocks.push_back(overused_block); + } else { + allow_unrelated_clustering.set_block_status(overused_block, std::make_pair(e_unrel_clust_stat::ON, block_mode)); + } + } + if (packer_opts->balance_block_type_utilization == e_balance_block_type_util::AUTO) { + VTR_ASSERT(balance_block_type_util == false); + balance_block_type_util = true; + } + + if (fixed_blocks.size() > 0) { + std::stringstream msg; + msg << "Packing failed to fit on device.\n" + << "The following block types were overused, but unrelated clustering cannot be changed for them:\n" + << vtr::join(fixed_blocks, ",").c_str() << "\n"; + VPR_FATAL_ERROR(VPR_ERROR_PACK, msg.str().c_str()); + } + VTR_LOG("Packing failed to fit on device. Re-packing with: unrelated_logic_clustering=true for block types=[%s] balance_block_type_util=%s\n", + vtr::join(overused_blocks, ",").c_str(), + (balance_block_type_util ? "true" : "false")); + /* + * When running with tight floorplan constraints, some regions may become overfull with clusters (i.e. + * the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we + * cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more + * densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end + * of every iteration if any floorplan regions are overfull. In the first iteration, we run + * with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration, + * we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way + * until the last iteration, when we create attraction groups for every partition, if needed. + */ + } else if (pack_iteration == 1 && floorplan_not_fitting) { + VTR_LOG("Floorplan regions are overfull: trying to pack again using cluster attraction groups. \n"); + attraction_groups.create_att_groups_for_overfull_regions(); + attraction_groups.set_att_group_pulls(1); + + } else if (pack_iteration >= 2 && pack_iteration < 5 && floorplan_not_fitting) { + if (pack_iteration == 2) { + VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n"); + attraction_groups.create_att_groups_for_overfull_regions(); + VTR_LOG("Pack iteration is %d\n", pack_iteration); + } else if (pack_iteration == 3) { + attraction_groups.create_att_groups_for_all_regions(); + VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration. \n"); + VTR_LOG("Pack iteration is %d\n", pack_iteration); + } else if (pack_iteration == 4) { + attraction_groups.create_att_groups_for_all_regions(); + VTR_LOG("Floorplan regions are overfull: trying to pack again with more attraction groups exploration and higher target pin utilization. \n"); + VTR_LOG("Pack iteration is %d\n", pack_iteration); + attraction_groups.set_att_group_pulls(4); + t_ext_pin_util pin_util(1.0, 1.0); + helper_ctx.target_external_pin_util.set_block_pin_util("clb", pin_util); + } + + } else { + //Unable to pack densely enough: Give Up + + if (floorplan_regions_overfull) { + VPR_FATAL_ERROR(VPR_ERROR_OTHER, + "Failed to find pack clusters densely enough to fit in the designated floorplan regions.\n" + "The floorplan regions may need to be expanded to run successfully. \n"); + } + + //No suitable device found + std::string resource_reqs; + std::string resource_avail; + auto& grid = g_vpr_ctx.device().grid; + for (auto iter = helper_ctx.num_used_type_instances.begin(); iter != helper_ctx.num_used_type_instances.end(); ++iter) { + if (iter != helper_ctx.num_used_type_instances.begin()) { + resource_reqs += ", "; + resource_avail += ", "; + } + + resource_reqs += std::string(iter->first->name) + ": " + std::to_string(iter->second); + + int num_instances = 0; + for (auto type : iter->first->equivalent_tiles) + num_instances += grid.num_instances(type); + + resource_avail += std::string(iter->first->name) + ": " + std::to_string(num_instances); + } + + VPR_FATAL_ERROR(VPR_ERROR_OTHER, "Failed to find device which satisifies resource requirements required: %s (available %s)", resource_reqs.c_str(), resource_avail.c_str()); + } + + return false; + +} + + static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name) { /* Checks whether the packed circuit can fit on the target device num_type_instances: lists the number of used blocks for each pb_type */ From e3893a531b9a70794cc6714da41fb7c276493ed8 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Fri, 10 Feb 2023 23:46:43 -0500 Subject: [PATCH 6/8] Add comments --- vpr/src/pack/pack.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index 8011f29c498..ab0fb1788bc 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -36,6 +36,7 @@ static std::string target_external_pin_util_to_string(const t_ext_pin_util_targe /* parse_unrelated_clustering_stat parses the status of unrelated clustering from a list of specifications provided as an input. */ static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs); std::pair parse_unrel_clust_from_str(std::string str); +/* */ static bool block_type_found(std::string block_type_name); static t_pack_high_fanout_thresholds parse_high_fanout_thresholds(std::vector specs); @@ -469,7 +470,11 @@ std::pair parse_unrel_clust_fr } return conv_value; } + + static bool block_type_found(std::string block_type_name) { + /*The function takes as input the name of a block type and + checks if it exists in the list of logical block types in the device context.*/ const DeviceContext& device_ctx = g_vpr_ctx.device(); auto logical_block_types = device_ctx.logical_block_types; From 91884fef463bebf549b46eefc0a282a5f164ec69 Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Fri, 10 Feb 2023 23:48:41 -0500 Subject: [PATCH 7/8] Add comments --- vpr/src/pack/pack.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index ab0fb1788bc..c6b957002ab 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -36,7 +36,7 @@ static std::string target_external_pin_util_to_string(const t_ext_pin_util_targe /* parse_unrelated_clustering_stat parses the status of unrelated clustering from a list of specifications provided as an input. */ static t_allow_unrelated_clustering parse_unrelated_clustering_stat(std::vector specs); std::pair parse_unrel_clust_from_str(std::string str); -/* */ +/* The function checks if a given block type exists in the list of logical block types in the device context. */ static bool block_type_found(std::string block_type_name); static t_pack_high_fanout_thresholds parse_high_fanout_thresholds(std::vector specs); @@ -473,8 +473,8 @@ std::pair parse_unrel_clust_fr static bool block_type_found(std::string block_type_name) { - /*The function takes as input the name of a block type and - checks if it exists in the list of logical block types in the device context.*/ + /* The function takes as input the name of a block type and + checks if it exists in the list of logical block types in the device context. */ const DeviceContext& device_ctx = g_vpr_ctx.device(); auto logical_block_types = device_ctx.logical_block_types; From 7500fcd9afc6f56661d6f68a28005faa93f22dbe Mon Sep 17 00:00:00 2001 From: kimiatkh Date: Sat, 11 Feb 2023 11:47:04 -0500 Subject: [PATCH 8/8] make foramt --- vpr/src/base/vpr_types.h | 6 ++-- vpr/src/pack/pack.cpp | 78 +++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 0939a53baeb..d97d2bcbbf9 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -134,8 +134,8 @@ enum class e_const_gen_inference { }; enum class e_unrel_clust_stat { - OFF, /// default_; - /** + /** * @brief Overrides the default value of unrelated clustering status for specific block types. Each entry * is associated with a certain block type and determines whether unrelated cluster is on or off, * and whether its status is set by the user or automatically determined by VPR. diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index c6b957002ab..44eaf3ddff6 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -42,12 +42,12 @@ static bool block_type_found(std::string block_type_name); static t_pack_high_fanout_thresholds parse_high_fanout_thresholds(std::vector specs); static std::string high_fanout_thresholds_to_string(const t_pack_high_fanout_thresholds& hf_thresholds); -bool determine_packing_status(int pack_iteration, +bool determine_packing_status(int pack_iteration, t_packer_opts* packer_opts, - bool floorplan_regions_overfull, - std::vector overused_blocks, - t_allow_unrelated_clustering& allow_unrelated_clustering, - bool& balance_block_type_util, + bool floorplan_regions_overfull, + std::vector overused_blocks, + t_allow_unrelated_clustering& allow_unrelated_clustering, + bool& balance_block_type_util, AttractionInfo& attraction_groups); bool try_pack(t_packer_opts* packer_opts, @@ -168,16 +168,15 @@ bool try_pack(t_packer_opts* packer_opts, //Try to size/find a device std::vector overused_blocks = try_size_device_grid(*arch, helper_ctx.num_used_type_instances, packer_opts->target_device_utilization, packer_opts->device_layout); - bool packing_done = determine_packing_status(pack_iteration, - packer_opts, - floorplan_regions_overfull, - overused_blocks, - allow_unrelated_clustering, - balance_block_type_util, - attraction_groups); + bool packing_done = determine_packing_status(pack_iteration, + packer_opts, + floorplan_regions_overfull, + overused_blocks, + allow_unrelated_clustering, + balance_block_type_util, + attraction_groups); - if(packing_done) - { + if (packing_done) { break; } @@ -278,24 +277,22 @@ std::unordered_set alloc_and_load_is_clock(bool global_clocks) { return (is_clock); } - /* This function determines whether packing is done or not. If returned true, the packer will exit. - If packing fails it will print out a message explaining the cause of failure and and take the appropriate action to try to resolve it. - If no further action can be taken in case of failure, this function will throw an error*/ -bool determine_packing_status(int pack_iteration, + * If packing fails it will print out a message explaining the cause of failure and and take the appropriate action to try to resolve it. + * If no further action can be taken in case of failure, this function will throw an error*/ +bool determine_packing_status(int pack_iteration, t_packer_opts* packer_opts, - bool floorplan_regions_overfull, - std::vector overused_blocks, - t_allow_unrelated_clustering& allow_unrelated_clustering, - bool& balance_block_type_util, - AttractionInfo& attraction_groups){ - + bool floorplan_regions_overfull, + std::vector overused_blocks, + t_allow_unrelated_clustering& allow_unrelated_clustering, + bool& balance_block_type_util, + AttractionInfo& attraction_groups) { auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); /* We use this bool to determine the cause for the clustering not being dense enough. If the clustering - * is not dense enough and there are floorplan constraints, it is presumed that the constraints are the cause - * of the floorplan not fitting, so attraction groups are turned on for later iterations. - */ + * is not dense enough and there are floorplan constraints, it is presumed that the constraints are the cause + * of the floorplan not fitting, so attraction groups are turned on for later iterations. + */ bool floorplan_not_fitting = (floorplan_regions_overfull || g_vpr_ctx.mutable_floorplanning().constraints.get_num_partitions() > 0); if (overused_blocks.empty() && !floorplan_regions_overfull) { @@ -331,15 +328,15 @@ bool determine_packing_status(int pack_iteration, vtr::join(overused_blocks, ",").c_str(), (balance_block_type_util ? "true" : "false")); /* - * When running with tight floorplan constraints, some regions may become overfull with clusters (i.e. - * the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we - * cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more - * densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end - * of every iteration if any floorplan regions are overfull. In the first iteration, we run - * with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration, - * we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way - * until the last iteration, when we create attraction groups for every partition, if needed. - */ + * When running with tight floorplan constraints, some regions may become overfull with clusters (i.e. + * the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we + * cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more + * densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end + * of every iteration if any floorplan regions are overfull. In the first iteration, we run + * with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration, + * we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way + * until the last iteration, when we create attraction groups for every partition, if needed. + */ } else if (pack_iteration == 1 && floorplan_not_fitting) { VTR_LOG("Floorplan regions are overfull: trying to pack again using cluster attraction groups. \n"); attraction_groups.create_att_groups_for_overfull_regions(); @@ -395,16 +392,14 @@ bool determine_packing_status(int pack_iteration, } return false; - } - static std::vector try_size_device_grid(const t_arch& arch, const std::map& num_type_instances, float target_device_utilization, std::string device_layout_name) { /* Checks whether the packed circuit can fit on the target device - num_type_instances: lists the number of used blocks for each pb_type */ + * num_type_instances: lists the number of used blocks for each pb_type */ /* The function returns a list of block types that were overutilized. - Therefore, if the design fits on the device the returning list will be empty */ + * Therefore, if the design fits on the device the returning list will be empty */ auto& device_ctx = g_vpr_ctx.mutable_device(); //Build the device @@ -471,10 +466,9 @@ std::pair parse_unrel_clust_fr return conv_value; } - static bool block_type_found(std::string block_type_name) { /* The function takes as input the name of a block type and - checks if it exists in the list of logical block types in the device context. */ + * checks if it exists in the list of logical block types in the device context. */ const DeviceContext& device_ctx = g_vpr_ctx.device(); auto logical_block_types = device_ctx.logical_block_types;