diff --git a/vpr/src/place/RL_agent_util.cpp b/vpr/src/place/RL_agent_util.cpp index c65cd4301e7..54ca3601545 100644 --- a/vpr/src/place/RL_agent_util.cpp +++ b/vpr/src/place/RL_agent_util.cpp @@ -7,6 +7,7 @@ std::pair, std::unique_ptr> create_move_generators(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, const t_placer_opts& placer_opts, int move_lim, double noc_attraction_weight, @@ -25,8 +26,8 @@ std::pair, std::unique_ptr> create move_name.c_str(), placer_opts.place_static_move_prob[move_type]); } - move_generators.first = std::make_unique(placer_state, place_macros, reward_fun, rng, placer_opts.place_static_move_prob); - move_generators.second = std::make_unique(placer_state, place_macros, reward_fun, rng, placer_opts.place_static_move_prob); + move_generators.first = std::make_unique(placer_state, place_macros, net_cost_handler, reward_fun, rng, placer_opts.place_static_move_prob); + move_generators.second = std::make_unique(placer_state, place_macros, net_cost_handler, reward_fun, rng, placer_opts.place_static_move_prob); } else { //RL based placement /* For the non timing driven placement: the agent has a single state * * - Available moves are (Uniform / Median / Centroid) * @@ -91,6 +92,7 @@ std::pair, std::unique_ptr> create karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.first = std::make_unique(placer_state, place_macros, + net_cost_handler, reward_fun, rng, karmed_bandit_agent1, @@ -105,6 +107,7 @@ std::pair, std::unique_ptr> create karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.second = std::make_unique(placer_state, place_macros, + net_cost_handler, reward_fun, rng, karmed_bandit_agent2, @@ -129,6 +132,7 @@ std::pair, std::unique_ptr> create karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.first = std::make_unique(placer_state, place_macros, + net_cost_handler, reward_fun, rng, karmed_bandit_agent1, @@ -142,6 +146,7 @@ std::pair, std::unique_ptr> create karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.second = std::make_unique(placer_state, place_macros, + net_cost_handler, reward_fun, rng, karmed_bandit_agent2, diff --git a/vpr/src/place/RL_agent_util.h b/vpr/src/place/RL_agent_util.h index 326cbf01548..511cd73d0d6 100644 --- a/vpr/src/place/RL_agent_util.h +++ b/vpr/src/place/RL_agent_util.h @@ -30,6 +30,7 @@ enum class e_agent_state { */ std::pair, std::unique_ptr> create_move_generators(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, const t_placer_opts& placer_opts, int move_lim, double noc_attraction_weight, diff --git a/vpr/src/place/annealer.cpp b/vpr/src/place/annealer.cpp index 13426283c6c..949dfe5b4c1 100644 --- a/vpr/src/place/annealer.cpp +++ b/vpr/src/place/annealer.cpp @@ -213,7 +213,7 @@ PlacementAnnealer::PlacementAnnealer(const t_placer_opts& placer_opts, , rng_(rng) , move_generator_1_(std::move(move_generator_1)) , move_generator_2_(std::move(move_generator_2)) - , manual_move_generator_(placer_state, place_macros, rng) + , manual_move_generator_(placer_state, place_macros, net_cost_handler, rng) , agent_state_(e_agent_state::EARLY_IN_THE_ANNEAL) , delay_model_(delay_model) , criticalities_(criticalities) @@ -257,14 +257,14 @@ PlacementAnnealer::PlacementAnnealer(const t_placer_opts& placer_opts, tot_iter_ = 0; // Get the first range limiter - placer_state_.mutable_move().first_rlim = (float)std::max(device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); + MoveGenerator::first_rlim = (float)std::max(device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); // In automatic schedule we do a number of random moves before starting the main annealer // to get an estimate for the initial temperature. We set this temperature low // to ensure that initial placement quality will be preserved constexpr float pre_annealing_temp = 1.e-15f; annealing_state_ = t_annealing_state(pre_annealing_temp, - placer_state_.move().first_rlim, + MoveGenerator::first_rlim, first_move_lim, first_crit_exponent); diff --git a/vpr/src/place/move_generators/centroid_move_generator.cpp b/vpr/src/place/move_generators/centroid_move_generator.cpp index c144e2f2ccf..68850ac6b98 100644 --- a/vpr/src/place/move_generators/centroid_move_generator.cpp +++ b/vpr/src/place/move_generators/centroid_move_generator.cpp @@ -11,20 +11,22 @@ CentroidMoveGenerator::CentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) , weighted_(false) , noc_attraction_weight_(0.0f) , noc_attraction_enabled_(false) {} CentroidMoveGenerator::CentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, float noc_attraction_weight, size_t high_fanout_net) - : MoveGenerator(placer_state, place_macros, reward_function, rng) + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) , noc_attraction_weight_(noc_attraction_weight) , noc_attraction_enabled_(true) { VTR_ASSERT(noc_attraction_weight > 0.0 && noc_attraction_weight <= 1.0); @@ -41,7 +43,6 @@ e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& block const auto& block_locs = placer_state.block_locs(); const auto& device_ctx = g_vpr_ctx.device(); const auto& cluster_ctx = g_vpr_ctx.clustering(); - const auto& place_move_ctx = placer_state.move(); const auto& blk_loc_registry = placer_state.blk_loc_registry(); // Find a movable block based on blk_type @@ -71,7 +72,7 @@ e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& block VTR_ASSERT(is_tile_compatible(grid_from_type, cluster_from_type)); t_range_limiters range_limiters{rlim, - place_move_ctx.first_rlim, + first_rlim, placer_opts.place_dm_rlim}; t_pl_loc to; diff --git a/vpr/src/place/move_generators/centroid_move_generator.h b/vpr/src/place/move_generators/centroid_move_generator.h index 64577178f4a..f818b03f8fb 100644 --- a/vpr/src/place/move_generators/centroid_move_generator.h +++ b/vpr/src/place/move_generators/centroid_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_CENTROID_MOVE_GEN_H -#define VPR_CENTROID_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -33,6 +32,7 @@ class CentroidMoveGenerator : public MoveGenerator { */ CentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -53,6 +53,7 @@ class CentroidMoveGenerator : public MoveGenerator { */ CentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, float noc_attraction_weight, @@ -131,5 +132,3 @@ class CentroidMoveGenerator : public MoveGenerator { */ void initialize_noc_groups(size_t high_fanout_net); }; - -#endif diff --git a/vpr/src/place/move_generators/critical_uniform_move_generator.cpp b/vpr/src/place/move_generators/critical_uniform_move_generator.cpp index d076f16a948..0a641c30043 100644 --- a/vpr/src/place/move_generators/critical_uniform_move_generator.cpp +++ b/vpr/src/place/move_generators/critical_uniform_move_generator.cpp @@ -10,9 +10,10 @@ CriticalUniformMoveGenerator::CriticalUniformMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) {} e_create_move CriticalUniformMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/move_generators/critical_uniform_move_generator.h b/vpr/src/place/move_generators/critical_uniform_move_generator.h index b49535a4198..7b8e316e867 100644 --- a/vpr/src/place/move_generators/critical_uniform_move_generator.h +++ b/vpr/src/place/move_generators/critical_uniform_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_CRITICAL_UNIFORM_MOVE_GEN_H -#define VPR_CRITICAL_UNIFORM_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -21,6 +20,7 @@ class CriticalUniformMoveGenerator : public MoveGenerator { CriticalUniformMoveGenerator() = delete; CriticalUniformMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -31,5 +31,3 @@ class CriticalUniformMoveGenerator : public MoveGenerator { const t_placer_opts& /*placer_opts*/, const PlacerCriticalities* /*criticalities*/) override; }; - -#endif diff --git a/vpr/src/place/move_generators/feasible_region_move_generator.cpp b/vpr/src/place/move_generators/feasible_region_move_generator.cpp index e9758bf6391..bb8de8522e5 100644 --- a/vpr/src/place/move_generators/feasible_region_move_generator.cpp +++ b/vpr/src/place/move_generators/feasible_region_move_generator.cpp @@ -12,9 +12,10 @@ FeasibleRegionMoveGenerator::FeasibleRegionMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) {} e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, @@ -23,7 +24,6 @@ e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& const PlacerCriticalities* criticalities) { const auto& cluster_ctx = g_vpr_ctx.clustering(); auto& placer_state = placer_state_.get(); - auto& place_move_ctx = placer_state.mutable_move(); const auto& block_locs = placer_state.block_locs(); const auto& blk_loc_registry = placer_state.blk_loc_registry(); @@ -48,18 +48,22 @@ e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& //from block data t_pl_loc from = block_locs[b_from].loc; - auto cluster_from_type = cluster_ctx.clb_nlist.block_type(b_from); - auto grid_from_type = g_vpr_ctx.device().grid.get_physical_type({from.x, from.y, from.layer}); + t_logical_block_type_ptr cluster_from_type = cluster_ctx.clb_nlist.block_type(b_from); + t_physical_tile_type_ptr grid_from_type = g_vpr_ctx.device().grid.get_physical_type({from.x, from.y, from.layer}); VTR_ASSERT(is_tile_compatible(grid_from_type, cluster_from_type)); /* Calculate the feasible region */ t_pl_loc to; // Currently, we don't change the layer for this move to.layer = from.layer; - int max_x, min_x, max_y, min_y; - place_move_ctx.X_coord.clear(); - place_move_ctx.Y_coord.clear(); + int max_x = std::numeric_limits::min(); + int min_x = std::numeric_limits::max(); + int max_y = std::numeric_limits::min(); + int min_y = std::numeric_limits::max(); + + bool found = false; + //For critical input nodes, calculate the x & y min-max values for (ClusterPinId pin_id : cluster_ctx.clb_nlist.block_input_pins(b_from)) { ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(pin_id); @@ -69,28 +73,25 @@ e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& int ipin = cluster_ctx.clb_nlist.pin_net_index(pin_id); if (criticalities->criticality(net_id, ipin) > placer_opts.place_crit_limit) { ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); - place_move_ctx.X_coord.push_back(block_locs[bnum].loc.x); - place_move_ctx.Y_coord.push_back(block_locs[bnum].loc.y); + const t_pl_loc& loc = block_locs[bnum].loc; + min_x = std::min(min_x, loc.x); + max_x = std::max(max_x, loc.x); + min_y = std::min(min_y, loc.y); + max_y = std::max(max_y, loc.y); + found = true; } } - if (!place_move_ctx.X_coord.empty()) { - max_x = *(std::max_element(place_move_ctx.X_coord.begin(), place_move_ctx.X_coord.end())); - min_x = *(std::min_element(place_move_ctx.X_coord.begin(), place_move_ctx.X_coord.end())); - max_y = *(std::max_element(place_move_ctx.Y_coord.begin(), place_move_ctx.Y_coord.end())); - min_y = *(std::min_element(place_move_ctx.Y_coord.begin(), place_move_ctx.Y_coord.end())); - } else { - max_x = from.x; - min_x = from.x; - max_y = from.y; - min_y = from.y; + + if (!found) { + min_x = max_x = from.x; + min_y = max_y = from.y; } //Get the most critical output of the node - int xt, yt; ClusterBlockId b_output = cluster_ctx.clb_nlist.net_pin_block(net_from, pin_from); t_pl_loc output_loc = block_locs[b_output].loc; - xt = output_loc.x; - yt = output_loc.y; + int xt = output_loc.x; + int yt = output_loc.y; /** * @brief determine the feasible region @@ -128,14 +129,13 @@ e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& VTR_ASSERT(FR_coords.ymin <= FR_coords.ymax); t_range_limiters range_limiters{rlim, - place_move_ctx.first_rlim, + first_rlim, placer_opts.place_dm_rlim}; // Try to find a legal location inside the feasible region if (!find_to_loc_median(cluster_from_type, from, &FR_coords, to, b_from, blk_loc_registry, rng_)) { - /** If there is no legal location in the feasible region, calculate the center of the FR and try to find a legal location - * in a range around this center. - */ + /* If there is no legal location in the feasible region, calculate the center of the FR and try to find a legal location + * in a range around this center. */ t_pl_loc center; center.x = (FR_coords.xmin + FR_coords.xmax) / 2; center.y = (FR_coords.ymin + FR_coords.ymax) / 2; diff --git a/vpr/src/place/move_generators/feasible_region_move_generator.h b/vpr/src/place/move_generators/feasible_region_move_generator.h index cf869f86b78..72e58b17753 100644 --- a/vpr/src/place/move_generators/feasible_region_move_generator.h +++ b/vpr/src/place/move_generators/feasible_region_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_FEASIBLE_REGION_MOVE_GEN_H -#define VPR_FEASIBLE_REGION_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -25,6 +24,7 @@ class FeasibleRegionMoveGenerator : public MoveGenerator { FeasibleRegionMoveGenerator() = delete; FeasibleRegionMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -35,5 +35,3 @@ class FeasibleRegionMoveGenerator : public MoveGenerator { const t_placer_opts& placer_opts, const PlacerCriticalities* criticalities) override; }; - -#endif diff --git a/vpr/src/place/move_generators/manual_move_generator.cpp b/vpr/src/place/move_generators/manual_move_generator.cpp index 9d3e310a67a..cebbe8e8dd6 100644 --- a/vpr/src/place/move_generators/manual_move_generator.cpp +++ b/vpr/src/place/move_generators/manual_move_generator.cpp @@ -22,8 +22,9 @@ ManualMoveGenerator::ManualMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, e_reward_function::UNDEFINED_REWARD, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, e_reward_function::UNDEFINED_REWARD, rng) {} //Manual Move Generator function e_create_move ManualMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/move_generators/manual_move_generator.h b/vpr/src/place/move_generators/manual_move_generator.h index 108bce80827..417ecb9d514 100644 --- a/vpr/src/place/move_generators/manual_move_generator.h +++ b/vpr/src/place/move_generators/manual_move_generator.h @@ -5,8 +5,7 @@ * @brief Contains the ManualMoveGenerator class. */ -#ifndef VPR_MANUAL_MOVE_GEN_H -#define VPR_MANUAL_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -22,6 +21,7 @@ class ManualMoveGenerator : public MoveGenerator { ManualMoveGenerator() = delete; ManualMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, vtr::RngContainer& rng); //Evaluates if move is successful and legal or unable to do. @@ -31,5 +31,3 @@ class ManualMoveGenerator : public MoveGenerator { const t_placer_opts& /*placer_opts*/, const PlacerCriticalities* /*criticalities*/) override; }; - -#endif /*VPR_MANUAL_MOVE_GEN_H */ diff --git a/vpr/src/place/move_generators/median_move_generator.cpp b/vpr/src/place/move_generators/median_move_generator.cpp index 0efde29fd04..f3652d97789 100644 --- a/vpr/src/place/move_generators/median_move_generator.cpp +++ b/vpr/src/place/move_generators/median_move_generator.cpp @@ -6,14 +6,16 @@ #include "place_macro.h" #include "placer_state.h" #include "move_utils.h" +#include "net_cost_handler.h" #include MedianMoveGenerator::MedianMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) {} e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, @@ -23,7 +25,6 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_ const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& device_ctx = g_vpr_ctx.device(); auto& placer_state = placer_state_.get(); - auto& place_move_ctx = placer_state.mutable_move(); const auto& block_locs = placer_state.block_locs(); const auto& blk_loc_registry = placer_state.blk_loc_registry(); @@ -60,9 +61,9 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_ //clear the vectors that saves X & Y coords //reused to save allocation time - place_move_ctx.X_coord.clear(); - place_move_ctx.Y_coord.clear(); - place_move_ctx.layer_coord.clear(); + X_coord.clear(); + Y_coord.clear(); + layer_coord.clear(); std::vector layer_blk_cnt(num_layers, 0); //true if the net is a feedback from the block to itself @@ -89,10 +90,10 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_ t_bb union_bb; const bool cube_bb = g_vpr_ctx.placement().cube_bb; if (!cube_bb) { - union_bb = union_2d_bb(place_move_ctx.layer_bb_coords[net_id]); + union_bb = net_cost_handler_.union_2d_bb(net_id); } - const auto& net_bb_coords = cube_bb ? place_move_ctx.bb_coords[net_id] : union_bb; + const auto& net_bb_coords = cube_bb ? net_cost_handler_.bb_coords(net_id) : union_bb; t_physical_tile_loc old_pin_loc = blk_loc_registry.get_coordinate_of_pin(pin_id); t_physical_tile_loc new_pin_loc; @@ -126,36 +127,36 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_ } } //push the calculated coordinates into X,Y coord vectors - place_move_ctx.X_coord.push_back(coords.xmin); - place_move_ctx.X_coord.push_back(coords.xmax); - place_move_ctx.Y_coord.push_back(coords.ymin); - place_move_ctx.Y_coord.push_back(coords.ymax); - place_move_ctx.layer_coord.push_back(coords.layer_min); - place_move_ctx.layer_coord.push_back(coords.layer_max); + X_coord.push_back(coords.xmin); + X_coord.push_back(coords.xmax); + Y_coord.push_back(coords.ymin); + Y_coord.push_back(coords.ymax); + layer_coord.push_back(coords.layer_min); + layer_coord.push_back(coords.layer_max); } - if ((place_move_ctx.X_coord.empty()) || (place_move_ctx.Y_coord.empty()) || (place_move_ctx.layer_coord.empty())) { + if ((X_coord.empty()) || (Y_coord.empty()) || (layer_coord.empty())) { VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\tMove aborted - X_coord or y_coord or layer_coord are empty\n"); return e_create_move::ABORT; } //calculate the median region - std::stable_sort(place_move_ctx.X_coord.begin(), place_move_ctx.X_coord.end()); - std::stable_sort(place_move_ctx.Y_coord.begin(), place_move_ctx.Y_coord.end()); - std::stable_sort(place_move_ctx.layer_coord.begin(), place_move_ctx.layer_coord.end()); + std::stable_sort(X_coord.begin(), X_coord.end()); + std::stable_sort(Y_coord.begin(), Y_coord.end()); + std::stable_sort(layer_coord.begin(), layer_coord.end()); - limit_coords.xmin = place_move_ctx.X_coord[((place_move_ctx.X_coord.size() - 1) / 2)]; - limit_coords.xmax = place_move_ctx.X_coord[((place_move_ctx.X_coord.size() - 1) / 2) + 1]; + limit_coords.xmin = X_coord[((X_coord.size() - 1) / 2)]; + limit_coords.xmax = X_coord[((X_coord.size() - 1) / 2) + 1]; - limit_coords.ymin = place_move_ctx.Y_coord[((place_move_ctx.Y_coord.size() - 1) / 2)]; - limit_coords.ymax = place_move_ctx.Y_coord[((place_move_ctx.Y_coord.size() - 1) / 2) + 1]; + limit_coords.ymin = Y_coord[((Y_coord.size() - 1) / 2)]; + limit_coords.ymax = Y_coord[((Y_coord.size() - 1) / 2) + 1]; - limit_coords.layer_min = place_move_ctx.layer_coord[((place_move_ctx.layer_coord.size() - 1) / 2)]; - limit_coords.layer_max = place_move_ctx.layer_coord[((place_move_ctx.layer_coord.size() - 1) / 2) + 1]; + limit_coords.layer_min = layer_coord[((layer_coord.size() - 1) / 2)]; + limit_coords.layer_max = layer_coord[((layer_coord.size() - 1) / 2) + 1]; //arrange the different range limiters t_range_limiters range_limiters{rlim, - place_move_ctx.first_rlim, + first_rlim, placer_opts.place_dm_rlim}; //find a location in a range around the center of median region @@ -272,8 +273,6 @@ bool MedianMoveGenerator::get_bb_incrementally(ClusterNetId net_id, t_physical_tile_loc old_pin_loc, t_physical_tile_loc new_pin_loc) { //TODO: account for multiple physical pin instances per logical pin - const auto& place_move_ctx = placer_state_.get().move(); - t_bb union_bb_edge; t_bb union_bb; const bool cube_bb = g_vpr_ctx.placement().cube_bb; @@ -284,15 +283,14 @@ bool MedianMoveGenerator::get_bb_incrementally(ClusterNetId net_id, * For example, the xmax of this cube bounding box is determined by the maximum x coordinate across all blocks on all layers. */ if (!cube_bb) { - std::tie(union_bb_edge, union_bb) = union_2d_bb_incr(place_move_ctx.layer_bb_num_on_edges[net_id], - place_move_ctx.layer_bb_coords[net_id]); + std::tie(union_bb_edge, union_bb) = net_cost_handler_.union_2d_bb_incr(net_id); } /* In this move, we use a 3D bounding box. Thus, if per-layer BB is used by placer, we need to take a union of BBs and use that for the rest of * operations in this move */ - const t_bb& curr_bb_edge = cube_bb ? place_move_ctx.bb_num_on_edges[net_id] : union_bb_edge; - const t_bb& curr_bb_coord = cube_bb ? place_move_ctx.bb_coords[net_id] : union_bb; + const t_bb& curr_bb_edge = cube_bb ? net_cost_handler_.bb_num_on_edges(net_id) : union_bb_edge; + const t_bb& curr_bb_coord = cube_bb ? net_cost_handler_.bb_coords(net_id) : union_bb; /* Check if I can update the bounding box incrementally. */ diff --git a/vpr/src/place/move_generators/median_move_generator.h b/vpr/src/place/move_generators/median_move_generator.h index 4dc037350f9..62326cbe145 100644 --- a/vpr/src/place/move_generators/median_move_generator.h +++ b/vpr/src/place/move_generators/median_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_MEDIAN_MOVE_GEN_H -#define VPR_MEDIAN_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -23,6 +22,7 @@ class MedianMoveGenerator : public MoveGenerator { MedianMoveGenerator() = delete; MedianMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -64,6 +64,12 @@ class MedianMoveGenerator : public MoveGenerator { t_bb& bb_coord_new, ClusterBlockId moving_block_id, bool& skip_net); -}; -#endif + private: + /// Stores x positions to find the median + std::vector X_coord; + /// Stores y positions to find the median + std::vector Y_coord; + /// Stores layer positions to find the median + std::vector layer_coord; +}; diff --git a/vpr/src/place/move_generators/move_generator.cpp b/vpr/src/place/move_generators/move_generator.cpp index b627b7ef9e0..9aa3a527a34 100644 --- a/vpr/src/place/move_generators/move_generator.cpp +++ b/vpr/src/place/move_generators/move_generator.cpp @@ -3,6 +3,8 @@ #include "vpr_error.h" +float MoveGenerator::first_rlim; + void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, double delta_c, float timing_bb_factor) { diff --git a/vpr/src/place/move_generators/move_generator.h b/vpr/src/place/move_generators/move_generator.h index 2fc4cb8931d..4f9ed137247 100644 --- a/vpr/src/place/move_generators/move_generator.h +++ b/vpr/src/place/move_generators/move_generator.h @@ -1,4 +1,3 @@ - #pragma once #include "vpr_types.h" @@ -10,6 +9,7 @@ class PlaceMacros; class PlacerState; +class NetCostHandler; struct MoveOutcomeStats { float delta_cost_norm = std::numeric_limits::quiet_NaN(); @@ -101,10 +101,12 @@ class MoveGenerator { */ MoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) : placer_state_(placer_state) , place_macros_(place_macros) + , net_cost_handler_(net_cost_handler) , reward_func_(reward_function) , rng_(rng) {} @@ -157,9 +159,22 @@ class MoveGenerator { double delta_c, float timing_bb_factor); + public: + /** + * @brief Initial move range limit for clustered blocks. + * + * @details + * Used by multiple move generators to track annealing progress and adjust behavior. + * Several move generators compare the current range limit with its initial value to + * see if the annealing is in its early or late iterations. + * Since no specific move generators owns this variable, it's been made static. + */ + static float first_rlim; + protected: std::reference_wrapper placer_state_; const PlaceMacros& place_macros_; + const NetCostHandler& net_cost_handler_; e_reward_function reward_func_; vtr::RngContainer& rng_; }; diff --git a/vpr/src/place/move_generators/simpleRL_move_generator.h b/vpr/src/place/move_generators/simpleRL_move_generator.h index 1959f1cec80..a3df9f01ac2 100644 --- a/vpr/src/place/move_generators/simpleRL_move_generator.h +++ b/vpr/src/place/move_generators/simpleRL_move_generator.h @@ -1,5 +1,5 @@ -#ifndef VPR_SIMPLERL_MOVE_GEN_H -#define VPR_SIMPLERL_MOVE_GEN_H +#pragma once + #include "move_generator.h" #include "median_move_generator.h" #include "weighted_median_move_generator.h" @@ -231,13 +231,12 @@ class SimpleRLMoveGenerator : public MoveGenerator { * * @param agent std::unique_ptr to the agent. Only EpsilonGreedyAgent and SoftmaxAgent types are accepted * by the constructor. If other types are passed, a compile error would be thrown. - * - * @param is_multi_layer A boolean value to indicate whether the placement is multi-layer or not */ template::value || std::is_same::value>::type> explicit SimpleRLMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, std::unique_ptr& agent, @@ -258,30 +257,30 @@ class SimpleRLMoveGenerator : public MoveGenerator { template SimpleRLMoveGenerator::SimpleRLMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, std::unique_ptr& agent, float noc_attraction_weight, size_t high_fanout_thresh) - : MoveGenerator(placer_state, place_macros, reward_function, rng) { + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) { if (noc_attraction_weight > 0.0f) { all_moves.resize((int)e_move_type::NUMBER_OF_AUTO_MOVES); } else { all_moves.resize((int)e_move_type::NUMBER_OF_AUTO_MOVES - 1); } - all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, place_macros_, reward_function, rng); + all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); if (noc_attraction_weight > 0.0f) { - all_moves[e_move_type::NOC_ATTRACTION_CENTROID] = std::make_unique(placer_state, place_macros_, reward_function, rng, + all_moves[e_move_type::NOC_ATTRACTION_CENTROID] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng, noc_attraction_weight, high_fanout_thresh); } karmed_bandit_agent = std::move(agent); } -#endif diff --git a/vpr/src/place/move_generators/static_move_generator.cpp b/vpr/src/place/move_generators/static_move_generator.cpp index facfc979b80..bbe9248682c 100644 --- a/vpr/src/place/move_generators/static_move_generator.cpp +++ b/vpr/src/place/move_generators/static_move_generator.cpp @@ -15,19 +15,20 @@ StaticMoveGenerator::StaticMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, const vtr::vector& move_probs) - : MoveGenerator(placer_state, place_macros, reward_function, rng) { + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) { all_moves.resize((int)e_move_type::NUMBER_OF_AUTO_MOVES); - all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, place_macros_, reward_function, rng); - all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, place_macros_, reward_function, rng); + all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); + all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, place_macros_, net_cost_handler_, reward_function, rng); initialize_move_prob(move_probs); } diff --git a/vpr/src/place/move_generators/static_move_generator.h b/vpr/src/place/move_generators/static_move_generator.h index 6161d004c56..803109b5dbc 100644 --- a/vpr/src/place/move_generators/static_move_generator.h +++ b/vpr/src/place/move_generators/static_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_STATIC_MOVE_GEN_H -#define VPR_STATIC_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -22,6 +21,7 @@ class StaticMoveGenerator : public MoveGenerator { StaticMoveGenerator() = delete; StaticMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng, const vtr::vector& move_probs); @@ -32,4 +32,3 @@ class StaticMoveGenerator : public MoveGenerator { const t_placer_opts& placer_opts, const PlacerCriticalities* criticalities) override; }; -#endif diff --git a/vpr/src/place/move_generators/uniform_move_generator.cpp b/vpr/src/place/move_generators/uniform_move_generator.cpp index 216ef8a1a36..ebfebca5652 100644 --- a/vpr/src/place/move_generators/uniform_move_generator.cpp +++ b/vpr/src/place/move_generators/uniform_move_generator.cpp @@ -9,9 +9,10 @@ UniformMoveGenerator::UniformMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) {} e_create_move UniformMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/move_generators/uniform_move_generator.h b/vpr/src/place/move_generators/uniform_move_generator.h index 5513c728d38..f91ff71635b 100644 --- a/vpr/src/place/move_generators/uniform_move_generator.h +++ b/vpr/src/place/move_generators/uniform_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_UNIFORM_MOVE_GEN_H -#define VPR_UNIFORM_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -16,6 +15,7 @@ class UniformMoveGenerator : public MoveGenerator { UniformMoveGenerator() = delete; UniformMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -26,5 +26,3 @@ class UniformMoveGenerator : public MoveGenerator { const t_placer_opts& /*placer_opts*/, const PlacerCriticalities* /*criticalities*/) override; }; - -#endif diff --git a/vpr/src/place/move_generators/weighted_centroid_move_generator.cpp b/vpr/src/place/move_generators/weighted_centroid_move_generator.cpp index 3250e48a3b7..489d5f0ceb4 100644 --- a/vpr/src/place/move_generators/weighted_centroid_move_generator.cpp +++ b/vpr/src/place/move_generators/weighted_centroid_move_generator.cpp @@ -3,8 +3,9 @@ WeightedCentroidMoveGenerator::WeightedCentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : CentroidMoveGenerator(placer_state, place_macros, reward_function, rng) { + : CentroidMoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) { weighted_ = true; } diff --git a/vpr/src/place/move_generators/weighted_centroid_move_generator.h b/vpr/src/place/move_generators/weighted_centroid_move_generator.h index cd8ec1e4943..8d07a0e6118 100644 --- a/vpr/src/place/move_generators/weighted_centroid_move_generator.h +++ b/vpr/src/place/move_generators/weighted_centroid_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_WEIGHTED_CENTROID_MOVE_GEN_H -#define VPR_WEIGHTED_CENTROID_MOVE_GEN_H +#pragma once #include "centroid_move_generator.h" @@ -21,8 +20,7 @@ class WeightedCentroidMoveGenerator : public CentroidMoveGenerator { WeightedCentroidMoveGenerator() = delete; WeightedCentroidMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); }; - -#endif diff --git a/vpr/src/place/move_generators/weighted_median_move_generator.cpp b/vpr/src/place/move_generators/weighted_median_move_generator.cpp index a063cdab3ac..9588e899fa6 100644 --- a/vpr/src/place/move_generators/weighted_median_move_generator.cpp +++ b/vpr/src/place/move_generators/weighted_median_move_generator.cpp @@ -14,9 +14,10 @@ WeightedMedianMoveGenerator::WeightedMedianMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng) - : MoveGenerator(placer_state, place_macros, reward_function, rng) {} + : MoveGenerator(placer_state, place_macros, net_cost_handler, reward_function, rng) {} e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, @@ -26,7 +27,6 @@ e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& const auto& cluster_ctx = g_vpr_ctx.clustering(); auto& placer_state = placer_state_.get(); const auto& block_locs = placer_state.block_locs(); - auto& place_move_ctx = placer_state.mutable_move(); const auto& blk_loc_registry = placer_state.blk_loc_registry(); //Find a movable block based on blk_type @@ -61,9 +61,9 @@ e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& //clear the vectors that saves X & Y coords //reused to save allocation time - place_move_ctx.X_coord.clear(); - place_move_ctx.Y_coord.clear(); - place_move_ctx.layer_coord.clear(); + X_coord.clear(); + Y_coord.clear(); + layer_coord.clear(); std::vector layer_blk_cnt(num_layers, 0); //iterate over block pins @@ -91,50 +91,50 @@ e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& // We need to insert the calculated edges in the X,Y vectors multiple times based on the criticality of the pin that caused each of them. // As all the criticalities are [0,1], we map it to [0,CRIT_MULT_FOR_W_MEDIAN] inserts in the vectors for each edge // by multiplying each edge's criticality by CRIT_MULT_FOR_W_MEDIAN - place_move_ctx.X_coord.insert(place_move_ctx.X_coord.end(), ceil(coords.xmin.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.xmin.edge); - place_move_ctx.X_coord.insert(place_move_ctx.X_coord.end(), ceil(coords.xmax.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.xmax.edge); - place_move_ctx.Y_coord.insert(place_move_ctx.Y_coord.end(), ceil(coords.ymin.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.ymin.edge); - place_move_ctx.Y_coord.insert(place_move_ctx.Y_coord.end(), ceil(coords.ymax.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.ymax.edge); - place_move_ctx.layer_coord.insert(place_move_ctx.layer_coord.end(), ceil(coords.layer_min.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.layer_min.edge); - place_move_ctx.layer_coord.insert(place_move_ctx.layer_coord.end(), ceil(coords.layer_max.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.layer_max.edge); + X_coord.insert(X_coord.end(), ceil(coords.xmin.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.xmin.edge); + X_coord.insert(X_coord.end(), ceil(coords.xmax.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.xmax.edge); + Y_coord.insert(Y_coord.end(), ceil(coords.ymin.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.ymin.edge); + Y_coord.insert(Y_coord.end(), ceil(coords.ymax.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.ymax.edge); + layer_coord.insert(layer_coord.end(), ceil(coords.layer_min.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.layer_min.edge); + layer_coord.insert(layer_coord.end(), ceil(coords.layer_max.criticality * CRIT_MULT_FOR_W_MEDIAN), coords.layer_max.edge); } - if ((place_move_ctx.X_coord.empty()) || (place_move_ctx.Y_coord.empty()) || (place_move_ctx.layer_coord.empty())) { + if ((X_coord.empty()) || (Y_coord.empty()) || (layer_coord.empty())) { VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\tMove aborted - X_coord or y_coord or layer_coord are empty\n"); return e_create_move::ABORT; } //calculate the weighted median region - std::stable_sort(place_move_ctx.X_coord.begin(), place_move_ctx.X_coord.end()); - std::stable_sort(place_move_ctx.Y_coord.begin(), place_move_ctx.Y_coord.end()); - std::stable_sort(place_move_ctx.layer_coord.begin(), place_move_ctx.layer_coord.end()); + std::stable_sort(X_coord.begin(), X_coord.end()); + std::stable_sort(Y_coord.begin(), Y_coord.end()); + std::stable_sort(layer_coord.begin(), layer_coord.end()); - if (place_move_ctx.X_coord.size() == 1) { - limit_coords.xmin = place_move_ctx.X_coord[0]; + if (X_coord.size() == 1) { + limit_coords.xmin = X_coord[0]; limit_coords.xmax = limit_coords.xmin; } else { - limit_coords.xmin = place_move_ctx.X_coord[((place_move_ctx.X_coord.size() - 1) / 2)]; - limit_coords.xmax = place_move_ctx.X_coord[((place_move_ctx.X_coord.size() - 1) / 2) + 1]; + limit_coords.xmin = X_coord[((X_coord.size() - 1) / 2)]; + limit_coords.xmax = X_coord[((X_coord.size() - 1) / 2) + 1]; } - if (place_move_ctx.Y_coord.size() == 1) { - limit_coords.ymin = place_move_ctx.Y_coord[0]; + if (Y_coord.size() == 1) { + limit_coords.ymin = Y_coord[0]; limit_coords.ymax = limit_coords.ymin; } else { - limit_coords.ymin = place_move_ctx.Y_coord[((place_move_ctx.Y_coord.size() - 1) / 2)]; - limit_coords.ymax = place_move_ctx.Y_coord[((place_move_ctx.Y_coord.size() - 1) / 2) + 1]; + limit_coords.ymin = Y_coord[((Y_coord.size() - 1) / 2)]; + limit_coords.ymax = Y_coord[((Y_coord.size() - 1) / 2) + 1]; } - if (place_move_ctx.layer_coord.size() == 1) { - limit_coords.layer_min = place_move_ctx.layer_coord[0]; + if (layer_coord.size() == 1) { + limit_coords.layer_min = layer_coord[0]; limit_coords.layer_max = limit_coords.layer_min; } else { - limit_coords.layer_min = place_move_ctx.layer_coord[((place_move_ctx.layer_coord.size() - 1) / 2)]; - limit_coords.layer_max = place_move_ctx.layer_coord[((place_move_ctx.layer_coord.size() - 1) / 2) + 1]; + limit_coords.layer_min = layer_coord[((layer_coord.size() - 1) / 2)]; + limit_coords.layer_max = layer_coord[((layer_coord.size() - 1) / 2) + 1]; } t_range_limiters range_limiters{rlim, - place_move_ctx.first_rlim, + first_rlim, placer_opts.place_dm_rlim}; t_pl_loc w_median_point; diff --git a/vpr/src/place/move_generators/weighted_median_move_generator.h b/vpr/src/place/move_generators/weighted_median_move_generator.h index fc1a61394d1..6cdaf72588f 100644 --- a/vpr/src/place/move_generators/weighted_median_move_generator.h +++ b/vpr/src/place/move_generators/weighted_median_move_generator.h @@ -1,5 +1,4 @@ -#ifndef VPR_WEIGHTED_MEDIAN_MOVE_GEN_H -#define VPR_WEIGHTED_MEDIAN_MOVE_GEN_H +#pragma once #include "move_generator.h" @@ -19,6 +18,7 @@ class WeightedMedianMoveGenerator : public MoveGenerator { WeightedMedianMoveGenerator() = delete; WeightedMedianMoveGenerator(PlacerState& placer_state, const PlaceMacros& place_macros, + const NetCostHandler& net_cost_handler, e_reward_function reward_function, vtr::RngContainer& rng); @@ -44,6 +44,12 @@ class WeightedMedianMoveGenerator : public MoveGenerator { ClusterPinId moving_pin_id, const PlacerCriticalities* criticalities, t_bb_cost* coords); -}; -#endif + private: + /// Stores x positions to find the median + std::vector X_coord; + /// Stores y positions to find the median + std::vector Y_coord; + /// Stores layer positions to find the median + std::vector layer_coord; +}; diff --git a/vpr/src/place/move_utils.cpp b/vpr/src/place/move_utils.cpp index 5e941e2f3c1..f3cc457d0bb 100644 --- a/vpr/src/place/move_utils.cpp +++ b/vpr/src/place/move_utils.cpp @@ -1263,111 +1263,3 @@ int get_random_layer(t_logical_block_type_ptr logical_block, vtr::RngContainer& return layer_num; } - -t_bb union_2d_bb(const std::vector& bb_vec) { - t_bb merged_bb; - - // Not all 2d_bbs are valid. Thus, if one of the coordinates in the 2D_bb is not valid (equal to OPEN), - // we need to skip it. - for (const auto& layer_bb : bb_vec) { - if (layer_bb.xmin == OPEN) { - VTR_ASSERT_SAFE(layer_bb.xmax == OPEN); - VTR_ASSERT_SAFE(layer_bb.ymin == OPEN); - VTR_ASSERT_SAFE(layer_bb.ymax == OPEN); - VTR_ASSERT_SAFE(layer_bb.layer_num == OPEN); - continue; - } - if (merged_bb.xmin == OPEN || layer_bb.xmin < merged_bb.xmin) { - merged_bb.xmin = layer_bb.xmin; - } - if (merged_bb.xmax == OPEN || layer_bb.xmax > merged_bb.xmax) { - merged_bb.xmax = layer_bb.xmax; - } - if (merged_bb.ymin == OPEN || layer_bb.ymin < merged_bb.ymin) { - merged_bb.ymin = layer_bb.ymin; - } - if (merged_bb.ymax == OPEN || layer_bb.ymax > merged_bb.ymax) { - merged_bb.ymax = layer_bb.ymax; - } - if (merged_bb.layer_min == OPEN || layer_bb.layer_num < merged_bb.layer_min) { - merged_bb.layer_min = layer_bb.layer_num; - } - if (merged_bb.layer_max == OPEN || layer_bb.layer_num > merged_bb.layer_max) { - merged_bb.layer_max = layer_bb.layer_num; - } - } - - return merged_bb; -} - -std::pair union_2d_bb_incr(const std::vector& num_edge_vec, - const std::vector& bb_vec) { - t_bb merged_num_edge; - t_bb merged_bb; - - for (const auto& layer_bb : bb_vec) { - if (layer_bb.xmin == OPEN) { - VTR_ASSERT_SAFE(layer_bb.xmax == OPEN); - VTR_ASSERT_SAFE(layer_bb.ymin == OPEN); - VTR_ASSERT_SAFE(layer_bb.ymax == OPEN); - VTR_ASSERT_SAFE(layer_bb.layer_num == OPEN); - continue; - } - if (merged_bb.xmin == OPEN || layer_bb.xmin <= merged_bb.xmin) { - if (layer_bb.xmin == merged_bb.xmin) { - VTR_ASSERT_SAFE(merged_num_edge.xmin != OPEN); - merged_num_edge.xmin += num_edge_vec[layer_bb.layer_num].xmin; - } else { - merged_num_edge.xmin = num_edge_vec[layer_bb.layer_num].xmin; - } - merged_bb.xmin = layer_bb.xmin; - } - if (merged_bb.xmax == OPEN || layer_bb.xmax >= merged_bb.xmax) { - if (layer_bb.xmax == merged_bb.xmax) { - VTR_ASSERT_SAFE(merged_num_edge.xmax != OPEN); - merged_num_edge.xmax += num_edge_vec[layer_bb.layer_num].xmax; - } else { - merged_num_edge.xmax = num_edge_vec[layer_bb.layer_num].xmax; - } - merged_bb.xmax = layer_bb.xmax; - } - if (merged_bb.ymin == OPEN || layer_bb.ymin <= merged_bb.ymin) { - if (layer_bb.ymin == merged_bb.ymin) { - VTR_ASSERT_SAFE(merged_num_edge.ymin != OPEN); - merged_num_edge.ymin += num_edge_vec[layer_bb.layer_num].ymin; - } else { - merged_num_edge.ymin = num_edge_vec[layer_bb.layer_num].ymin; - } - merged_bb.ymin = layer_bb.ymin; - } - if (merged_bb.ymax == OPEN || layer_bb.ymax >= merged_bb.ymax) { - if (layer_bb.ymax == merged_bb.ymax) { - VTR_ASSERT_SAFE(merged_num_edge.ymax != OPEN); - merged_num_edge.ymax += num_edge_vec[layer_bb.layer_num].ymax; - } else { - merged_num_edge.ymax = num_edge_vec[layer_bb.layer_num].ymax; - } - merged_bb.ymax = layer_bb.ymax; - } - if (merged_bb.layer_min == OPEN || layer_bb.layer_num <= merged_bb.layer_min) { - if (layer_bb.layer_num == merged_bb.layer_min) { - VTR_ASSERT_SAFE(merged_num_edge.layer_min != OPEN); - merged_num_edge.layer_min += num_edge_vec[layer_bb.layer_num].layer_num; - } else { - merged_num_edge.layer_min = num_edge_vec[layer_bb.layer_num].layer_num; - } - merged_bb.layer_min = layer_bb.layer_num; - } - if (merged_bb.layer_max == OPEN || layer_bb.layer_num >= merged_bb.layer_max) { - if (layer_bb.layer_num == merged_bb.layer_max) { - VTR_ASSERT_SAFE(merged_num_edge.layer_max != OPEN); - merged_num_edge.layer_max += num_edge_vec[layer_bb.layer_num].layer_num; - } else { - merged_num_edge.layer_max = num_edge_vec[layer_bb.layer_num].layer_num; - } - merged_bb.layer_max = layer_bb.layer_num; - } - } - - return std::make_pair(merged_num_edge, merged_bb); -} diff --git a/vpr/src/place/move_utils.h b/vpr/src/place/move_utils.h index 2b0fa65bba7..5552c36e8e9 100644 --- a/vpr/src/place/move_utils.h +++ b/vpr/src/place/move_utils.h @@ -433,24 +433,6 @@ int find_free_layer(t_logical_block_type_ptr logical_block, int get_random_layer(t_logical_block_type_ptr logical_block, vtr::RngContainer& rng); -/** - * @brief Iterate over all layers and get the maximum x and y over that layers that have a valid value. set the layer min and max - * based on the layers that have a valid BB. - * @param tbb_vec - * @return 3D bounding box - */ -t_bb union_2d_bb(const std::vector& tbb_vec); - -/** - * @brief Iterate over all layers and get the maximum x and y over that layers that have a valid value. Create the "num_edge" in a similar way. This data structure - * stores how many blocks are on each edge of the BB. set the layer min and max based on the layers that have a valid BB. - * @param num_edge_vec - * @param bb_vec - * @return num_edge, 3D bb - */ -std::pair union_2d_bb_incr(const std::vector& num_edge_vec, - const std::vector& bb_vec); - /** * @brief If the block ID passed to the placer_debug_net parameter of the command line is equal to blk_id, or if any of the nets * connected to the block share the same ID as the net ID passed to the placer_debug_net parameter of the command line, diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 9f0c23fccd4..0a48466c644 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -108,6 +108,8 @@ NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, if (cube_bb_) { ts_bb_edge_new_.resize(num_nets, t_bb()); ts_bb_coord_new_.resize(num_nets, t_bb()); + bb_coords_.resize(num_nets, t_bb()); + bb_num_on_edges_.resize(num_nets, t_bb()); comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_cube_bb_cost_, this, std::placeholders::_1); update_bb_functor_ = std::bind(&NetCostHandler::update_bb_, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); @@ -116,6 +118,8 @@ NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, } else { layer_ts_bb_edge_new_.resize(num_nets, std::vector(num_layers, t_2D_bb())); layer_ts_bb_coord_new_.resize(num_nets, std::vector(num_layers, t_2D_bb())); + layer_bb_num_on_edges_.resize(num_nets, std::vector(num_layers, t_2D_bb())); + layer_bb_coords_.resize(num_nets, std::vector(num_layers, t_2D_bb())); comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_per_layer_bb_cost_, this, std::placeholders::_1); update_bb_functor_ = std::bind(&NetCostHandler::update_layer_bb_, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); @@ -125,6 +129,7 @@ NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, /* This initializes the whole matrix to OPEN which is an invalid value*/ ts_layer_sink_pin_count_.resize({num_nets, size_t(num_layers)}, OPEN); + num_sink_pin_layer_.resize({num_nets, size_t(num_layers)}, OPEN); ts_nets_to_update_.resize(num_nets, ClusterNetId::INVALID()); @@ -246,7 +251,6 @@ std::pair NetCostHandler::comp_bb_cost(e_cost_methods method) { std::pair NetCostHandler::comp_cube_bb_cost_(e_cost_methods method) { const auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& place_move_ctx = placer_state_.mutable_move(); double cost = 0; double expected_wirelength = 0.0; @@ -256,10 +260,7 @@ std::pair NetCostHandler::comp_cube_bb_cost_(e_cost_methods meth /* Small nets don't use incremental updating on their bounding boxes, * * so they can use a fast bounding box calculator. */ if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET && method == e_cost_methods::NORMAL) { - get_bb_from_scratch_(net_id, - place_move_ctx.bb_coords[net_id], - place_move_ctx.bb_num_on_edges[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + get_bb_from_scratch_(net_id, /*use_ts=*/false); } else { get_non_updatable_cube_bb_(net_id, /*use_ts=*/false); } @@ -277,7 +278,6 @@ std::pair NetCostHandler::comp_cube_bb_cost_(e_cost_methods meth std::pair NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { const auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& place_move_ctx = placer_state_.mutable_move(); double cost = 0; double expected_wirelength = 0.0; @@ -288,9 +288,9 @@ std::pair NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods * so they can use a fast bounding box calculator. */ if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET && method == e_cost_methods::NORMAL) { get_layer_bb_from_scratch_(net_id, - place_move_ctx.layer_bb_num_on_edges[net_id], - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + layer_bb_num_on_edges_[net_id], + layer_bb_coords_[net_id], + num_sink_pin_layer_[size_t(net_id)]); } else { get_non_updatable_per_layer_bb_(net_id, /*use_ts=*/false); } @@ -484,12 +484,11 @@ void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, bool use_ts const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& device_ctx = g_vpr_ctx.device(); const auto& blk_loc_registry = placer_state_.blk_loc_registry(); - auto& move_ctx = placer_state_.mutable_move(); // the bounding box coordinates that is going to be updated by this function - t_bb& bb_coord_new = use_ts ? ts_bb_coord_new_[net_id] : move_ctx.bb_coords[net_id]; + t_bb& bb_coord_new = use_ts ? ts_bb_coord_new_[net_id] : bb_coords_[net_id]; // the number of sink pins of "net_id" on each layer - vtr::NdMatrixProxy num_sink_pin_layer = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : move_ctx.num_sink_pin_layer[size_t(net_id)]; + vtr::NdMatrixProxy num_sink_pin_layer = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : num_sink_pin_layer_[size_t(net_id)]; // get the source pin's location ClusterPinId source_pin_id = cluster_ctx.clb_nlist.net_pin(net_id, 0); @@ -537,10 +536,9 @@ void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool u const auto& device_ctx = g_vpr_ctx.device(); const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& blk_loc_registry = placer_state_.blk_loc_registry(); - auto& move_ctx = placer_state_.mutable_move(); - std::vector& bb_coord_new = use_ts ? layer_ts_bb_coord_new_[net_id] : move_ctx.layer_bb_coords[net_id]; - vtr::NdMatrixProxy num_sink_layer = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : move_ctx.num_sink_pin_layer[size_t(net_id)]; + std::vector& bb_coord_new = use_ts ? layer_ts_bb_coord_new_[net_id] : layer_bb_coords_[net_id]; + vtr::NdMatrixProxy num_sink_layer = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : num_sink_pin_layer_[size_t(net_id)]; const int num_layers = device_ctx.grid.get_num_layers(); VTR_ASSERT_DEBUG(bb_coord_new.size() == (size_t)num_layers); @@ -579,8 +577,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, //TODO: account for multiple physical pin instances per logical pin const t_bb *curr_bb_edge, *curr_bb_coord; - auto& device_ctx = g_vpr_ctx.device(); - auto& place_move_ctx = placer_state_.move(); + const auto& device_ctx = g_vpr_ctx.device(); const int num_layers = device_ctx.grid.get_num_layers(); @@ -597,12 +594,12 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, return; } - vtr::NdMatrixProxy curr_num_sink_pin_layer = (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) ? place_move_ctx.num_sink_pin_layer[size_t(net_id)] : num_sink_pin_layer_new; + vtr::NdMatrixProxy curr_num_sink_pin_layer = (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) ? num_sink_pin_layer_[size_t(net_id)] : num_sink_pin_layer_new; if (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) { /* The net had NOT been updated before, could use the old values */ - curr_bb_edge = &place_move_ctx.bb_num_on_edges[net_id]; - curr_bb_coord = &place_move_ctx.bb_coords[net_id]; + curr_bb_edge = &bb_num_on_edges_[net_id]; + curr_bb_coord = &bb_coords_[net_id]; bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } else { /* The net had been updated before, must use the new values */ @@ -618,7 +615,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, if (pin_old_loc.x == curr_bb_coord->xmax) { /* Old position at xmax. */ if (curr_bb_edge->xmax == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -650,7 +647,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, if (pin_old_loc.x == curr_bb_coord->xmin) { /* Old position at xmin. */ if (curr_bb_edge->xmin == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -691,7 +688,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, if (pin_old_loc.y == curr_bb_coord->ymax) { /* Old position at ymax. */ if (curr_bb_edge->ymax == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -723,7 +720,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, if (pin_old_loc.y == curr_bb_coord->ymin) { /* Old position at ymin. */ if (curr_bb_edge->ymin == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -773,7 +770,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, if (pin_new_loc.layer_num < pin_old_loc.layer_num) { if (pin_old_loc.layer_num == curr_bb_coord->layer_max) { if (curr_bb_edge->layer_max == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -799,7 +796,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, } else if (pin_new_loc.layer_num > pin_old_loc.layer_num) { if (pin_old_loc.layer_num == curr_bb_coord->layer_min) { if (curr_bb_edge->layer_min == 1) { - get_bb_from_scratch_(net_id, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); + get_bb_from_scratch_(net_id, /*use_ts=*/true); bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -845,8 +842,6 @@ void NetCostHandler::update_layer_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_output_pin) { - auto& place_move_ctx = placer_state_.move(); - std::vector& bb_edge_new = layer_ts_bb_edge_new_[net_id]; std::vector& bb_coord_new = layer_ts_bb_coord_new_[net_id]; vtr::NdMatrixProxy bb_pin_sink_count_new = ts_layer_sink_pin_count_[size_t(net_id)]; @@ -857,13 +852,13 @@ void NetCostHandler::update_layer_bb_(ClusterNetId net_id, return; } - const vtr::NdMatrixProxy curr_layer_pin_sink_count = (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) ? place_move_ctx.num_sink_pin_layer[size_t(net_id)] : bb_pin_sink_count_new; + const vtr::NdMatrixProxy curr_layer_pin_sink_count = (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) ? num_sink_pin_layer_[size_t(net_id)] : bb_pin_sink_count_new; const std::vector*curr_bb_edge, *curr_bb_coord; if (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) { /* The net had NOT been updated before, could use the old values */ - curr_bb_edge = &place_move_ctx.layer_bb_num_on_edges[net_id]; - curr_bb_coord = &place_move_ctx.layer_bb_coords[net_id]; + curr_bb_edge = &layer_bb_num_on_edges_[net_id]; + curr_bb_coord = &layer_bb_coords_[net_id]; bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } else { /* The net had been updated before, must use the new values */ @@ -1182,15 +1177,16 @@ static void add_block_to_bb(const t_physical_tile_loc& new_pin_loc, } } -void NetCostHandler::get_bb_from_scratch_(ClusterNetId net_id, - t_bb& coords, - t_bb& num_on_edges, - vtr::NdMatrixProxy num_sink_pin_layer) { +void NetCostHandler::get_bb_from_scratch_(ClusterNetId net_id, bool use_ts) { const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& device_ctx = g_vpr_ctx.device(); const auto& grid = device_ctx.grid; const auto& blk_loc_registry = placer_state_.blk_loc_registry(); + t_bb& coords = use_ts ? ts_bb_coord_new_[net_id] : bb_coords_[net_id]; + t_bb& num_on_edges = use_ts ? ts_bb_edge_new_[net_id] : bb_num_on_edges_[net_id]; + vtr::NdMatrixProxy num_sink_pin_layer = use_ts ? ts_layer_sink_pin_count_[(size_t)net_id] : num_sink_pin_layer_[(size_t)net_id]; + // get the source pin's location ClusterPinId source_pin_id = cluster_ctx.clb_nlist.net_pin(net_id, 0); t_physical_tile_loc source_pin_loc = blk_loc_registry.get_coordinate_of_pin(source_pin_id); @@ -1338,7 +1334,7 @@ double NetCostHandler::get_net_cube_bb_cost_(ClusterNetId net_id, bool use_ts) { // Finds the cost due to one net by looking at its coordinate bounding box. auto& cluster_ctx = g_vpr_ctx.clustering(); - const t_bb& bb = use_ts ? ts_bb_coord_new_[net_id] : placer_state_.move().bb_coords[net_id]; + const t_bb& bb = use_ts ? ts_bb_coord_new_[net_id] : bb_coords_[net_id]; const double crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size()); @@ -1369,11 +1365,9 @@ double NetCostHandler::get_net_cube_bb_cost_(ClusterNetId net_id, bool use_ts) { } double NetCostHandler::get_net_per_layer_bb_cost_(ClusterNetId net_id, bool use_ts) { - const auto& move_ctx = placer_state_.move(); - // Per-layer bounding box of the net - const std::vector& bb = use_ts ? layer_ts_bb_coord_new_[net_id] : move_ctx.layer_bb_coords[net_id]; - const vtr::NdMatrixProxy layer_pin_sink_count = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : move_ctx.num_sink_pin_layer[size_t(net_id)]; + const std::vector& bb = use_ts ? layer_ts_bb_coord_new_[net_id] : layer_bb_coords_[net_id]; + const vtr::NdMatrixProxy layer_pin_sink_count = use_ts ? ts_layer_sink_pin_count_[size_t(net_id)] : num_sink_pin_layer_[size_t(net_id)]; // Finds the cost due to one net by looking at its coordinate bounding box double ncost = 0.; @@ -1412,8 +1406,7 @@ double NetCostHandler::get_net_per_layer_bb_cost_(ClusterNetId net_id, bool use_ } double NetCostHandler::get_net_wirelength_estimate_(ClusterNetId net_id) const { - const auto& move_ctx = placer_state_.move(); - const t_bb& bb = move_ctx.bb_coords[net_id]; + const t_bb& bb = bb_coords_[net_id]; auto& cluster_ctx = g_vpr_ctx.clustering(); double crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size()); @@ -1436,9 +1429,8 @@ double NetCostHandler::get_net_wirelength_from_layer_bb_(ClusterNetId net_id) co /* WMF: Finds the estimate of wirelength due to one net by looking at * * its coordinate bounding box. */ - const auto& move_ctx = placer_state_.move(); - const std::vector& bb = move_ctx.layer_bb_coords[net_id]; - const vtr::NdMatrixProxy net_layer_pin_sink_count = move_ctx.num_sink_pin_layer[size_t(net_id)]; + const std::vector& bb = layer_bb_coords_[net_id]; + const vtr::NdMatrixProxy net_layer_pin_sink_count = num_sink_pin_layer_[size_t(net_id)]; double ncost = 0.; VTR_ASSERT_SAFE(static_cast(bb.size()) == g_vpr_ctx.device().grid.get_num_layers()); @@ -1562,7 +1554,6 @@ void NetCostHandler::find_affected_nets_and_update_costs(const PlaceDelayModel* void NetCostHandler::update_move_nets() { /* update net cost functions and reset flags. */ auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& place_move_ctx = placer_state_.mutable_move(); for (const ClusterNetId ts_net : ts_nets_to_update_) { ClusterNetId net_id = ts_net; @@ -1570,7 +1561,7 @@ void NetCostHandler::update_move_nets() { set_ts_bb_coord_(net_id); for (int layer_num = 0; layer_num < g_vpr_ctx.device().grid.get_num_layers(); layer_num++) { - place_move_ctx.num_sink_pin_layer[size_t(net_id)][layer_num] = ts_layer_sink_pin_count_[size_t(net_id)][layer_num]; + num_sink_pin_layer_[size_t(net_id)][layer_num] = ts_layer_sink_pin_count_[size_t(net_id)][layer_num]; } if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET) { @@ -1641,19 +1632,128 @@ double NetCostHandler::get_total_wirelength_estimate() const { } void NetCostHandler::set_ts_bb_coord_(const ClusterNetId net_id) { - auto& place_move_ctx = placer_state_.mutable_move(); if (cube_bb_) { - place_move_ctx.bb_coords[net_id] = ts_bb_coord_new_[net_id]; + bb_coords_[net_id] = ts_bb_coord_new_[net_id]; } else { - place_move_ctx.layer_bb_coords[net_id] = layer_ts_bb_coord_new_[net_id]; + layer_bb_coords_[net_id] = layer_ts_bb_coord_new_[net_id]; } } void NetCostHandler::set_ts_edge_(const ClusterNetId net_id) { - auto& place_move_ctx = placer_state_.mutable_move(); if (cube_bb_) { - place_move_ctx.bb_num_on_edges[net_id] = ts_bb_edge_new_[net_id]; + bb_num_on_edges_[net_id] = ts_bb_edge_new_[net_id]; } else { - place_move_ctx.layer_bb_num_on_edges[net_id] = layer_ts_bb_edge_new_[net_id]; + layer_bb_num_on_edges_[net_id] = layer_ts_bb_edge_new_[net_id]; + } +} + +t_bb NetCostHandler::union_2d_bb(ClusterNetId net_id) const { + t_bb merged_bb; + const std::vector& bb_vec = layer_bb_coords_[net_id]; + + // Not all 2d_bbs are valid. Thus, if one of the coordinates in the 2D_bb is not valid (equal to OPEN), + // we need to skip it. + for (const t_2D_bb& layer_bb : bb_vec) { + if (layer_bb.xmin == OPEN) { + VTR_ASSERT_DEBUG(layer_bb.xmax == OPEN); + VTR_ASSERT_DEBUG(layer_bb.ymin == OPEN); + VTR_ASSERT_DEBUG(layer_bb.ymax == OPEN); + VTR_ASSERT_DEBUG(layer_bb.layer_num == OPEN); + continue; + } + if (merged_bb.xmin == OPEN || layer_bb.xmin < merged_bb.xmin) { + merged_bb.xmin = layer_bb.xmin; + } + if (merged_bb.xmax == OPEN || layer_bb.xmax > merged_bb.xmax) { + merged_bb.xmax = layer_bb.xmax; + } + if (merged_bb.ymin == OPEN || layer_bb.ymin < merged_bb.ymin) { + merged_bb.ymin = layer_bb.ymin; + } + if (merged_bb.ymax == OPEN || layer_bb.ymax > merged_bb.ymax) { + merged_bb.ymax = layer_bb.ymax; + } + if (merged_bb.layer_min == OPEN || layer_bb.layer_num < merged_bb.layer_min) { + merged_bb.layer_min = layer_bb.layer_num; + } + if (merged_bb.layer_max == OPEN || layer_bb.layer_num > merged_bb.layer_max) { + merged_bb.layer_max = layer_bb.layer_num; + } + } + + return merged_bb; +} + +std::pair NetCostHandler::union_2d_bb_incr(ClusterNetId net_id) const { + t_bb merged_num_edge; + t_bb merged_bb; + + const std::vector& num_edge_vec = layer_bb_num_on_edges_[net_id]; + const std::vector& bb_vec = layer_bb_coords_[net_id]; + + for (const t_2D_bb& layer_bb : bb_vec) { + if (layer_bb.xmin == OPEN) { + VTR_ASSERT_SAFE(layer_bb.xmax == OPEN); + VTR_ASSERT_SAFE(layer_bb.ymin == OPEN); + VTR_ASSERT_SAFE(layer_bb.ymax == OPEN); + VTR_ASSERT_SAFE(layer_bb.layer_num == OPEN); + continue; + } + if (merged_bb.xmin == OPEN || layer_bb.xmin <= merged_bb.xmin) { + if (layer_bb.xmin == merged_bb.xmin) { + VTR_ASSERT_SAFE(merged_num_edge.xmin != OPEN); + merged_num_edge.xmin += num_edge_vec[layer_bb.layer_num].xmin; + } else { + merged_num_edge.xmin = num_edge_vec[layer_bb.layer_num].xmin; + } + merged_bb.xmin = layer_bb.xmin; + } + if (merged_bb.xmax == OPEN || layer_bb.xmax >= merged_bb.xmax) { + if (layer_bb.xmax == merged_bb.xmax) { + VTR_ASSERT_SAFE(merged_num_edge.xmax != OPEN); + merged_num_edge.xmax += num_edge_vec[layer_bb.layer_num].xmax; + } else { + merged_num_edge.xmax = num_edge_vec[layer_bb.layer_num].xmax; + } + merged_bb.xmax = layer_bb.xmax; + } + if (merged_bb.ymin == OPEN || layer_bb.ymin <= merged_bb.ymin) { + if (layer_bb.ymin == merged_bb.ymin) { + VTR_ASSERT_SAFE(merged_num_edge.ymin != OPEN); + merged_num_edge.ymin += num_edge_vec[layer_bb.layer_num].ymin; + } else { + merged_num_edge.ymin = num_edge_vec[layer_bb.layer_num].ymin; + } + merged_bb.ymin = layer_bb.ymin; + } + if (merged_bb.ymax == OPEN || layer_bb.ymax >= merged_bb.ymax) { + if (layer_bb.ymax == merged_bb.ymax) { + VTR_ASSERT_SAFE(merged_num_edge.ymax != OPEN); + merged_num_edge.ymax += num_edge_vec[layer_bb.layer_num].ymax; + } else { + merged_num_edge.ymax = num_edge_vec[layer_bb.layer_num].ymax; + } + merged_bb.ymax = layer_bb.ymax; + } + if (merged_bb.layer_min == OPEN || layer_bb.layer_num <= merged_bb.layer_min) { + if (layer_bb.layer_num == merged_bb.layer_min) { + VTR_ASSERT_SAFE(merged_num_edge.layer_min != OPEN); + merged_num_edge.layer_min += num_edge_vec[layer_bb.layer_num].layer_num; + } else { + merged_num_edge.layer_min = num_edge_vec[layer_bb.layer_num].layer_num; + } + merged_bb.layer_min = layer_bb.layer_num; + } + if (merged_bb.layer_max == OPEN || layer_bb.layer_num >= merged_bb.layer_max) { + if (layer_bb.layer_num == merged_bb.layer_max) { + VTR_ASSERT_SAFE(merged_num_edge.layer_max != OPEN); + merged_num_edge.layer_max += num_edge_vec[layer_bb.layer_num].layer_num; + } else { + merged_num_edge.layer_max = num_edge_vec[layer_bb.layer_num].layer_num; + } + merged_bb.layer_max = layer_bb.layer_num; + } } + + return std::make_pair(merged_num_edge, merged_bb); } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 99bda916575..ee60d5ed348 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -154,12 +154,20 @@ class NetCostHandler { }; /** - * @brief The wire length estimation is based on the bounding box of the net. In the case of the 2D architecture, - * we use a 3D BB with the z-dimension (layer) set to 1. In the case of 3D architecture, there 2 types of bounding box: - * 3D and per-layer. The type is determined at the beginning of the placement and stored in the placement context. - * If the bonding box is of the type 3D, ts_bb_coord_new and ts_bb_edge_new are used. Otherwise, layer_ts_bb_edge_new and - * layer_ts_bb_coord_new are used. + * @brief The wire length estimation is based on the bounding box of the net. + * + * For 2D architectures, we use a 3D bounding box with the layer (z) set to 1. + * For 3D architectures, we support two types: full 3D and per-layer bounding boxes. + * The type is set at the start of placement and stored in the placement context. + * + * If using full 3D, `ts_bb_coord_new_` and `ts_bb_edge_new_` are used. + * If using per-layer, `layer_ts_bb_coord_new_` and `layer_ts_bb_edge_new_` are used. + * + * Temporary `ts_*` data members store the bounding box updates for nets affected by a move. + * If the move is accepted, these updates are copied to the permanent data members that store + * bounding box information for all nets. */ + /* [0...cluster_ctx.clb_nlist.nets().size()-1] -> 3D bounding box*/ vtr::vector ts_bb_coord_new_, ts_bb_edge_new_; /* [0...cluster_ctx.clb_nlist.nets().size()-1][0...num_layers-1] -> 2D bonding box on a layer*/ @@ -169,6 +177,21 @@ class NetCostHandler { /* [0...num_affected_nets] -> net_id of the affected nets */ std::vector ts_nets_to_update_; + // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each of a net's bounding box (to allow efficient updates) + vtr::vector bb_num_on_edges_; + + // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates of a net's bounding box + vtr::vector bb_coords_; + + // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each of a net's bounding box (to allow efficient updates) + vtr::vector> layer_bb_num_on_edges_; + + // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates of a net's bounding box + vtr::vector> layer_bb_coords_; + + // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each layer () + vtr::Matrix num_sink_pin_layer_; + /** * @brief In each of these vectors, there is one entry per cluster level net: * [0...cluster_ctx.clb_nlist.nets().size()-1]. @@ -327,14 +350,9 @@ class NetCostHandler { * It updates both the coordinate and number of pins on each edge information. It should only be called when the bounding box * information is not valid. * @param net_id ID of the net which the moving pin belongs to - * @param coords Bounding box coordinates of the net. It is calculated in this function - * @param num_on_edges Net's number of blocks on the edges of the bounding box. It is calculated in this function. - * @param num_sink_pin_layer Net's number of sinks on each layer, calculated in this function. + * @param use_ts Specifies whether the `ts` bounding box is updated or the actual one. */ - void get_bb_from_scratch_(ClusterNetId net_id, - t_bb& coords, - t_bb& num_on_edges, - vtr::NdMatrixProxy num_sink_pin_layer); + void get_bb_from_scratch_(ClusterNetId net_id, bool use_ts); /** * @brief Calculate the per-layer BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. @@ -557,4 +575,24 @@ class NetCostHandler { * @return Wirelength estimate of the net */ double get_net_wirelength_from_layer_bb_(ClusterNetId net_id) const; + + // Bounding-box getters + public: + inline const t_bb& bb_num_on_edges(ClusterNetId net_id) const { return bb_num_on_edges_[net_id]; } + + inline const t_bb& bb_coords(ClusterNetId net_id) const { return bb_coords_[net_id]; } + + /** + * @brief Iterate over all layers and get the maximum x and y over that layers that have a valid value. set the layer min and max + * based on the layers that have a valid BB. + * @return 3D bounding box + */ + t_bb union_2d_bb(ClusterNetId net_id) const; + + /** + * @brief Iterate over all layers and get the maximum x and y over that layers that have a valid value. Create the "num_edge" in a similar way. This data structure + * stores how many blocks are on each edge of the BB. set the layer min and max based on the layers that have a valid BB. + * @return num_edge, 3D bb + */ + std::pair union_2d_bb_incr(ClusterNetId net_id) const; }; diff --git a/vpr/src/place/placer.cpp b/vpr/src/place/placer.cpp index 52f68a442e2..d850fb0144b 100644 --- a/vpr/src/place/placer.cpp +++ b/vpr/src/place/placer.cpp @@ -40,7 +40,7 @@ Placer::Placer(const Netlist<>& net_list, , pb_gpin_lookup_(pb_gpin_lookup) , netlist_pin_lookup_(netlist_pin_lookup) , costs_(placer_opts.place_algorithm, noc_opts.noc) - , placer_state_(placer_opts.place_algorithm.is_timing_driven(), cube_bb) + , placer_state_(placer_opts.place_algorithm.is_timing_driven()) , rng_(placer_opts.seed) , net_cost_handler_(placer_opts, placer_state_, cube_bb) , place_delay_model_(std::move(place_delay_model)) @@ -83,7 +83,12 @@ Placer::Placer(const Netlist<>& net_list, const int move_lim = (int)(placer_opts.anneal_sched.inner_num * pow(net_list.blocks().size(), 1.3333)); //create the move generator based on the chosen placement strategy - auto [move_generator, move_generator2] = create_move_generators(placer_state_, place_macros, placer_opts, move_lim, noc_opts.noc_centroid_weight, rng_); + auto [move_generator, move_generator2] = create_move_generators(placer_state_, + place_macros, + net_cost_handler_, + placer_opts, move_lim, + noc_opts.noc_centroid_weight, + rng_); if (!placer_opts.write_initial_place_file.empty()) { print_place(nullptr, nullptr, placer_opts.write_initial_place_file.c_str(), placer_state_.block_locs()); diff --git a/vpr/src/place/placer_state.cpp b/vpr/src/place/placer_state.cpp index d85572f6d9c..c0bba0052be 100644 --- a/vpr/src/place/placer_state.cpp +++ b/vpr/src/place/placer_state.cpp @@ -4,29 +4,6 @@ #include "globals.h" #include "move_transactions.h" -PlacerMoveContext::PlacerMoveContext(bool cube_bb) { - const auto& device_ctx = g_vpr_ctx.device(); - const auto& cluster_ctx = g_vpr_ctx.clustering(); - - const size_t num_nets = cluster_ctx.clb_nlist.nets().size(); - - const int num_layers = device_ctx.grid.get_num_layers(); - - if (cube_bb) { - bb_coords.resize(num_nets, t_bb()); - bb_num_on_edges.resize(num_nets, t_bb()); - } else { - layer_bb_num_on_edges.resize(num_nets, std::vector(num_layers, t_2D_bb())); - layer_bb_coords.resize(num_nets, std::vector(num_layers, t_2D_bb())); - } - - num_sink_pin_layer.resize({num_nets, size_t(num_layers)}); - for (size_t flat_idx = 0; flat_idx < num_sink_pin_layer.size(); flat_idx++) { - int& elem = num_sink_pin_layer.get(flat_idx); - elem = OPEN; - } -} - PlacerTimingContext::PlacerTimingContext(bool placement_is_timing_driven) { const auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -94,6 +71,5 @@ void PlacerTimingContext::revert_td_cost(const t_pl_blocks_to_be_moved& blocks_a #endif } -PlacerState::PlacerState(bool placement_is_timing_driven, bool cube_bb) - : timing_(placement_is_timing_driven) - , move_(cube_bb) {} +PlacerState::PlacerState(bool placement_is_timing_driven) + : timing_(placement_is_timing_driven) {} diff --git a/vpr/src/place/placer_state.h b/vpr/src/place/placer_state.h index 9e8d9ee0ca3..10592ebcfca 100644 --- a/vpr/src/place/placer_state.h +++ b/vpr/src/place/placer_state.h @@ -111,42 +111,6 @@ struct PlacerRuntimeContext : public Context { float f_update_td_costs_total_elapsed_sec; }; -/** - * @brief Placement Move generators data - */ -struct PlacerMoveContext : public Context { - public: - PlacerMoveContext() = delete; - explicit PlacerMoveContext(bool cube_bb); - - public: - // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each of a net's bounding box (to allow efficient updates) - vtr::vector bb_num_on_edges; - - // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates of a net's bounding box - vtr::vector bb_coords; - - // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each of a net's bounding box (to allow efficient updates) - vtr::vector> layer_bb_num_on_edges; - - // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates of a net's bounding box - vtr::vector> layer_bb_coords; - - // [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the number of blocks on each layer () - vtr::Matrix num_sink_pin_layer; - - // The first range limit calculated by the annealer - float first_rlim; - - // Scratch vectors that are used by different directed moves for temporary calculations - // These vectors will grow up with the net size as it is mostly used to save coords of the net pins or net bb edges - // Given that placement moves involve operations on each coordinate independently, we chose to - // utilize a Struct of Arrays (SoA) rather than an Array of Struct (AoS). - std::vector X_coord; - std::vector Y_coord; - std::vector layer_coord; -}; - /** * @brief This object encapsulates VPR placer's state. * @@ -162,7 +126,7 @@ struct PlacerMoveContext : public Context { */ class PlacerState : public Context { public: - PlacerState(bool placement_is_timing_driven, bool cube_bb); + PlacerState(bool placement_is_timing_driven); public: inline const PlacerTimingContext& timing() const { return timing_; } @@ -171,9 +135,6 @@ class PlacerState : public Context { inline const PlacerRuntimeContext& runtime() const { return runtime_; } inline PlacerRuntimeContext& mutable_runtime() { return runtime_; } - inline const PlacerMoveContext& move() const { return move_; } - inline PlacerMoveContext& mutable_move() { return move_; } - inline const vtr::vector_map& block_locs() const { return blk_loc_registry_.block_locs(); } inline vtr::vector_map& mutable_block_locs() { return blk_loc_registry_.mutable_block_locs(); } @@ -189,7 +150,6 @@ class PlacerState : public Context { private: PlacerTimingContext timing_; PlacerRuntimeContext runtime_; - PlacerMoveContext move_; /** * @brief Contains: 1) The location where each clustered block is placed at.