From 4927620e5f0080eec4df2b79b4e039653976a0e5 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 14:35:14 -0400 Subject: [PATCH 01/36] create NetCostHandler class --- vpr/src/place/net_cost_handler.cpp | 328 ++++++++++++----------------- vpr/src/place/net_cost_handler.h | 188 ++++++++++++----- vpr/src/place/place.cpp | 80 +++---- 3 files changed, 313 insertions(+), 283 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 39aa79ea7bb..f64686bb3a3 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -127,32 +127,13 @@ struct TSInfo { // TSInfo(TSInfo&&) = delete; }; -/** - * @brief This class is used to hide control flows needed to distinguish 2d and 3d placement - */ -class BBUpdater { - // BBUpdater(const BBUpdater&) = delete; - // BBUpdater(BBUpdater&&) = delete; - - private: - bool m_cube_bb = false; - - public: - void init(size_t num_nets, bool cube_bb); - void get_non_updatable_bb(const ClusterNetId& net); - void update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver); - double get_net_cost(const ClusterNetId net_id); - void set_ts_bb_coord(const ClusterNetId net_id); - void set_ts_edge(const ClusterNetId net_id); -}; + } // namespace static struct PLNetCost pl_net_cost; static struct TSInfo ts_info; -static BBUpdater bb_updater; - static std::optional> placer_ctx_ref; void set_net_handlers_placer_ctx(PlacerContext& placer_ctx) { @@ -166,19 +147,7 @@ void set_net_handlers_placer_ctx(PlacerContext& placer_ctx) { */ static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks); -/** - * @brief Update the bounding box (3D) of the net connected to blk_pin. The old and new locations of the pin are - * stored in pl_moved_block. The updated bounding box will be stored in ts data structures. Do not update the net - * cost here since it should only be updated once per net, not once per pin. - * @param net - * @param blk - * @param blk_pin - * @param pl_moved_block - */ -static void update_net_bb(const ClusterNetId net, - const ClusterBlockId blk, - const ClusterPinId blk_pin, - const t_pl_moved_block& pl_moved_block); + /** * @brief Calculate the new connection delay and timing cost of all the @@ -206,29 +175,6 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model, */ static void record_affected_net(const ClusterNetId net); -/** - * @brief Call suitable function based on the bounding box type to update the bounding box of the net connected to pin_id. Also, - * call the function to update timing information if the placement algorithm is timing-driven. - * @param place_algorithm Placement algorithm - * @param delay_model Timing delay model used by placer - * @param criticalities Connections timing criticalities - * @param blk_id Block ID of that the moving pin belongs to. - * @param pin_id Pin ID of the moving pin - * @param moving_blk_inf Data structure that holds information, e.g., old location and new location, about all moving blocks - * @param affected_pins Netlist pins which are affected, in terms placement cost, by the proposed move. - * @param timing_delta_c Timing cost change based on the proposed move - * @param is_src_moving Is the moving pin the source of a net. - */ -static void update_net_info_on_pin_move(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - const ClusterBlockId blk_id, - const ClusterPinId pin_id, - const t_pl_moved_block& moving_blk_inf, - std::vector& affected_pins, - double& timing_delta_c, - bool is_src_moving); - /** * @brief Update the 3D bounding box of "net_id" incrementally based on the old and new locations of a pin on that net * @details Updates the bounding box of a net by storing its coordinates in the bb_coord_new data structure and the @@ -476,96 +422,9 @@ static double recompute_bb_cost(); */ static double wirelength_crossing_count(size_t fanout); -/** - * @brief Calculates and returns the total bb (wirelength) cost change that would result from moving the blocks - * indicated in the blocks_affected data structure. - * @param bb_delta_c Cost difference after and before moving the block - */ -static void set_bb_delta_cost(double& bb_delta_c); -/******************************* End of Function definitions ************************************/ -namespace { -// Initialize the ts vectors -void BBUpdater::init(size_t num_nets, bool cube_bb) { - const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); - m_cube_bb = cube_bb; - // Either 3D BB or per layer BB data structure are used, not both. - if (m_cube_bb) { - ts_info.ts_bb_edge_new.resize(num_nets, t_bb()); - ts_info.ts_bb_coord_new.resize(num_nets, t_bb()); - } else { - ts_info.layer_ts_bb_edge_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); - ts_info.layer_ts_bb_coord_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); - } - - /* This initializes the whole matrix to OPEN which is an invalid value*/ - ts_info.ts_layer_sink_pin_count.resize({num_nets, size_t(num_layers)}, OPEN); - - ts_info.ts_nets_to_update.resize(num_nets, ClusterNetId::INVALID()); -} - -void BBUpdater::get_non_updatable_bb(const ClusterNetId& net) { - if (m_cube_bb) { - ::get_non_updatable_bb(net, - ts_info.ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); - } - else { - ::get_non_updatable_layer_bb(net, - ts_info.layer_ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); - } -} - -void BBUpdater::update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { - if (m_cube_bb) { - ::update_bb(net_id, - ts_info.ts_bb_edge_new[net_id], - ts_info.ts_bb_coord_new[net_id], - ts_info.ts_layer_sink_pin_count[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); - } - else { - ::update_layer_bb(net_id, - ts_info.layer_ts_bb_edge_new[net_id], - ts_info.layer_ts_bb_coord_new[net_id], - ts_info.ts_layer_sink_pin_count[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); - } -} - -double BBUpdater::get_net_cost(const ClusterNetId net_id) { - if (m_cube_bb) { - return ::get_net_cost(net_id, ts_info.ts_bb_coord_new[net_id]); - } - else { - return ::get_net_layer_bb_wire_cost(net_id, ts_info.layer_ts_bb_coord_new[net_id], ts_info.ts_layer_sink_pin_count[size_t(net_id)]); - } -} - -void BBUpdater::set_ts_bb_coord(const ClusterNetId net_id) { - auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); - if (m_cube_bb) { - place_move_ctx.bb_coords[net_id] = ts_info.ts_bb_coord_new[net_id]; - } else { - place_move_ctx.layer_bb_coords[net_id] = ts_info.layer_ts_bb_coord_new[net_id]; - } -} - -void BBUpdater::set_ts_edge(const ClusterNetId net_id) { - auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); - if (m_cube_bb) { - place_move_ctx.bb_num_on_edges[net_id] = ts_info.ts_bb_edge_new[net_id]; - } else { - place_move_ctx.layer_bb_num_on_edges[net_id] = ts_info.layer_ts_bb_edge_new[net_id]; - } -} -} // namespace +/******************************* End of Function definitions ************************************/ //Returns true if 'net' is driven by one of the blocks in 'blocks_affected' static bool driven_by_moved_block(const ClusterNetId net, @@ -584,10 +443,10 @@ static bool driven_by_moved_block(const ClusterNetId net, return is_driven_by_move_blk; } -static void update_net_bb(const ClusterNetId net, - const ClusterBlockId blk, - const ClusterPinId blk_pin, - const t_pl_moved_block& pl_moved_block) { +void NetCostHandler::update_net_bb_(const ClusterNetId net, + const ClusterBlockId blk, + const ClusterPinId blk_pin, + const t_pl_moved_block& pl_moved_block) { const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& placer_ctx = placer_ctx_ref->get(); const auto& block_locs = placer_ctx.block_locs(); @@ -596,7 +455,7 @@ static void update_net_bb(const ClusterNetId net, //For small nets brute-force bounding box update is faster if (pl_net_cost.bb_update_status[net] == NetUpdateState::NOT_UPDATED_YET) { //Only once per-net - bb_updater.get_non_updatable_bb(net); + bb_updater_.get_non_updatable_bb(net); } } else { //For large nets, update bounding box incrementally @@ -609,14 +468,14 @@ static void update_net_bb(const ClusterNetId net, bool is_driver = cluster_ctx.clb_nlist.pin_type(blk_pin) == PinType::DRIVER; //Incremental bounding box update - bb_updater.update_bb(net, - {pl_moved_block.old_loc.x + pin_width_offset, - pl_moved_block.old_loc.y + pin_height_offset, - pl_moved_block.old_loc.layer}, - {pl_moved_block.new_loc.x + pin_width_offset, - pl_moved_block.new_loc.y + pin_height_offset, - pl_moved_block.new_loc.layer}, - is_driver); + bb_updater_.update_bb(net, + {pl_moved_block.old_loc.x + pin_width_offset, + pl_moved_block.old_loc.y + pin_height_offset, + pl_moved_block.old_loc.layer}, + {pl_moved_block.new_loc.x + pin_width_offset, + pl_moved_block.new_loc.y + pin_height_offset, + pl_moved_block.new_loc.layer}, + is_driver); } } @@ -723,22 +582,22 @@ static void record_affected_net(const ClusterNetId net) { } } -static void update_net_info_on_pin_move(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - const ClusterBlockId blk_id, - const ClusterPinId pin_id, - const t_pl_moved_block& moving_blk_inf, - std::vector& affected_pins, - double& timing_delta_c, - bool is_src_moving) { +void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place_algorithm, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + const ClusterBlockId blk_id, + const ClusterPinId pin_id, + const t_pl_moved_block& moving_blk_inf, + std::vector& affected_pins, + double& timing_delta_c, + bool is_src_moving) { const auto& cluster_ctx = g_vpr_ctx.clustering(); const ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(pin_id); VTR_ASSERT_SAFE_MSG(net_id, "Only valid nets should be found in compressed netlist block pins"); if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) { - //TODO: Do we require anyting special here for global nets? + //TODO: Do we require anything special here for global nets? //"Global nets are assumed to span the whole chip, and do not effect costs." return; } @@ -747,7 +606,7 @@ static void update_net_info_on_pin_move(const t_place_algorithm& place_algorithm record_affected_net(net_id); /* Update the net bounding boxes. */ - update_net_bb(net_id, blk_id, pin_id, moving_blk_inf); + update_net_bb_(net_id, blk_id, pin_id, moving_blk_inf); if (place_algorithm.is_timing_driven()) { /* Determine the change in connection delay and timing cost. */ @@ -1888,23 +1747,22 @@ static double wirelength_crossing_count(size_t fanout) { } } -static void set_bb_delta_cost(double& bb_delta_c) { +void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { for (const ClusterNetId ts_net: ts_info.ts_nets_to_update) { ClusterNetId net_id = ts_net; - pl_net_cost.proposed_net_cost[net_id] = bb_updater.get_net_cost(net_id); + pl_net_cost.proposed_net_cost[net_id] = bb_updater_.get_net_cost(net_id); bb_delta_c += pl_net_cost.proposed_net_cost[net_id] - pl_net_cost.net_cost[net_id]; } } -void find_affected_nets_and_update_costs( - const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - t_pl_blocks_to_be_moved& blocks_affected, - double& bb_delta_c, - double& timing_delta_c) { +void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + t_pl_blocks_to_be_moved& blocks_affected, + double& bb_delta_c, + double& timing_delta_c) { VTR_ASSERT_SAFE(bb_delta_c == 0.); VTR_ASSERT_SAFE(timing_delta_c == 0.); auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; @@ -1922,24 +1780,23 @@ void find_affected_nets_and_update_costs( bool is_src_moving = false; if (clb_nlist.pin_type(blk_pin) == PinType::SINK) { ClusterNetId net_id = clb_nlist.pin_net(blk_pin); - is_src_moving = driven_by_moved_block(net_id, - blocks_affected.moved_blocks); + is_src_moving = driven_by_moved_block(net_id, blocks_affected.moved_blocks); } - update_net_info_on_pin_move(place_algorithm, - delay_model, - criticalities, - blk, - blk_pin, - moving_block_inf, - affected_pins, - timing_delta_c, - is_src_moving); + update_net_info_on_pin_move_(place_algorithm, + delay_model, + criticalities, + blk, + blk_pin, + moving_block_inf, + affected_pins, + timing_delta_c, + is_src_moving); } } /* Now update the bounding box costs (since the net bounding * * boxes are up-to-date). The cost is only updated once per net. */ - set_bb_delta_cost(bb_delta_c); + set_bb_delta_cost_(bb_delta_c); } double comp_bb_cost(e_cost_methods method) { @@ -2020,7 +1877,7 @@ double comp_layer_bb_cost(e_cost_methods method) { return cost; } -void update_move_nets() { +void NetCostHandler::update_move_nets() { /* update net cost functions and reset flags. */ auto& cluster_ctx = g_vpr_ctx.clustering(); auto& placer_ctx = placer_ctx_ref->get(); @@ -2029,14 +1886,14 @@ void update_move_nets() { for (const ClusterNetId ts_net : ts_info.ts_nets_to_update) { ClusterNetId net_id = ts_net; - bb_updater.set_ts_bb_coord(net_id); + bb_updater_.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_info.ts_layer_sink_pin_count[size_t(net_id)][layer_num]; } if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET) { - bb_updater.set_ts_edge(net_id); + bb_updater_.set_ts_edge(net_id); } pl_net_cost.net_cost[net_id] = pl_net_cost.proposed_net_cost[net_id]; @@ -2240,10 +2097,6 @@ void free_place_move_structs() { vtr::release_memory(pl_net_cost.bb_update_status); } -void init_try_swap_net_cost_structs(size_t num_nets, bool cube_bb) { - bb_updater.init(num_nets, cube_bb); -} - void free_try_swap_net_cost_structs() { vtr::release_memory(ts_info.ts_bb_edge_new); vtr::release_memory(ts_info.ts_bb_coord_new); @@ -2252,3 +2105,86 @@ void free_try_swap_net_cost_structs() { ts_info.ts_layer_sink_pin_count.clear(); vtr::release_memory(ts_info.ts_nets_to_update); } + +NetCostHandler::NetCostHandler(size_t num_nets, bool cube_bb) + : bb_updater_(num_nets, cube_bb) {} + +NetCostHandler::BBUpdater::BBUpdater(size_t num_nets, bool cube_bb) : + cube_bb_(cube_bb) { + const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); + + // Either 3D BB or per layer BB data structure are used, not both. + if (cube_bb_) { + ts_info.ts_bb_edge_new.resize(num_nets, t_bb()); + ts_info.ts_bb_coord_new.resize(num_nets, t_bb()); + } else { + ts_info.layer_ts_bb_edge_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); + ts_info.layer_ts_bb_coord_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); + } + + /* This initializes the whole matrix to OPEN which is an invalid value*/ + ts_info.ts_layer_sink_pin_count.resize({num_nets, size_t(num_layers)}, OPEN); + + ts_info.ts_nets_to_update.resize(num_nets, ClusterNetId::INVALID()); +} + +void NetCostHandler::BBUpdater::get_non_updatable_bb(const ClusterNetId net) { + if (cube_bb_) { + ::get_non_updatable_bb(net, + ts_info.ts_bb_coord_new[net], + ts_info.ts_layer_sink_pin_count[size_t(net)]); + } + else { + ::get_non_updatable_layer_bb(net, + ts_info.layer_ts_bb_coord_new[net], + ts_info.ts_layer_sink_pin_count[size_t(net)]); + } +} + +void NetCostHandler::BBUpdater::update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { + if (cube_bb_) { + ::update_bb(net_id, + ts_info.ts_bb_edge_new[net_id], + ts_info.ts_bb_coord_new[net_id], + ts_info.ts_layer_sink_pin_count[size_t(net_id)], + pin_old_loc, + pin_new_loc, + is_driver); + } + else { + ::update_layer_bb(net_id, + ts_info.layer_ts_bb_edge_new[net_id], + ts_info.layer_ts_bb_coord_new[net_id], + ts_info.ts_layer_sink_pin_count[size_t(net_id)], + pin_old_loc, + pin_new_loc, + is_driver); + } +} + +double NetCostHandler::BBUpdater::get_net_cost(const ClusterNetId net_id) { + if (cube_bb_) { + return ::get_net_cost(net_id, ts_info.ts_bb_coord_new[net_id]); + } + else { + return ::get_net_layer_bb_wire_cost(net_id, ts_info.layer_ts_bb_coord_new[net_id], ts_info.ts_layer_sink_pin_count[size_t(net_id)]); + } +} + +void NetCostHandler::BBUpdater::set_ts_bb_coord(const ClusterNetId net_id) { + auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); + if (cube_bb_) { + place_move_ctx.bb_coords[net_id] = ts_info.ts_bb_coord_new[net_id]; + } else { + place_move_ctx.layer_bb_coords[net_id] = ts_info.layer_ts_bb_coord_new[net_id]; + } +} + +void NetCostHandler::BBUpdater::set_ts_edge(const ClusterNetId net_id) { + auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); + if (cube_bb_) { + place_move_ctx.bb_num_on_edges[net_id] = ts_info.ts_bb_edge_new[net_id]; + } else { + place_move_ctx.layer_bb_num_on_edges[net_id] = ts_info.layer_ts_bb_edge_new[net_id]; + } +} diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index c055a0f20c6..b8726dce2f8 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -25,43 +25,6 @@ enum class e_cost_methods { CHECK }; -/** - * @brief Find all the nets and pins affected by this swap and update costs. - * - * Find all the nets affected by this swap and update the bounding box (wiring) - * costs. This cost function doesn't depend on the timing info. - * - * Find all the connections affected by this swap and update the timing cost. - * For a connection to be affected, it not only needs to be on or driven by - * a block, but it also needs to have its delay changed. Otherwise, it will - * not be added to the affected_pins structure. - * - * For more, see update_td_delta_costs(). - * - * The timing costs are calculated by getting the new connection delays, - * multiplied by the connection criticalities returned by the timing - * analyzer. These timing costs are stored in the proposed_* data structures. - * - * The change in the bounding box cost is stored in `bb_delta_c`. - * The change in the timing cost is stored in `timing_delta_c`. - * ts_nets_to_update is also extended with the latest net. - * - * @param place_algorithm - * @param delay_model - * @param criticalities - * @param blocks_affected - * @param bb_delta_c - * @param timing_delta_c - * @return The number of affected nets. - */ -void find_affected_nets_and_update_costs( - const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - t_pl_blocks_to_be_moved& blocks_affected, - double& bb_delta_c, - double& timing_delta_c); - /** * @brief Finds the bb cost from scratch (based on 3D BB). * Done only when the placement has been radically changed @@ -89,12 +52,6 @@ double comp_bb_cost(e_cost_methods method); */ double comp_layer_bb_cost(e_cost_methods method); -/** - * @brief update net cost data structures (in placer context and net_cost in .cpp file) and reset flags (proposed_net_cost and bb_updated_before). - * @param num_nets_affected The number of nets affected by the move. It is used to determine the index up to which elements in ts_nets_to_update are valid. - */ -void update_move_nets(); - /** * @brief Reset the net cost function flags (proposed_net_cost and bb_updated_before) * @param num_nets_affected @@ -142,14 +99,7 @@ void init_place_move_structs(size_t num_nets); */ void free_place_move_structs(); -/** - * @brief Resize temporary storage data structures needed to determine which nets are affected by a move and data needed per net - * about where their terminals are in order to quickly (incrementally) update their wirelength costs. These data structures are - * (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update. - * @param num_nets Number of nets in the netlist used by the placement engine (currently clustered netlist) - * @param cube_bb True if the 3D bounding box should be used, false otherwise. - */ -void init_try_swap_net_cost_structs(size_t num_nets, bool cube_bb); + /** * @brief Free (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update data structures. @@ -157,3 +107,139 @@ void init_try_swap_net_cost_structs(size_t num_nets, bool cube_bb); void free_try_swap_net_cost_structs(); void set_net_handlers_placer_ctx(PlacerContext& placer_ctx); + + +class NetCostHandler { + public: + NetCostHandler() = delete; + NetCostHandler(const NetCostHandler&) = delete; + NetCostHandler(NetCostHandler&&) = delete; + NetCostHandler& operator=(const NetCostHandler&) = delete; + NetCostHandler& operator=(NetCostHandler&&) = delete; + + /** + * @brief Resize temporary swap data structures needed to determine which nets are affected by a move and data needed per net + * about where their terminals are in order to quickly (incrementally) update their wirelength costs. These data structures are + * (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update. + * @param num_nets Number of nets in the netlist used by the placement engine (currently clustered netlist) + * @param cube_bb True if the 3D bounding box should be used, false otherwise. + */ + NetCostHandler(size_t num_nets, bool cube_bb); + + /** + * @brief Find all the nets and pins affected by this swap and update costs. + * + * Find all the nets affected by this swap and update the bounding box (wiring) + * costs. This cost function doesn't depend on the timing info. + * + * Find all the connections affected by this swap and update the timing cost. + * For a connection to be affected, it not only needs to be on or driven by + * a block, but it also needs to have its delay changed. Otherwise, it will + * not be added to the affected_pins structure. + * + * For more, see update_td_delta_costs(). + * + * The timing costs are calculated by getting the new connection delays, + * multiplied by the connection criticalities returned by the timing + * analyzer. These timing costs are stored in the proposed_* data structures. + * + * The change in the bounding box cost is stored in `bb_delta_c`. + * The change in the timing cost is stored in `timing_delta_c`. + * ts_nets_to_update is also extended with the latest net. + * + * @param place_algorithm + * @param delay_model + * @param criticalities + * @param blocks_affected + * @param bb_delta_c + * @param timing_delta_c + * @return The number of affected nets. + */ + void find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + t_pl_blocks_to_be_moved& blocks_affected, + double& bb_delta_c, + double& timing_delta_c); + + /** + * @brief update net cost data structures (in placer context and net_cost in .cpp file) and reset flags (proposed_net_cost and bb_updated_before). + * @param num_nets_affected The number of nets affected by the move. It is used to determine the index up to which elements in ts_nets_to_update are valid. + */ + void update_move_nets(); + + private: + /** + * @brief This class is used to hide control flows needed to distinguish 2d and 3d placement + */ + class BBUpdater { + public: + BBUpdater() = delete; + BBUpdater(const BBUpdater&) = delete; + BBUpdater(BBUpdater&&) = delete; + BBUpdater& operator=(const BBUpdater&) = delete; + BBUpdater& operator=(BBUpdater&&) = delete; + + BBUpdater(size_t num_nets, bool cube_bb); + + private: + bool cube_bb_ = false; + + public: + + void get_non_updatable_bb(const ClusterNetId net); + + void update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver); + + double get_net_cost(const ClusterNetId net_id); + + void set_ts_bb_coord(const ClusterNetId net_id); + + void set_ts_edge(const ClusterNetId net_id); + }; + + private: + BBUpdater bb_updater_; + + private: + /** + * @brief Update the bounding box (3D) of the net connected to blk_pin. The old and new locations of the pin are + * stored in pl_moved_block. The updated bounding box will be stored in ts data structures. Do not update the net + * cost here since it should only be updated once per net, not once per pin. + */ + void update_net_bb_(const ClusterNetId net, + const ClusterBlockId blk, + const ClusterPinId blk_pin, + const t_pl_moved_block& pl_moved_block); + + /** + * @brief Call suitable function based on the bounding box type to update the bounding box of the net connected to pin_id. Also, + * call the function to update timing information if the placement algorithm is timing-driven. + * @param place_algorithm Placement algorithm + * @param delay_model Timing delay model used by placer + * @param criticalities Connections timing criticalities + * @param blk_id Block ID of that the moving pin belongs to. + * @param pin_id Pin ID of the moving pin + * @param moving_blk_inf Data structure that holds information, e.g., old location and new location, about all moving blocks + * @param affected_pins Netlist pins which are affected, in terms placement cost, by the proposed move. + * @param timing_delta_c Timing cost change based on the proposed move + * @param is_src_moving Is the moving pin the source of a net. + */ + void update_net_info_on_pin_move_(const t_place_algorithm& place_algorithm, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + const ClusterBlockId blk_id, + const ClusterPinId pin_id, + const t_pl_moved_block& moving_blk_inf, + std::vector& affected_pins, + double& timing_delta_c, + bool is_src_moving); + + /** + * @brief Calculates and returns the total bb (wirelength) cost change that would result from moving the blocks + * indicated in the blocks_affected data structure. + * @param bb_delta_c Cost difference after and before moving the block + */ + void set_bb_delta_cost_(double& bb_delta_c); + +}; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 31598ad314d..d2fcb076bec 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -188,14 +188,14 @@ void print_clb_placement(const char* fname); static bool is_cube_bb(const e_place_bounding_box_mode place_bb_mode, const RRGraphView& rr_graph); -static void alloc_and_load_placement_structs(float place_cost_exp, - const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, - t_direct_inf* directs, - int num_directs, - PlacerContext& placer_ctx); - -static void alloc_and_load_try_swap_structs(const bool cube_bb); +static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, + const t_placer_opts& placer_opts, + const t_noc_opts& noc_opts, + t_direct_inf* directs, + int num_directs, + PlacerContext& placer_ctx); + +static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb); static void free_try_swap_structs(); static void free_placement_structs(const t_placer_opts& placer_opts, @@ -219,7 +219,8 @@ static e_move_result try_swap(const t_annealing_state* state, float timing_bb_factor, bool manual_move_enabled, t_swap_stats& swap_stats, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static void check_place(const t_placer_costs& costs, const PlaceDelayModel* delay_model, @@ -253,7 +254,8 @@ static float starting_t(const t_annealing_state* state, const t_noc_opts& noc_opts, MoveTypeStat& move_type_stat, t_swap_stats& swap_stats, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static int count_connections(); @@ -311,7 +313,8 @@ static void placement_inner_loop(const t_annealing_state* state, MoveTypeStat& move_type_stat, float timing_bb_factor, t_swap_stats& swap_stats, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static void generate_post_place_timing_reports(const t_placer_opts& placer_opts, const t_analysis_opts& analysis_opts, @@ -443,7 +446,8 @@ void try_place(const Netlist<>& net_list, const auto& p_runtime_ctx = placer_ctx.runtime(); - alloc_and_load_placement_structs(placer_opts.place_cost_exp, placer_opts, noc_opts, directs, num_directs, placer_ctx); + NetCostHandler net_cost_handler = alloc_and_load_placement_structs(placer_opts.place_cost_exp, placer_opts, + noc_opts, directs, num_directs, placer_ctx); set_net_handlers_placer_ctx(placer_ctx); std::unique_ptr manual_move_generator = std::make_unique(placer_ctx); @@ -706,7 +710,7 @@ void try_place(const Netlist<>& net_list, placer_setup_slacks.get(), timing_info.get(), *move_generator, *manual_move_generator, pin_timing_invalidator.get(), blocks_affected, placer_opts, noc_opts, move_type_stat, - swap_stats, placer_ctx); + swap_stats, placer_ctx, net_cost_handler); if (!placer_opts.move_stats_file.empty()) { f_move_stats_file = std::unique_ptr( @@ -780,7 +784,7 @@ void try_place(const Netlist<>& net_list, blocks_affected, timing_info.get(), placer_opts.place_algorithm, move_type_stat, timing_bb_factor, - swap_stats, placer_ctx); + swap_stats, placer_ctx, net_cost_handler); //move the update used move_generator to its original variable update_move_generator(move_generator, move_generator2, agent_state, @@ -847,7 +851,7 @@ void try_place(const Netlist<>& net_list, blocks_affected, timing_info.get(), placer_opts.place_quench_algorithm, move_type_stat, timing_bb_factor, - swap_stats, placer_ctx); + swap_stats, placer_ctx, net_cost_handler); //move the update used move_generator to its original variable update_move_generator(move_generator, move_generator2, agent_state, @@ -1057,7 +1061,8 @@ static void placement_inner_loop(const t_annealing_state* state, MoveTypeStat& move_type_stat, float timing_bb_factor, t_swap_stats& swap_stats, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { //How many times have we dumped placement to a file this temperature? int inner_placement_save_count = 0; @@ -1071,7 +1076,8 @@ static void placement_inner_loop(const t_annealing_state* state, manual_move_generator, timing_info, pin_timing_invalidator, blocks_affected, delay_model, criticalities, setup_slacks, placer_opts, noc_opts, move_type_stat, place_algorithm, - timing_bb_factor, manual_move_enabled, swap_stats, placer_ctx); + timing_bb_factor, manual_move_enabled, swap_stats, + placer_ctx, net_cost_handler); if (swap_result == ACCEPTED) { /* Move was accepted. Update statistics that are useful for the annealing schedule. */ @@ -1169,7 +1175,8 @@ static float starting_t(const t_annealing_state* state, const t_noc_opts& noc_opts, MoveTypeStat& move_type_stat, t_swap_stats& swap_stats, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { if (annealing_sched.type == USER_SCHED) { return (annealing_sched.init_t); } @@ -1202,7 +1209,8 @@ static float starting_t(const t_annealing_state* state, manual_move_generator, timing_info, pin_timing_invalidator, blocks_affected, delay_model, criticalities, setup_slacks, placer_opts, noc_opts, move_type_stat, placer_opts.place_algorithm, - REWARD_BB_TIMING_RELATIVE_WEIGHT, manual_move_enabled, swap_stats, placer_ctx); + REWARD_BB_TIMING_RELATIVE_WEIGHT, manual_move_enabled, swap_stats, + placer_ctx, net_cost_handler); if (swap_result == ACCEPTED) { num_accepted++; @@ -1273,7 +1281,8 @@ static e_move_result try_swap(const t_annealing_state* state, float timing_bb_factor, bool manual_move_enabled, t_swap_stats& swap_stats, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { /* Picks some block and moves it to another spot. If this spot is * * occupied, switch the blocks. Assess the change in cost function. * * rlim is the range limiter. * @@ -1381,8 +1390,8 @@ static e_move_result try_swap(const t_annealing_state* state, // //Also find all the pins affected by the swap, and calculates new connection //delays and timing costs and store them in proposed_* data structures. - find_affected_nets_and_update_costs(place_algorithm, delay_model, criticalities, - blocks_affected, bb_delta_c, timing_delta_c); + net_cost_handler.find_affected_nets_and_update_costs(place_algorithm, delay_model, criticalities, + blocks_affected, bb_delta_c, timing_delta_c); //For setup slack analysis, we first do a timing analysis to get the newest //slack values resulted from the proposed block moves. If the move turns out @@ -1482,7 +1491,7 @@ static e_move_result try_swap(const t_annealing_state* state, } /* Update net cost functions and reset flags. */ - update_move_nets(); + net_cost_handler.update_move_nets(); /* Update clb data structures since we kept the move. */ commit_move_blocks(blocks_affected, placer_ctx.mutable_grid_blocks()); @@ -1833,12 +1842,12 @@ static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& block /* Allocates the major structures needed only by the placer, primarily for * * computing costs quickly and such. */ -static void alloc_and_load_placement_structs(float place_cost_exp, - const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, - t_direct_inf* directs, - int num_directs, - PlacerContext& placer_ctx) { +static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, + const t_placer_opts& placer_opts, + const t_noc_opts& noc_opts, + t_direct_inf* directs, + int num_directs, + PlacerContext& placer_ctx) { const auto& device_ctx = g_vpr_ctx.device(); const auto& cluster_ctx = g_vpr_ctx.clustering(); auto& place_ctx = g_vpr_ctx.mutable_placement(); @@ -1908,13 +1917,13 @@ static void alloc_and_load_placement_structs(float place_cost_exp, alloc_and_load_chan_w_factors_for_place_cost(place_cost_exp); - alloc_and_load_try_swap_structs(place_ctx.cube_bb); - place_ctx.pl_macros = alloc_and_load_placement_macros(directs, num_directs); if (noc_opts.noc) { allocate_and_load_noc_placement_structs(); } + + return alloc_and_load_try_swap_structs(place_ctx.cube_bb); } /* Frees the major structures needed by the placer (and not needed * @@ -1957,17 +1966,16 @@ static void free_placement_structs(const t_placer_opts& placer_opts, } } -static void alloc_and_load_try_swap_structs(const bool cube_bb) { +static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb) { /* Allocate the local bb_coordinate storage, etc. only once. */ /* Allocate with size cluster_ctx.clb_nlist.nets().size() for any number of nets affected. */ auto& cluster_ctx = g_vpr_ctx.clustering(); - size_t num_nets = cluster_ctx.clb_nlist.nets().size(); - - init_try_swap_net_cost_structs(num_nets, cube_bb); - auto& place_ctx = g_vpr_ctx.mutable_placement(); place_ctx.compressed_block_grids = create_compressed_block_grids(); + + size_t num_nets = cluster_ctx.clb_nlist.nets().size(); + return {num_nets, cube_bb}; } static void free_try_swap_structs() { From 5bd661276a7a56f22d4c10a661c4567e4ca7732e Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 15:23:53 -0400 Subject: [PATCH 02/36] add public methods for NetCostHandler --- vpr/src/place/net_cost_handler.cpp | 46 ++++---- vpr/src/place/net_cost_handler.h | 180 +++++++++++++---------------- vpr/src/place/place.cpp | 70 +++++------ 3 files changed, 143 insertions(+), 153 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index f64686bb3a3..b7b903c7fed 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -1799,7 +1799,7 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm set_bb_delta_cost_(bb_delta_c); } -double comp_bb_cost(e_cost_methods method) { +double NetCostHandler::comp_bb_cost(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1836,7 +1836,7 @@ double comp_bb_cost(e_cost_methods method) { return cost; } -double comp_layer_bb_cost(e_cost_methods method) { +double NetCostHandler::comp_layer_bb_cost(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1904,7 +1904,7 @@ void NetCostHandler::update_move_nets() { } } -void reset_move_nets() { +void NetCostHandler::reset_move_nets() { /* Reset the net cost function flags first. */ for (const ClusterNetId ts_net : ts_info.ts_nets_to_update) { ClusterNetId net_id = ts_net; @@ -1913,11 +1913,11 @@ void reset_move_nets() { } } -void recompute_costs_from_scratch(const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - t_placer_costs* costs) { +void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_opts, + const t_noc_opts& noc_opts, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + t_placer_costs* costs) { auto& placer_ctx = placer_ctx_ref->get(); auto check_and_print_cost = [](double new_cost, @@ -1979,7 +1979,7 @@ void recompute_costs_from_scratch(const t_placer_opts& placer_opts, } } -void alloc_and_load_chan_w_factors_for_place_cost(float place_cost_exp) { +void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp) { /* Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac * * arrays with the inverse of the average number of tracks per channel * * between [subhigh] and [sublow]. This is only useful for the cost * @@ -2077,27 +2077,18 @@ void alloc_and_load_chan_w_factors_for_place_cost(float place_cost_exp) { } } -void free_chan_w_factors_for_place_cost() { +void NetCostHandler::free_chan_w_factors_for_place_cost() { chanx_place_cost_fac.clear(); chany_place_cost_fac.clear(); } -void init_place_move_structs(size_t num_nets) { - pl_net_cost.net_cost.resize(num_nets, -1.); - pl_net_cost.proposed_net_cost.resize(num_nets, -1.); - /* Used to store costs for moves not yet made and to indicate when a net's * - * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * - * been recomputed. */ - pl_net_cost.bb_update_status.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); -} - -void free_place_move_structs() { +void NetCostHandler::free_place_move_structs() { vtr::release_memory(pl_net_cost.net_cost); vtr::release_memory(pl_net_cost.proposed_net_cost); vtr::release_memory(pl_net_cost.bb_update_status); } -void free_try_swap_net_cost_structs() { +void NetCostHandler::free_try_swap_net_cost_structs() { vtr::release_memory(ts_info.ts_bb_edge_new); vtr::release_memory(ts_info.ts_bb_coord_new); vtr::release_memory(ts_info.layer_ts_bb_edge_new); @@ -2106,8 +2097,17 @@ void free_try_swap_net_cost_structs() { vtr::release_memory(ts_info.ts_nets_to_update); } -NetCostHandler::NetCostHandler(size_t num_nets, bool cube_bb) - : bb_updater_(num_nets, cube_bb) {} +NetCostHandler::NetCostHandler(size_t num_nets, bool cube_bb, float place_cost_exp) + : bb_updater_(num_nets, cube_bb) { + pl_net_cost.net_cost.resize(num_nets, -1.); + pl_net_cost.proposed_net_cost.resize(num_nets, -1.); + /* Used to store costs for moves not yet made and to indicate when a net's * + * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * + * been recomputed. */ + pl_net_cost.bb_update_status.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); + + alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); +} NetCostHandler::BBUpdater::BBUpdater(size_t num_nets, bool cube_bb) : cube_bb_(cube_bb) { diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index b8726dce2f8..909178aa17d 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -25,87 +25,6 @@ enum class e_cost_methods { CHECK }; -/** - * @brief Finds the bb cost from scratch (based on 3D BB). - * Done only when the placement has been radically changed - * (i.e. after initial placement). Otherwise find the cost - * change incrementally. If method check is NORMAL, we find - * bounding boxes that are updatable for the larger nets. - * If method is CHECK, all bounding boxes are found via the - * non_updateable_bb routine, to provide a cost which can be - * used to check the correctness of the other routine. - * @param method - * @return The bounding box cost of the placement, computed by the 3D method. - */ -double comp_bb_cost(e_cost_methods method); - -/** - * @brief Finds the bb cost from scratch (based on per-layer BB). - * Done only when the placement has been radically changed - * (i.e. after initial placement). Otherwise find the cost change - * incrementally. If method check is NORMAL, we find bounding boxes - * that are updateable for the larger nets. If method is CHECK, all - * bounding boxes are found via the non_updateable_bb routine, to provide - * a cost which can be used to check the correctness of the other routine. - * @param method - * @return The placement bounding box cost, computed by the per layer method. - */ -double comp_layer_bb_cost(e_cost_methods method); - -/** - * @brief Reset the net cost function flags (proposed_net_cost and bb_updated_before) - * @param num_nets_affected - */ -void reset_move_nets(); - -/** - * @brief re-calculates different terms of the cost function (wire-length, timing, NoC) and update "costs" accordingly. It is important to note that - * in this function bounding box and connection delays are not calculated from scratch. However, it iterates over all nets and connections and updates - * their costs by a complete summation, rather than incrementally. - * @param placer_opts - * @param noc_opts - * @param delay_model - * @param criticalities - * @param costs passed by reference and computed by this routine (i.e. returned by reference) - */ -void recompute_costs_from_scratch(const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, - const PlaceDelayModel* delay_model, - const PlacerCriticalities* criticalities, - t_placer_costs* costs); - -/** - * @brief Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac - * arrays with the inverse of the average number of tracks per channel - * between [subhigh] and [sublow]. - * @param place_cost_exp It is an exponent to which you take the average inverse channel - * capacity; a higher value would favour wider channels more over narrower channels during placement (usually we use 1). - */ -void alloc_and_load_chan_w_factors_for_place_cost(float place_cost_exp); - -/** - * @brief Frees the chanx_place_cost_fac and chany_place_cost_fac arrays. - */ -void free_chan_w_factors_for_place_cost(); - -/** - * @brief Resize net_cost, proposed_net_cost, and bb_updated_before data structures to accommodate all nets. - * @param num_nets Number of nets in the netlist (clustered currently) that the placement engine uses. - */ -void init_place_move_structs(size_t num_nets); - -/** - * @brief Free net_cost, proposed_net_cost, and bb_updated_before data structures. - */ -void free_place_move_structs(); - - - -/** - * @brief Free (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update data structures. - */ -void free_try_swap_net_cost_structs(); - void set_net_handlers_placer_ctx(PlacerContext& placer_ctx); @@ -118,13 +37,14 @@ class NetCostHandler { NetCostHandler& operator=(NetCostHandler&&) = delete; /** - * @brief Resize temporary swap data structures needed to determine which nets are affected by a move and data needed per net - * about where their terminals are in order to quickly (incrementally) update their wirelength costs. These data structures are - * (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update. - * @param num_nets Number of nets in the netlist used by the placement engine (currently clustered netlist) - * @param cube_bb True if the 3D bounding box should be used, false otherwise. - */ - NetCostHandler(size_t num_nets, bool cube_bb); + * @brief Resize temporary swap data structures needed to determine which nets are affected by a move and data needed per net + * about where their terminals are in order to quickly (incrementally) update their wirelength costs. These data structures are + * (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update. + * @param num_nets Number of nets in the netlist used by the placement engine (currently clustered netlist) + * @param cube_bb True if the 3D bounding box should be used, false otherwise. + * @param place_cost_exp It is an exponent to which you take the average inverse channel + */ + NetCostHandler(size_t num_nets, bool cube_bb, float place_cost_exp); /** * @brief Find all the nets and pins affected by this swap and update costs. @@ -147,12 +67,6 @@ class NetCostHandler { * The change in the timing cost is stored in `timing_delta_c`. * ts_nets_to_update is also extended with the latest net. * - * @param place_algorithm - * @param delay_model - * @param criticalities - * @param blocks_affected - * @param bb_delta_c - * @param timing_delta_c * @return The number of affected nets. */ void find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm, @@ -163,11 +77,74 @@ class NetCostHandler { double& timing_delta_c); /** - * @brief update net cost data structures (in placer context and net_cost in .cpp file) and reset flags (proposed_net_cost and bb_updated_before). - * @param num_nets_affected The number of nets affected by the move. It is used to determine the index up to which elements in ts_nets_to_update are valid. - */ + * @brief Finds the bb cost from scratch (based on 3D BB). + * Done only when the placement has been radically changed + * (i.e. after initial placement). Otherwise find the cost + * change incrementally. If method check is NORMAL, we find + * bounding boxes that are updatable for the larger nets. + * If method is CHECK, all bounding boxes are found via the + * non_updateable_bb routine, to provide a cost which can be + * used to check the correctness of the other routine. + * @param method The method used to calculate placement cost. + * @return The bounding box cost of the placement, computed by the 3D method. + */ + double comp_bb_cost(e_cost_methods method); + + /** + * @brief Finds the bb cost from scratch (based on per-layer BB). + * Done only when the placement has been radically changed + * (i.e. after initial placement). Otherwise find the cost change + * incrementally. If method check is NORMAL, we find bounding boxes + * that are updateable for the larger nets. If method is CHECK, all + * bounding boxes are found via the non_updateable_bb routine, to provide + * a cost which can be used to check the correctness of the other routine. + * @param method The method used to calculate placement cost. + * @return The placement bounding box cost, computed by the per layer method. + */ + double comp_layer_bb_cost(e_cost_methods method); + + /** + * @brief Reset the net cost function flags (proposed_net_cost and bb_updated_before) + */ + void reset_move_nets(); + + /** + * @brief update net cost data structures (in placer context and net_cost in .cpp file) and reset flags (proposed_net_cost and bb_updated_before). + * @param num_nets_affected The number of nets affected by the move. It is used to determine the index up to which elements in ts_nets_to_update are valid. + */ void update_move_nets(); + /** + * @brief re-calculates different terms of the cost function (wire-length, timing, NoC) and update "costs" accordingly. It is important to note that + * in this function bounding box and connection delays are not calculated from scratch. However, it iterates over all nets and connections and updates + * their costs by a complete summation, rather than incrementally. + * @param placer_opts + * @param noc_opts + * @param delay_model + * @param criticalities + * @param costs passed by reference and computed by this routine (i.e. returned by reference) + */ + void recompute_costs_from_scratch(const t_placer_opts& placer_opts, + const t_noc_opts& noc_opts, + const PlaceDelayModel* delay_model, + const PlacerCriticalities* criticalities, + t_placer_costs* costs); + + /** + * @brief Frees the chanx_place_cost_fac and chany_place_cost_fac arrays. + */ + void free_chan_w_factors_for_place_cost(); + + /** + * @brief Free net_cost, proposed_net_cost, and bb_updated_before data structures. + */ + void free_place_move_structs(); + + /** + * @brief Free (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update data structures. + */ + void free_try_swap_net_cost_structs(); + private: /** * @brief This class is used to hide control flows needed to distinguish 2d and 3d placement @@ -242,4 +219,13 @@ class NetCostHandler { */ void set_bb_delta_cost_(double& bb_delta_c); + /** + * @brief Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac + * arrays with the inverse of the average number of tracks per channel + * between [subhigh] and [sublow]. + * @param place_cost_exp It is an exponent to which you take the average inverse channel + * capacity; a higher value would favour wider channels more over narrower channels during placement (usually we use 1). + */ + void alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp); + }; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index d2fcb076bec..05d086d3ea1 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -195,12 +195,13 @@ static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, int num_directs, PlacerContext& placer_ctx); -static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb); -static void free_try_swap_structs(); +static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb, float place_cost_exp); +static void free_try_swap_structs(NetCostHandler& net_cost_handler); static void free_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static e_move_result try_swap(const t_annealing_state* state, t_placer_costs* costs, @@ -227,13 +228,15 @@ static void check_place(const t_placer_costs& costs, const PlacerCriticalities* criticalities, const t_place_algorithm& place_algorithm, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static int check_placement_costs(const t_placer_costs& costs, const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, const t_place_algorithm& place_algorithm, - PlacerContext& placer_ctx); + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler); static int check_placement_consistency(const BlkLocRegistry& blk_loc_registry); static int check_block_placement_consistency(const BlkLocRegistry& blk_loc_registry); @@ -497,10 +500,10 @@ void try_place(const Netlist<>& net_list, if (placer_opts.place_algorithm.is_timing_driven()) { if (cube_bb) { - costs.bb_cost = comp_bb_cost(e_cost_methods::NORMAL); + costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); } else { VTR_ASSERT_SAFE(!cube_bb); - costs.bb_cost = comp_layer_bb_cost(e_cost_methods::NORMAL); + costs.bb_cost = net_cost_handler.comp_layer_bb_cost(e_cost_methods::NORMAL); } first_crit_exponent = placer_opts.td_place_exp_first; /*this will be modified when rlim starts to change */ @@ -578,10 +581,10 @@ void try_place(const Netlist<>& net_list, /* Total cost is the same as wirelength cost normalized*/ if (cube_bb) { - costs.bb_cost = comp_bb_cost(e_cost_methods::NORMAL); + costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); } else { VTR_ASSERT_SAFE(!cube_bb); - costs.bb_cost = comp_layer_bb_cost(e_cost_methods::NORMAL); + costs.bb_cost = net_cost_handler.comp_layer_bb_cost(e_cost_methods::NORMAL); } costs.bb_cost_norm = 1 / costs.bb_cost; @@ -614,7 +617,8 @@ void try_place(const Netlist<>& net_list, placer_criticalities.get(), placer_opts.place_algorithm, noc_opts, - placer_ctx); + placer_ctx, + net_cost_handler); //Initial placement statistics VTR_LOG("Initial placement cost: %g bb_cost: %g td_cost: %g\n", costs.cost, @@ -918,7 +922,8 @@ void try_place(const Netlist<>& net_list, placer_criticalities.get(), placer_opts.place_algorithm, noc_opts, - placer_ctx); + placer_ctx, + net_cost_handler); //Some stats VTR_LOG("\n"); @@ -983,7 +988,7 @@ void try_place(const Netlist<>& net_list, write_noc_placement_file(noc_opts.noc_placement_file_name, blk_loc_registry.block_locs()); } - free_placement_structs(placer_opts, noc_opts, placer_ctx); + free_placement_structs(placer_opts, noc_opts, placer_ctx, net_cost_handler); free_try_swap_arrays(); print_timing_stats("Placement Quench", post_quench_timing_stats, @@ -1121,8 +1126,8 @@ static void placement_inner_loop(const t_annealing_state* state, ++(*moves_since_cost_recompute); if (*moves_since_cost_recompute > MAX_MOVES_BEFORE_RECOMPUTE) { //VTR_LOG("recomputing costs from scratch, old bb_cost is %g\n", costs->bb_cost); - recompute_costs_from_scratch(placer_opts, noc_opts, delay_model, - criticalities, costs); + net_cost_handler.recompute_costs_from_scratch(placer_opts, noc_opts, delay_model, + criticalities, costs); //VTR_LOG("new_bb_cost is %g\n", costs->bb_cost); *moves_since_cost_recompute = 0; } @@ -1515,7 +1520,7 @@ static e_move_result try_swap(const t_annealing_state* state, VTR_ASSERT_SAFE(move_outcome == REJECTED); /* Reset the net cost function flags first. */ - reset_move_nets(); + net_cost_handler.reset_move_nets(); /* Restore the place_ctx.block_locs data structures to their state before the move. */ revert_move_blocks(blocks_affected, placer_ctx.mutable_blk_loc_registry()); @@ -1897,8 +1902,6 @@ static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, } } - init_place_move_structs(num_nets); - auto& place_move_ctx = placer_ctx.mutable_move(); if (place_ctx.cube_bb) { place_move_ctx.bb_coords.resize(num_nets, t_bb()); @@ -1915,22 +1918,21 @@ static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, elem = OPEN; } - alloc_and_load_chan_w_factors_for_place_cost(place_cost_exp); - place_ctx.pl_macros = alloc_and_load_placement_macros(directs, num_directs); if (noc_opts.noc) { allocate_and_load_noc_placement_structs(); } - return alloc_and_load_try_swap_structs(place_ctx.cube_bb); + return alloc_and_load_try_swap_structs(place_ctx.cube_bb, place_cost_exp); } /* Frees the major structures needed by the placer (and not needed * * elsewhere). */ static void free_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { auto& place_move_ctx = placer_ctx.mutable_move(); if (placer_opts.place_algorithm.is_timing_driven()) { @@ -1946,7 +1948,7 @@ static void free_placement_structs(const t_placer_opts& placer_opts, free_placement_macros_structs(); - free_place_move_structs(); + net_cost_handler.free_place_move_structs(); vtr::release_memory(place_move_ctx.bb_coords); vtr::release_memory(place_move_ctx.bb_num_on_edges); @@ -1957,16 +1959,16 @@ static void free_placement_structs(const t_placer_opts& placer_opts, place_move_ctx.num_sink_pin_layer.clear(); - free_chan_w_factors_for_place_cost(); + net_cost_handler.free_chan_w_factors_for_place_cost(); - free_try_swap_structs(); + free_try_swap_structs(net_cost_handler); if (noc_opts.noc) { free_noc_placement_structs(); } } -static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb) { +static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb, float place_cost_exp) { /* Allocate the local bb_coordinate storage, etc. only once. */ /* Allocate with size cluster_ctx.clb_nlist.nets().size() for any number of nets affected. */ auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1975,11 +1977,11 @@ static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb) { place_ctx.compressed_block_grids = create_compressed_block_grids(); size_t num_nets = cluster_ctx.clb_nlist.nets().size(); - return {num_nets, cube_bb}; + return {num_nets, cube_bb, place_cost_exp}; } -static void free_try_swap_structs() { - free_try_swap_net_cost_structs(); +static void free_try_swap_structs(NetCostHandler& net_cost_handler) { + net_cost_handler.free_try_swap_net_cost_structs(); auto& place_ctx = g_vpr_ctx.mutable_placement(); vtr::release_memory(place_ctx.compressed_block_grids); @@ -1990,7 +1992,8 @@ static void check_place(const t_placer_costs& costs, const PlacerCriticalities* criticalities, const t_place_algorithm& place_algorithm, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { /* Checks that the placement has not confused our data structures. * * i.e. the clb and block structures agree about the locations of * * every block, blocks are in legal spots, etc. Also recomputes * @@ -2000,7 +2003,7 @@ static void check_place(const t_placer_costs& costs, int error = 0; error += check_placement_consistency(placer_ctx.blk_loc_registry()); - error += check_placement_costs(costs, delay_model, criticalities, place_algorithm, placer_ctx); + error += check_placement_costs(costs, delay_model, criticalities, place_algorithm, placer_ctx, net_cost_handler); error += check_placement_floorplanning(placer_ctx.block_locs()); if (noc_opts.noc) { @@ -2026,7 +2029,8 @@ static int check_placement_costs(const t_placer_costs& costs, const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, const t_place_algorithm& place_algorithm, - PlacerContext& placer_ctx) { + PlacerContext& placer_ctx, + NetCostHandler& net_cost_handler) { int error = 0; double bb_cost_check; double timing_cost_check; @@ -2034,10 +2038,10 @@ static int check_placement_costs(const t_placer_costs& costs, const bool cube_bb = g_vpr_ctx.placement().cube_bb; if (cube_bb) { - bb_cost_check = comp_bb_cost(e_cost_methods::CHECK); + bb_cost_check = net_cost_handler.comp_bb_cost(e_cost_methods::CHECK); } else { VTR_ASSERT_SAFE(!cube_bb); - bb_cost_check = comp_layer_bb_cost(e_cost_methods::CHECK); + bb_cost_check = net_cost_handler.comp_layer_bb_cost(e_cost_methods::CHECK); } if (fabs(bb_cost_check - costs.bb_cost) > costs.bb_cost * ERROR_TOL) { From 94c2dadcc7511d7e8013b5a979a31882694aac1d Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 15:26:03 -0400 Subject: [PATCH 03/36] remove place_cost_exp argument from alloc_and_load_placement_structs() --- vpr/src/place/place.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 05d086d3ea1..49eb2392dd2 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -188,8 +188,7 @@ void print_clb_placement(const char* fname); static bool is_cube_bb(const e_place_bounding_box_mode place_bb_mode, const RRGraphView& rr_graph); -static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, - const t_placer_opts& placer_opts, +static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, t_direct_inf* directs, int num_directs, @@ -449,8 +448,8 @@ void try_place(const Netlist<>& net_list, const auto& p_runtime_ctx = placer_ctx.runtime(); - NetCostHandler net_cost_handler = alloc_and_load_placement_structs(placer_opts.place_cost_exp, placer_opts, - noc_opts, directs, num_directs, placer_ctx); + NetCostHandler net_cost_handler = alloc_and_load_placement_structs(placer_opts, noc_opts, directs, + num_directs, placer_ctx); set_net_handlers_placer_ctx(placer_ctx); std::unique_ptr manual_move_generator = std::make_unique(placer_ctx); @@ -1847,8 +1846,7 @@ static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& block /* Allocates the major structures needed only by the placer, primarily for * * computing costs quickly and such. */ -static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, - const t_placer_opts& placer_opts, +static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, t_direct_inf* directs, int num_directs, @@ -1924,7 +1922,7 @@ static NetCostHandler alloc_and_load_placement_structs(float place_cost_exp, allocate_and_load_noc_placement_structs(); } - return alloc_and_load_try_swap_structs(place_ctx.cube_bb, place_cost_exp); + return alloc_and_load_try_swap_structs(place_ctx.cube_bb, placer_opts.place_cost_exp); } /* Frees the major structures needed by the placer (and not needed * From 5651cbedd1a354a5ad3d527d45770e7e5c7f5d7a Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 17:42:53 -0400 Subject: [PATCH 04/36] move some static functions from net_cost_handler.cpp to NetCostHandler class --- vpr/src/place/net_cost_handler.cpp | 425 ++++++++--------------------- vpr/src/place/net_cost_handler.h | 247 +++++++++++++++-- vpr/src/place/place.cpp | 9 +- 3 files changed, 335 insertions(+), 346 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index b7b903c7fed..0860f0d2bf4 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -134,11 +134,6 @@ static struct PLNetCost pl_net_cost; static struct TSInfo ts_info; -static std::optional> placer_ctx_ref; - -void set_net_handlers_placer_ctx(PlacerContext& placer_ctx) { - placer_ctx_ref = std::ref(placer_ctx); -} /** * @param net @@ -149,25 +144,7 @@ static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks); -/** - * @brief Calculate the new connection delay and timing cost of all the - * sink pins affected by moving a specific pin to a new location. Also - * calculates the total change in the timing cost. - * @param delay_model - * @param criticalities - * @param net - * @param pin - * @param affected_pins Updated by this routine to store the sink pins whose delays are changed due to moving the block - * @param delta_timing_cost Computed by this routine and returned by reference. - * @param is_src_moving True if "pin" is a sink pin and its driver is among the moving blocks - */ -static void update_td_delta_costs(const PlaceDelayModel* delay_model, - const PlacerCriticalities& criticalities, - const ClusterNetId net, - const ClusterPinId pin, - std::vector& affected_pins, - double& delta_timing_cost, - bool is_src_moving); + /** * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. @@ -175,111 +152,7 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model, */ static void record_affected_net(const ClusterNetId net); -/** - * @brief Update the 3D bounding box of "net_id" incrementally based on the old and new locations of a pin on that net - * @details Updates the bounding box of a net by storing its coordinates in the bb_coord_new data structure and the - * number of blocks on each edge in the bb_edge_new data structure. This routine should only be called for large nets, - * since it has some overhead relative to just doing a brute force bounding box calculation. The bounding box coordinate - * and edge information for inet must be valid before this routine is called. Currently assumes channels on both sides of - * the CLBs forming the edges of the bounding box can be used. Essentially, I am assuming the pins always lie on the - * outside of the bounding box. The x and y coordinates are the pin's x and y coordinates. IO blocks are considered to be one - * cell in for simplicity. - * @param bb_edge_new Number of blocks on the edges of the bounding box - * @param bb_coord_new Coordinates of the bounding box - * @param num_sink_pin_layer_new Number of sinks of the given net on each layer - * @param pin_old_loc The old location of the moving pin - * @param pin_new_loc The new location of the moving pin - * @param src_pin Is the moving pin driving the net - */ -static void update_bb(ClusterNetId net_id, - t_bb& bb_edge_new, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool src_pin); - -/** - * @brief Calculate the 3D bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and - * store them in bb_coord_new - * @param net_id ID of the net for which the bounding box is requested - * @param bb_coord_new Computed by this function and returned by reference. - * @param num_sink_pin_layer Store the number of sink pins of "net_id" on each layer - */ -static void get_non_updatable_bb(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer); -/** - * @brief Calculate the per-layer bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and - * store them in bb_coord_new - * @param net_id ID of the net for which the bounding box is requested - * @param bb_coord_new Computed by this function and returned by reference. - * @param num_sink_layer Store the number of sink pins of "net_id" on each layer - */ -static void get_non_updatable_layer_bb(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer); - -/** - * @brief Update the per-layer bounding box of "net_id" incrementally based on the old and new locations of a pin on that net - * @details Updates the bounding box of a net by storing its coordinates in the bb_coord_new data structure and - * the number of blocks on each edge in the bb_edge_new data structure. This routine should only be called for - * large nets, since it has some overhead relative to just doing a brute force bounding box calculation. - * The bounding box coordinate and edge information for inet must be valid before this routine is called. - * Currently assumes channels on both sides of the CLBs forming the edges of the bounding box can be used. - * Essentially, I am assuming the pins always lie on the outside of the bounding box. The x and y coordinates - * are the pin's x and y coordinates. IO blocks are considered to be one cell in for simplicity. - * @param bb_edge_new Number of blocks on the edges of the bounding box - * @param bb_coord_new Coordinates of the bounding box - * @param num_sink_pin_layer_new Number of sinks of the given net on each layer - * @param pin_old_loc The old location of the moving pin - * @param pin_new_loc The new location of the moving pin - * @param is_output_pin Is the moving pin of the type output - */ -static void update_layer_bb(ClusterNetId net_id, - std::vector& bb_edge_new, - std::vector& bb_coord_new, - vtr::NdMatrixProxy bb_pin_sink_count_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool is_output_pin); - -/** -* @brief This function is called in update_layer_bb to update the net's bounding box incrementally if -* the pin under consideration change layer. - * @param net_id ID of the net which the moving pin belongs to - * @param pin_old_loc Old location of the moving pin - * @param pin_new_loc New location of the moving pin - * @param curr_bb_edge The current known number of blocks of the net on bounding box edges - * @param curr_bb_coord The current known boudning box of the net - * @param bb_pin_sink_count_new The updated number of net's sinks on each layer - * @param bb_edge_new The new bb edge calculated by this function - * @param bb_coord_new The new bb calculated by this function - */ -static inline void update_bb_layer_changed(ClusterNetId net_id, - const t_physical_tile_loc& pin_old_loc, - const t_physical_tile_loc& pin_new_loc, - const std::vector& curr_bb_edge, - const std::vector& curr_bb_coord, - vtr::NdMatrixProxy bb_pin_sink_count_new, - std::vector& bb_edge_new, - std::vector& bb_coord_new); - -/** - * @brief Calculate the per-layer BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. - * @details This routine finds the bounding box of each net from scratch when the bounding box is of type per-layer (i.e. from - * only the block location information). It updates the coordinate, number of pins on each edge information, and the - * number of sinks on each layer. 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. - */ -static void get_layer_bb_from_scratch(ClusterNetId net_id, - std::vector& num_on_edges, - std::vector& coords, - vtr::NdMatrixProxy layer_pin_sink_count); /** * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer @@ -303,26 +176,7 @@ static double get_net_wirelength_from_layer_bb(ClusterNetId /* net_id */, const std::vector& bb, const vtr::NdMatrixProxy layer_pin_sink_count); -/** - * @brief This function is called in update_layer_bb to update the net's bounding box incrementally if - * the pin under consideration is not changing layer. - * @param net_id ID of the net which the moving pin belongs to - * @param pin_old_loc Old location of the moving pin - * @param pin_new_loc New location of the moving pin - * @param curr_bb_edge The current known number of blocks of the net on bounding box edges - * @param curr_bb_coord The current known boudning box of the net - * @param bb_pin_sink_count_new The updated number of net's sinks on each layer - * @param bb_edge_new The new bb edge calculated by this function - * @param bb_coord_new The new bb calculated by this function - */ -static inline void update_bb_same_layer(ClusterNetId net_id, - const t_physical_tile_loc& pin_old_loc, - const t_physical_tile_loc& pin_new_loc, - const std::vector& curr_bb_edge, - const std::vector& curr_bb_coord, - vtr::NdMatrixProxy bb_pin_sink_count_new, - std::vector& bb_edge_new, - std::vector& bb_coord_new); + /** * @brief If the moving pin is of type type SINK, update bb_pin_sink_count_new which stores the number of sink pins on each layer of "net_id" @@ -338,29 +192,7 @@ static void update_bb_pin_sink_count(const t_physical_tile_loc& pin_old_loc, vtr::NdMatrixProxy bb_pin_sink_count_new, bool is_output_pin); -/** - * @brief Update the data structure for large nets that keep track of - * the number of blocks on each edge of the bounding box. If the moving block - * is the only block on one of the edges, the bounding box is calculated from scratch. - * Since this function is used for large nets, it updates the bounding box incrementally. - * @param net_id ID of the net which the moving pin belongs to - * @param bb_edge_new The new bb edge calculated by this function - * @param bb_coord_new The new bb calculated by this function - * @param bb_layer_pin_sink_count The updated number of net's sinks on each layer - * @param old_num_block_on_edge The current known number of blocks of the net on bounding box edges - * @param old_edge_coord The current known boudning box of the net - * @param new_num_block_on_edge The new bb calculated by this function - * @param new_edge_coord The new bb edge calculated by this function - * - */ -static inline void update_bb_edge(ClusterNetId net_id, - std::vector& bb_edge_new, - std::vector& bb_coord_new, - vtr::NdMatrixProxy bb_layer_pin_sink_count, - const int& old_num_block_on_edge, - const int& old_edge_coord, - int& new_num_block_on_edge, - int& new_edge_coord); + /** * @brief When BB is being updated incrementally, the pin is moving to a new layer, and the BB is of the type "per-layer, @@ -377,21 +209,6 @@ static void add_block_to_bb(const t_physical_tile_loc& new_pin_loc, t_2D_bb& bb_edge_new, t_2D_bb& bb_coord_new); -/** - * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. - * @details This routine finds the bounding box of each net from scratch (i.e. from only the block location information). 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. - */ -static void get_bb_from_scratch(ClusterNetId net_id, - t_bb& coords, - t_bb& num_on_edges, - vtr::NdMatrixProxy num_sink_pin_layer); - /** * @brief Given the 3D BB, calculate the wire-length cost of the net * @param net_id ID of the net which cost is requested @@ -448,18 +265,17 @@ void NetCostHandler::update_net_bb_(const ClusterNetId net, const ClusterPinId blk_pin, const t_pl_moved_block& pl_moved_block) { const auto& cluster_ctx = g_vpr_ctx.clustering(); - const auto& placer_ctx = placer_ctx_ref->get(); - const auto& block_locs = placer_ctx.block_locs(); + const auto& block_locs = placer_ctx_.block_locs(); if (cluster_ctx.clb_nlist.net_sinks(net).size() < SMALL_NET) { //For small nets brute-force bounding box update is faster if (pl_net_cost.bb_update_status[net] == NetUpdateState::NOT_UPDATED_YET) { //Only once per-net - bb_updater_.get_non_updatable_bb(net); + get_non_updatable_bb_(net); } } else { //For large nets, update bounding box incrementally - int iblk_pin = placer_ctx.blk_loc_registry().tile_pin_index(blk_pin); + int iblk_pin = placer_ctx_.blk_loc_registry().tile_pin_index(blk_pin); t_pl_loc block_loc = block_locs[blk].loc; t_physical_tile_type_ptr blk_type = physical_tile_type(block_loc); @@ -468,24 +284,24 @@ void NetCostHandler::update_net_bb_(const ClusterNetId net, bool is_driver = cluster_ctx.clb_nlist.pin_type(blk_pin) == PinType::DRIVER; //Incremental bounding box update - bb_updater_.update_bb(net, - {pl_moved_block.old_loc.x + pin_width_offset, - pl_moved_block.old_loc.y + pin_height_offset, - pl_moved_block.old_loc.layer}, - {pl_moved_block.new_loc.x + pin_width_offset, - pl_moved_block.new_loc.y + pin_height_offset, - pl_moved_block.new_loc.layer}, - is_driver); + update_bb_(net, + {pl_moved_block.old_loc.x + pin_width_offset, + pl_moved_block.old_loc.y + pin_height_offset, + pl_moved_block.old_loc.layer}, + {pl_moved_block.new_loc.x + pin_width_offset, + pl_moved_block.new_loc.y + pin_height_offset, + pl_moved_block.new_loc.layer}, + is_driver); } } -static void update_td_delta_costs(const PlaceDelayModel* delay_model, - const PlacerCriticalities& criticalities, - const ClusterNetId net, - const ClusterPinId pin, - std::vector& affected_pins, - double& delta_timing_cost, - bool is_src_moving) { +void NetCostHandler::update_td_delta_costs_(const PlaceDelayModel* delay_model, + const PlacerCriticalities& criticalities, + const ClusterNetId net, + const ClusterPinId pin, + std::vector& affected_pins, + double& delta_timing_cost, + bool is_src_moving) { /** * Assumes that the blocks have been moved to the proposed new locations. * Otherwise, the routine comp_td_single_connection_delay() will not be @@ -512,13 +328,12 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model, * for incremental static timing analysis (incremental STA). */ auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& block_locs = placer_ctx.block_locs(); + auto& block_locs = placer_ctx_.block_locs(); - const auto& connection_delay = placer_ctx.timing().connection_delay; - auto& connection_timing_cost = placer_ctx.mutable_timing().connection_timing_cost; - auto& proposed_connection_delay = placer_ctx.mutable_timing().proposed_connection_delay; - auto& proposed_connection_timing_cost = placer_ctx.mutable_timing().proposed_connection_timing_cost; + const auto& connection_delay = placer_ctx_.timing().connection_delay; + auto& connection_timing_cost = placer_ctx_.mutable_timing().connection_timing_cost; + auto& proposed_connection_delay = placer_ctx_.mutable_timing().proposed_connection_delay; + auto& proposed_connection_timing_cost = placer_ctx_.mutable_timing().proposed_connection_timing_cost; if (cluster_ctx.clb_nlist.pin_type(pin) == PinType::DRIVER) { /* This pin is a net driver on a moved block. */ @@ -610,27 +425,26 @@ void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place if (place_algorithm.is_timing_driven()) { /* Determine the change in connection delay and timing cost. */ - update_td_delta_costs(delay_model, - *criticalities, - net_id, - pin_id, - affected_pins, - timing_delta_c, - is_src_moving); + update_td_delta_costs_(delay_model, + *criticalities, + net_id, + pin_id, + affected_pins, + timing_delta_c, + is_src_moving); } } -static void get_non_updatable_bb(ClusterNetId net_id, +void NetCostHandler::get_non_updatable_bb_(ClusterNetId net_id, t_bb& bb_coord_new, vtr::NdMatrixProxy num_sink_pin_layer) { //TODO: account for multiple physical pin instances per logical pin auto& cluster_ctx = g_vpr_ctx.clustering(); auto& device_ctx = g_vpr_ctx.device(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& block_locs = placer_ctx.block_locs(); + auto& block_locs = placer_ctx_.block_locs(); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); - int pnum = placer_ctx.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); + int pnum = placer_ctx_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); t_pl_loc block_loc = block_locs[bnum].loc; int x = block_loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; @@ -651,7 +465,7 @@ static void get_non_updatable_bb(ClusterNetId net_id, for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { bnum = cluster_ctx.clb_nlist.pin_block(pin_id); block_loc = block_locs[bnum].loc; - pnum = placer_ctx.blk_loc_registry().tile_pin_index(pin_id); + pnum = placer_ctx_.blk_loc_registry().tile_pin_index(pin_id); x = block_loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; y = block_loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; layer = block_loc.layer; @@ -693,14 +507,13 @@ static void get_non_updatable_bb(ClusterNetId net_id, bb_coord_new.layer_max = max(min(layer_max, device_ctx.grid.get_num_layers() - 1), 0); } -static void get_non_updatable_layer_bb(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer) { +void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, + std::vector& bb_coord_new, + vtr::NdMatrixProxy num_sink_layer) { //TODO: account for multiple physical pin instances per logical pin auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& block_locs = placer_ctx.block_locs(); + auto& block_locs = placer_ctx_.block_locs(); int num_layers = device_ctx.grid.get_num_layers(); for (int layer_num = 0; layer_num < device_ctx.grid.get_num_layers(); layer_num++) { @@ -709,7 +522,7 @@ static void get_non_updatable_layer_bb(ClusterNetId net_id, ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; - int pnum = placer_ctx.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); + int pnum = placer_ctx_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); int src_x = block_locs[bnum].loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; int src_y = block_locs[bnum].loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; @@ -722,7 +535,7 @@ static void get_non_updatable_layer_bb(ClusterNetId net_id, for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { bnum = cluster_ctx.clb_nlist.pin_block(pin_id); block_loc = block_locs[bnum].loc; - pnum = placer_ctx.blk_loc_registry().tile_pin_index(pin_id); + pnum = placer_ctx_.blk_loc_registry().tile_pin_index(pin_id); int x = block_locs[bnum].loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; int y = block_locs[bnum].loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; @@ -757,7 +570,7 @@ static void get_non_updatable_layer_bb(ClusterNetId net_id, } } -static void update_bb(ClusterNetId net_id, +void NetCostHandler::update_bb_(ClusterNetId net_id, t_bb& bb_edge_new, t_bb& bb_coord_new, vtr::NdMatrixProxy num_sink_pin_layer_new, @@ -768,8 +581,7 @@ static void update_bb(ClusterNetId net_id, const t_bb *curr_bb_edge, *curr_bb_coord; auto& device_ctx = g_vpr_ctx.device(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& place_move_ctx = placer_ctx.move(); + auto& place_move_ctx = placer_ctx_.move(); const int num_layers = device_ctx.grid.get_num_layers(); @@ -807,7 +619,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -839,7 +651,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -880,7 +692,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -912,7 +724,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -962,7 +774,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -988,7 +800,7 @@ static void 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, bb_coord_new, bb_edge_new, num_sink_pin_layer_new); pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { @@ -1030,7 +842,7 @@ static void update_bb(ClusterNetId net_id, } } -static void update_layer_bb(ClusterNetId net_id, +void NetCostHandler::update_layer_bb_(ClusterNetId net_id, std::vector& bb_edge_new, std::vector& bb_coord_new, vtr::NdMatrixProxy bb_pin_sink_count_new, @@ -1038,8 +850,7 @@ static void update_layer_bb(ClusterNetId net_id, t_physical_tile_loc pin_new_loc, bool is_output_pin) { auto& device_ctx = g_vpr_ctx.device(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& place_move_ctx = placer_ctx.move(); + auto& place_move_ctx = placer_ctx_.move(); pin_new_loc.x = max(min(pin_new_loc.x, device_ctx.grid.width() - 2), 1); //-2 for no perim channels pin_new_loc.y = max(min(pin_new_loc.y, device_ctx.grid.height() - 2), 1); //-2 for no perim channels @@ -1082,7 +893,7 @@ static void update_layer_bb(ClusterNetId net_id, bb_coord_new = *curr_bb_coord; if (layer_changed) { - update_bb_layer_changed(net_id, + update_bb_layer_changed_(net_id, pin_old_loc, pin_new_loc, *curr_bb_edge, @@ -1091,7 +902,7 @@ static void update_layer_bb(ClusterNetId net_id, bb_edge_new, bb_coord_new); } else { - update_bb_same_layer(net_id, + update_bb_same_layer_(net_id, pin_old_loc, pin_new_loc, *curr_bb_edge, @@ -1106,7 +917,7 @@ static void update_layer_bb(ClusterNetId net_id, } } -static inline void update_bb_same_layer(ClusterNetId net_id, +inline void NetCostHandler::update_bb_same_layer_(ClusterNetId net_id, const t_physical_tile_loc& pin_old_loc, const t_physical_tile_loc& pin_new_loc, const std::vector& curr_bb_edge, @@ -1125,7 +936,7 @@ static inline void update_bb_same_layer(ClusterNetId net_id, if (x_new < x_old) { if (x_old == curr_bb_coord[layer_num].xmax) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1148,7 +959,7 @@ static inline void update_bb_same_layer(ClusterNetId net_id, } else if (x_new > x_old) { if (x_old == curr_bb_coord[layer_num].xmin) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1172,7 +983,7 @@ static inline void update_bb_same_layer(ClusterNetId net_id, if (y_new < y_old) { if (y_old == curr_bb_coord[layer_num].ymax) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1195,7 +1006,7 @@ static inline void update_bb_same_layer(ClusterNetId net_id, } else if (y_new > y_old) { if (y_old == curr_bb_coord[layer_num].ymin) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1218,7 +1029,7 @@ static inline void update_bb_same_layer(ClusterNetId net_id, } } -static inline void update_bb_layer_changed(ClusterNetId net_id, +inline void NetCostHandler::update_bb_layer_changed_(ClusterNetId net_id, const t_physical_tile_loc& pin_old_loc, const t_physical_tile_loc& pin_new_loc, const std::vector& curr_bb_edge, @@ -1240,7 +1051,7 @@ static inline void update_bb_layer_changed(ClusterNetId net_id, "old_layer". Then, "add_block_to_bb" is called to update the bounding box on the new layer. */ if (x_old == curr_bb_coord[old_layer_num].xmax) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1252,7 +1063,7 @@ static inline void update_bb_layer_changed(ClusterNetId net_id, return; } } else if (x_old == curr_bb_coord[old_layer_num].xmin) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1266,7 +1077,7 @@ static inline void update_bb_layer_changed(ClusterNetId net_id, } if (y_old == curr_bb_coord[old_layer_num].ymax) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1278,7 +1089,7 @@ static inline void update_bb_layer_changed(ClusterNetId net_id, return; } } else if (y_old == curr_bb_coord[old_layer_num].ymin) { - update_bb_edge(net_id, + update_bb_edge_(net_id, bb_edge_new, bb_coord_new, bb_pin_sink_count_new, @@ -1313,7 +1124,7 @@ static void update_bb_pin_sink_count(const t_physical_tile_loc& pin_old_loc, } } -static inline void update_bb_edge(ClusterNetId net_id, +inline void NetCostHandler::update_bb_edge_(ClusterNetId net_id, std::vector& bb_edge_new, std::vector& bb_coord_new, vtr::NdMatrixProxy bb_layer_pin_sink_count, @@ -1322,7 +1133,7 @@ static inline void update_bb_edge(ClusterNetId net_id, int& new_num_block_on_edge, int& new_edge_coord) { if (old_num_block_on_edge == 1) { - get_layer_bb_from_scratch(net_id, + get_layer_bb_from_scratch_(net_id, bb_edge_new, bb_coord_new, bb_layer_pin_sink_count); @@ -1377,19 +1188,18 @@ static void add_block_to_bb(const t_physical_tile_loc& new_pin_loc, } } -static void get_bb_from_scratch(ClusterNetId net_id, +void NetCostHandler::get_bb_from_scratch_(ClusterNetId net_id, t_bb& coords, t_bb& num_on_edges, vtr::NdMatrixProxy num_sink_pin_layer) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& device_ctx = g_vpr_ctx.device(); auto& grid = device_ctx.grid; - const auto& placer_ctx = placer_ctx_ref->get(); - auto& block_locs = placer_ctx.block_locs(); + auto& block_locs = placer_ctx_.block_locs(); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; - int pnum = placer_ctx.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); + int pnum = placer_ctx_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); VTR_ASSERT_SAFE(pnum >= 0); int x = block_loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; int y = block_loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; @@ -1420,7 +1230,7 @@ static void get_bb_from_scratch(ClusterNetId net_id, for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { bnum = cluster_ctx.clb_nlist.pin_block(pin_id); block_loc = block_locs[bnum].loc; - pnum = placer_ctx.blk_loc_registry().tile_pin_index(pin_id); + pnum = placer_ctx_.blk_loc_registry().tile_pin_index(pin_id); x = block_locs[bnum].loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; y = block_locs[bnum].loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; pin_layer = block_locs[bnum].loc.layer; @@ -1497,15 +1307,14 @@ static void get_bb_from_scratch(ClusterNetId net_id, num_on_edges.layer_max = layer_max_edge; } -static void get_layer_bb_from_scratch(ClusterNetId net_id, +void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, std::vector& num_on_edges, std::vector& coords, vtr::NdMatrixProxy layer_pin_sink_count) { auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); auto& grid = device_ctx.grid; - auto& placer_ctx = placer_ctx_ref->get(); - auto& block_locs = placer_ctx.block_locs(); + auto& block_locs = placer_ctx_.block_locs(); const int num_layers = device_ctx.grid.get_num_layers(); std::vector xmin(num_layers, OPEN); @@ -1522,7 +1331,7 @@ static void get_layer_bb_from_scratch(ClusterNetId net_id, ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; - int pnum_src = placer_ctx.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); + int pnum_src = placer_ctx_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); VTR_ASSERT_SAFE(pnum_src >= 0); int x_src = block_loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum_src]; int y_src = block_loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum_src]; @@ -1547,7 +1356,7 @@ static void get_layer_bb_from_scratch(ClusterNetId net_id, for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { bnum = cluster_ctx.clb_nlist.pin_block(pin_id); block_loc = block_locs[bnum].loc; - int pnum = placer_ctx.blk_loc_registry().tile_pin_index(pin_id); + int pnum = placer_ctx_.blk_loc_registry().tile_pin_index(pin_id); int layer = block_locs[bnum].loc.layer; VTR_ASSERT_SAFE(layer >= 0 && layer < num_layers); num_sink_pin_layer[layer]++; @@ -1751,7 +1560,7 @@ void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { for (const ClusterNetId ts_net: ts_info.ts_nets_to_update) { ClusterNetId net_id = ts_net; - pl_net_cost.proposed_net_cost[net_id] = bb_updater_.get_net_cost(net_id); + pl_net_cost.proposed_net_cost[net_id] = get_net_cost_(net_id); bb_delta_c += pl_net_cost.proposed_net_cost[net_id] - pl_net_cost.net_cost[net_id]; } @@ -1803,20 +1612,19 @@ double NetCostHandler::comp_bb_cost(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& place_move_ctx = placer_ctx.mutable_move(); + auto& place_move_ctx = placer_ctx_.mutable_move(); for (auto net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ /* 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, + 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)]); } else { - get_non_updatable_bb(net_id, + get_non_updatable_bb_(net_id, place_move_ctx.bb_coords[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } @@ -1840,20 +1648,19 @@ double NetCostHandler::comp_layer_bb_cost(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& place_move_ctx = placer_ctx.mutable_move(); + auto& place_move_ctx = placer_ctx_.mutable_move(); for (auto net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ /* 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_layer_bb_from_scratch(net_id, + 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)]); } else { - get_non_updatable_layer_bb(net_id, + get_non_updatable_layer_bb_(net_id, place_move_ctx.layer_bb_coords[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } @@ -1880,20 +1687,19 @@ double NetCostHandler::comp_layer_bb_cost(e_cost_methods method) { void NetCostHandler::update_move_nets() { /* update net cost functions and reset flags. */ auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& placer_ctx = placer_ctx_ref->get(); - auto& place_move_ctx = placer_ctx.mutable_move(); + auto& place_move_ctx = placer_ctx_.mutable_move(); for (const ClusterNetId ts_net : ts_info.ts_nets_to_update) { ClusterNetId net_id = ts_net; - bb_updater_.set_ts_bb_coord(net_id); + 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_info.ts_layer_sink_pin_count[size_t(net_id)][layer_num]; } if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET) { - bb_updater_.set_ts_edge(net_id); + set_ts_edge_(net_id); } pl_net_cost.net_cost[net_id] = pl_net_cost.proposed_net_cost[net_id]; @@ -1918,8 +1724,6 @@ void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_op const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, t_placer_costs* costs) { - auto& placer_ctx = placer_ctx_ref->get(); - auto check_and_print_cost = [](double new_cost, double old_cost, const std::string& cost_name) -> void { @@ -1937,7 +1741,7 @@ void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_op if (placer_opts.place_algorithm.is_timing_driven()) { double new_timing_cost = 0.; - comp_td_costs(delay_model, *criticalities, placer_ctx, &new_timing_cost); + comp_td_costs(delay_model, *criticalities, placer_ctx_, &new_timing_cost); check_and_print_cost(new_timing_cost, costs->timing_cost, "timing_cost"); costs->timing_cost = new_timing_cost; } else { @@ -2097,20 +1901,9 @@ void NetCostHandler::free_try_swap_net_cost_structs() { vtr::release_memory(ts_info.ts_nets_to_update); } -NetCostHandler::NetCostHandler(size_t num_nets, bool cube_bb, float place_cost_exp) - : bb_updater_(num_nets, cube_bb) { - pl_net_cost.net_cost.resize(num_nets, -1.); - pl_net_cost.proposed_net_cost.resize(num_nets, -1.); - /* Used to store costs for moves not yet made and to indicate when a net's * - * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * - * been recomputed. */ - pl_net_cost.bb_update_status.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); - - alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); -} - -NetCostHandler::BBUpdater::BBUpdater(size_t num_nets, bool cube_bb) : - cube_bb_(cube_bb) { +NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) + : cube_bb_(cube_bb) + , placer_ctx_(placer_ctx) { const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); // Either 3D BB or per layer BB data structure are used, not both. @@ -2126,24 +1919,34 @@ NetCostHandler::BBUpdater::BBUpdater(size_t num_nets, bool cube_bb) : ts_info.ts_layer_sink_pin_count.resize({num_nets, size_t(num_layers)}, OPEN); ts_info.ts_nets_to_update.resize(num_nets, ClusterNetId::INVALID()); + + pl_net_cost.net_cost.resize(num_nets, -1.); + pl_net_cost.proposed_net_cost.resize(num_nets, -1.); + /* Used to store costs for moves not yet made and to indicate when a net's * + * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * + * been recomputed. */ + pl_net_cost.bb_update_status.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); + + alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); } -void NetCostHandler::BBUpdater::get_non_updatable_bb(const ClusterNetId net) { + +void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { if (cube_bb_) { - ::get_non_updatable_bb(net, - ts_info.ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); + get_non_updatable_bb_(net, + ts_info.ts_bb_coord_new[net], + ts_info.ts_layer_sink_pin_count[size_t(net)]); } else { - ::get_non_updatable_layer_bb(net, - ts_info.layer_ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); + get_non_updatable_layer_bb_(net, + ts_info.layer_ts_bb_coord_new[net], + ts_info.ts_layer_sink_pin_count[size_t(net)]); } } -void NetCostHandler::BBUpdater::update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { +void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { if (cube_bb_) { - ::update_bb(net_id, + update_bb_(net_id, ts_info.ts_bb_edge_new[net_id], ts_info.ts_bb_coord_new[net_id], ts_info.ts_layer_sink_pin_count[size_t(net_id)], @@ -2152,7 +1955,7 @@ void NetCostHandler::BBUpdater::update_bb(ClusterNetId net_id, t_physical_tile_l is_driver); } else { - ::update_layer_bb(net_id, + update_layer_bb_(net_id, ts_info.layer_ts_bb_edge_new[net_id], ts_info.layer_ts_bb_coord_new[net_id], ts_info.ts_layer_sink_pin_count[size_t(net_id)], @@ -2162,7 +1965,7 @@ void NetCostHandler::BBUpdater::update_bb(ClusterNetId net_id, t_physical_tile_l } } -double NetCostHandler::BBUpdater::get_net_cost(const ClusterNetId net_id) { +double NetCostHandler::get_net_cost_(const ClusterNetId net_id) { if (cube_bb_) { return ::get_net_cost(net_id, ts_info.ts_bb_coord_new[net_id]); } @@ -2171,8 +1974,8 @@ double NetCostHandler::BBUpdater::get_net_cost(const ClusterNetId net_id) { } } -void NetCostHandler::BBUpdater::set_ts_bb_coord(const ClusterNetId net_id) { - auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); +void NetCostHandler::set_ts_bb_coord_(const ClusterNetId net_id) { + auto& place_move_ctx = placer_ctx_.mutable_move(); if (cube_bb_) { place_move_ctx.bb_coords[net_id] = ts_info.ts_bb_coord_new[net_id]; } else { @@ -2180,8 +1983,8 @@ void NetCostHandler::BBUpdater::set_ts_bb_coord(const ClusterNetId net_id) { } } -void NetCostHandler::BBUpdater::set_ts_edge(const ClusterNetId net_id) { - auto& place_move_ctx = placer_ctx_ref->get().mutable_move(); +void NetCostHandler::set_ts_edge_(const ClusterNetId net_id) { + auto& place_move_ctx = placer_ctx_.mutable_move(); if (cube_bb_) { place_move_ctx.bb_num_on_edges[net_id] = ts_info.ts_bb_edge_new[net_id]; } else { diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 909178aa17d..4c29d64bfec 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -25,8 +25,6 @@ enum class e_cost_methods { CHECK }; -void set_net_handlers_placer_ctx(PlacerContext& placer_ctx); - class NetCostHandler { public: @@ -44,7 +42,7 @@ class NetCostHandler { * @param cube_bb True if the 3D bounding box should be used, false otherwise. * @param place_cost_exp It is an exponent to which you take the average inverse channel */ - NetCostHandler(size_t num_nets, bool cube_bb, float place_cost_exp); + NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp); /** * @brief Find all the nets and pins affected by this swap and update costs. @@ -145,38 +143,31 @@ class NetCostHandler { */ void free_try_swap_net_cost_structs(); - private: +// private: /** * @brief This class is used to hide control flows needed to distinguish 2d and 3d placement */ - class BBUpdater { - public: - BBUpdater() = delete; - BBUpdater(const BBUpdater&) = delete; - BBUpdater(BBUpdater&&) = delete; - BBUpdater& operator=(const BBUpdater&) = delete; - BBUpdater& operator=(BBUpdater&&) = delete; - - BBUpdater(size_t num_nets, bool cube_bb); - - private: - bool cube_bb_ = false; - - public: - - void get_non_updatable_bb(const ClusterNetId net); - - void update_bb(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver); - - double get_net_cost(const ClusterNetId net_id); - - void set_ts_bb_coord(const ClusterNetId net_id); - - void set_ts_edge(const ClusterNetId net_id); - }; +// class BBUpdater { +// public: +// BBUpdater() = delete; +// BBUpdater(const BBUpdater&) = delete; +// BBUpdater(BBUpdater&&) = delete; +// BBUpdater& operator=(const BBUpdater&) = delete; +// BBUpdater& operator=(BBUpdater&&) = delete; +// +// BBUpdater(PlacerContext& placer_ctx_, size_t num_nets, bool cube_bb); +// +// private: +// +// PlacerContext& placer_ctx_; +// +// public: +// +// }; private: - BBUpdater bb_updater_; + bool cube_bb_ = false; + PlacerContext& placer_ctx_; private: /** @@ -228,4 +219,200 @@ class NetCostHandler { */ void alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp); + /** + * @brief Calculate the new connection delay and timing cost of all the + * sink pins affected by moving a specific pin to a new location. Also + * calculates the total change in the timing cost. + * @param delay_model + * @param criticalities + * @param net + * @param pin + * @param affected_pins Updated by this routine to store the sink pins whose delays are changed due to moving the block + * @param delta_timing_cost Computed by this routine and returned by reference. + * @param is_src_moving True if "pin" is a sink pin and its driver is among the moving blocks + */ + void update_td_delta_costs_(const PlaceDelayModel* delay_model, + const PlacerCriticalities& criticalities, + const ClusterNetId net, + const ClusterPinId pin, + std::vector& affected_pins, + double& delta_timing_cost, + bool is_src_moving); + + void get_non_updatable_bb_(const ClusterNetId net); + + void update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver); + + double get_net_cost_(const ClusterNetId net_id); + + void set_ts_bb_coord_(const ClusterNetId net_id); + + void set_ts_edge_(const ClusterNetId net_id); + + /** + * @brief Calculate the 3D bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and + * store them in bb_coord_new + * @param net_id ID of the net for which the bounding box is requested + * @param bb_coord_new Computed by this function and returned by reference. + * @param num_sink_pin_layer Store the number of sink pins of "net_id" on each layer + */ + void get_non_updatable_bb_(ClusterNetId net_id, + t_bb& bb_coord_new, + vtr::NdMatrixProxy num_sink_pin_layer); + + /** + * @brief Calculate the per-layer bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and + * store them in bb_coord_new + * @param net_id ID of the net for which the bounding box is requested + * @param bb_coord_new Computed by this function and returned by reference. + * @param num_sink_layer Store the number of sink pins of "net_id" on each layer + */ + void get_non_updatable_layer_bb_(ClusterNetId net_id, + std::vector& bb_coord_new, + vtr::NdMatrixProxy num_sink_layer); + + /** + * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. + * @details This routine finds the bounding box of each net from scratch (i.e. from only the block location information). 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. + */ + void get_bb_from_scratch_(ClusterNetId net_id, + t_bb& coords, + t_bb& num_on_edges, + vtr::NdMatrixProxy num_sink_pin_layer); + + /** + * @brief Calculate the per-layer BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. + * @details This routine finds the bounding box of each net from scratch when the bounding box is of type per-layer (i.e. from + * only the block location information). It updates the coordinate, number of pins on each edge information, and the + * number of sinks on each layer. 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. + */ + void get_layer_bb_from_scratch_(ClusterNetId net_id, + std::vector& num_on_edges, + std::vector& coords, + vtr::NdMatrixProxy layer_pin_sink_count); + + /** + * @brief Update the 3D bounding box of "net_id" incrementally based on the old and new locations of a pin on that net + * @details Updates the bounding box of a net by storing its coordinates in the bb_coord_new data structure and the + * number of blocks on each edge in the bb_edge_new data structure. This routine should only be called for large nets, + * since it has some overhead relative to just doing a brute force bounding box calculation. The bounding box coordinate + * and edge information for inet must be valid before this routine is called. Currently assumes channels on both sides of + * the CLBs forming the edges of the bounding box can be used. Essentially, I am assuming the pins always lie on the + * outside of the bounding box. The x and y coordinates are the pin's x and y coordinates. IO blocks are considered to be one + * cell in for simplicity. + * @param bb_edge_new Number of blocks on the edges of the bounding box + * @param bb_coord_new Coordinates of the bounding box + * @param num_sink_pin_layer_new Number of sinks of the given net on each layer + * @param pin_old_loc The old location of the moving pin + * @param pin_new_loc The new location of the moving pin + * @param src_pin Is the moving pin driving the net + */ + void update_bb_(ClusterNetId net_id, + t_bb& bb_edge_new, + t_bb& bb_coord_new, + vtr::NdMatrixProxy num_sink_pin_layer_new, + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool src_pin); + + /** + * @brief Update the per-layer bounding box of "net_id" incrementally based on the old and new locations of a pin on that net + * @details Updates the bounding box of a net by storing its coordinates in the bb_coord_new data structure and + * the number of blocks on each edge in the bb_edge_new data structure. This routine should only be called for + * large nets, since it has some overhead relative to just doing a brute force bounding box calculation. + * The bounding box coordinate and edge information for inet must be valid before this routine is called. + * Currently assumes channels on both sides of the CLBs forming the edges of the bounding box can be used. + * Essentially, I am assuming the pins always lie on the outside of the bounding box. The x and y coordinates + * are the pin's x and y coordinates. IO blocks are considered to be one cell in for simplicity. + * @param bb_edge_new Number of blocks on the edges of the bounding box + * @param bb_coord_new Coordinates of the bounding box + * @param num_sink_pin_layer_new Number of sinks of the given net on each layer + * @param pin_old_loc The old location of the moving pin + * @param pin_new_loc The new location of the moving pin + * @param is_output_pin Is the moving pin of the type output + */ + void update_layer_bb_(ClusterNetId net_id, + std::vector& bb_edge_new, + std::vector& bb_coord_new, + vtr::NdMatrixProxy bb_pin_sink_count_new, + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool is_output_pin); + + /** + * @brief Update the data structure for large nets that keep track of + * the number of blocks on each edge of the bounding box. If the moving block + * is the only block on one of the edges, the bounding box is calculated from scratch. + * Since this function is used for large nets, it updates the bounding box incrementally. + * @param net_id ID of the net which the moving pin belongs to + * @param bb_edge_new The new bb edge calculated by this function + * @param bb_coord_new The new bb calculated by this function + * @param bb_layer_pin_sink_count The updated number of net's sinks on each layer + * @param old_num_block_on_edge The current known number of blocks of the net on bounding box edges + * @param old_edge_coord The current known boudning box of the net + * @param new_num_block_on_edge The new bb calculated by this function + * @param new_edge_coord The new bb edge calculated by this function + * + */ + inline void update_bb_edge_(ClusterNetId net_id, + std::vector& bb_edge_new, + std::vector& bb_coord_new, + vtr::NdMatrixProxy bb_layer_pin_sink_count, + const int& old_num_block_on_edge, + const int& old_edge_coord, + int& new_num_block_on_edge, + int& new_edge_coord); + + /** + * @brief This function is called in update_layer_bb to update the net's bounding box incrementally if + * the pin under consideration change layer. + * @param net_id ID of the net which the moving pin belongs to + * @param pin_old_loc Old location of the moving pin + * @param pin_new_loc New location of the moving pin + * @param curr_bb_edge The current known number of blocks of the net on bounding box edges + * @param curr_bb_coord The current known boudning box of the net + * @param bb_pin_sink_count_new The updated number of net's sinks on each layer + * @param bb_edge_new The new bb edge calculated by this function + * @param bb_coord_new The new bb calculated by this function + */ + inline void update_bb_layer_changed_(ClusterNetId net_id, + const t_physical_tile_loc& pin_old_loc, + const t_physical_tile_loc& pin_new_loc, + const std::vector& curr_bb_edge, + const std::vector& curr_bb_coord, + vtr::NdMatrixProxy bb_pin_sink_count_new, + std::vector& bb_edge_new, + std::vector& bb_coord_new); + + /** + * @brief This function is called in update_layer_bb to update the net's bounding box incrementally if + * the pin under consideration is not changing layer. + * @param net_id ID of the net which the moving pin belongs to + * @param pin_old_loc Old location of the moving pin + * @param pin_new_loc New location of the moving pin + * @param curr_bb_edge The current known number of blocks of the net on bounding box edges + * @param curr_bb_coord The current known boudning box of the net + * @param bb_pin_sink_count_new The updated number of net's sinks on each layer + * @param bb_edge_new The new bb edge calculated by this function + * @param bb_coord_new The new bb calculated by this function + */ + inline void update_bb_same_layer_(ClusterNetId net_id, + const t_physical_tile_loc& pin_old_loc, + const t_physical_tile_loc& pin_new_loc, + const std::vector& curr_bb_edge, + const std::vector& curr_bb_coord, + vtr::NdMatrixProxy bb_pin_sink_count_new, + std::vector& bb_edge_new, + std::vector& bb_coord_new); + }; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 49eb2392dd2..061b5ac00e9 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -194,7 +194,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac int num_directs, PlacerContext& placer_ctx); -static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb, float place_cost_exp); +static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, const bool cube_bb, float place_cost_exp); static void free_try_swap_structs(NetCostHandler& net_cost_handler); static void free_placement_structs(const t_placer_opts& placer_opts, @@ -450,7 +450,6 @@ void try_place(const Netlist<>& net_list, NetCostHandler net_cost_handler = alloc_and_load_placement_structs(placer_opts, noc_opts, directs, num_directs, placer_ctx); - set_net_handlers_placer_ctx(placer_ctx); std::unique_ptr manual_move_generator = std::make_unique(placer_ctx); @@ -1922,7 +1921,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac allocate_and_load_noc_placement_structs(); } - return alloc_and_load_try_swap_structs(place_ctx.cube_bb, placer_opts.place_cost_exp); + return alloc_and_load_try_swap_structs(placer_ctx, place_ctx.cube_bb, placer_opts.place_cost_exp); } /* Frees the major structures needed by the placer (and not needed * @@ -1966,7 +1965,7 @@ static void free_placement_structs(const t_placer_opts& placer_opts, } } -static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb, float place_cost_exp) { +static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, const bool cube_bb, float place_cost_exp) { /* Allocate the local bb_coordinate storage, etc. only once. */ /* Allocate with size cluster_ctx.clb_nlist.nets().size() for any number of nets affected. */ auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1975,7 +1974,7 @@ static NetCostHandler alloc_and_load_try_swap_structs(const bool cube_bb, float place_ctx.compressed_block_grids = create_compressed_block_grids(); size_t num_nets = cluster_ctx.clb_nlist.nets().size(); - return {num_nets, cube_bb, place_cost_exp}; + return {placer_ctx, num_nets, cube_bb, place_cost_exp}; } static void free_try_swap_structs(NetCostHandler& net_cost_handler) { From 57cf34580497d716e356e711cea7d04cd74872b0 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 18:26:55 -0400 Subject: [PATCH 05/36] remove direct calls to comp_layer_bb_cost --- vpr/src/place/net_cost_handler.cpp | 8 +++++++- vpr/src/place/net_cost_handler.h | 22 +++++++--------------- vpr/src/place/place.cpp | 24 +++--------------------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 0860f0d2bf4..35251a9a582 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -1609,6 +1609,10 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm } double NetCostHandler::comp_bb_cost(e_cost_methods method) { + return comp_bb_cost_functor_(method); +} + +double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1644,7 +1648,7 @@ double NetCostHandler::comp_bb_cost(e_cost_methods method) { return cost; } -double NetCostHandler::comp_layer_bb_cost(e_cost_methods method) { +double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { double cost = 0; double expected_wirelength = 0.0; auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1910,9 +1914,11 @@ NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool if (cube_bb_) { ts_info.ts_bb_edge_new.resize(num_nets, t_bb()); ts_info.ts_bb_coord_new.resize(num_nets, t_bb()); + comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_bb_cost_, this, std::placeholders::_1); } else { ts_info.layer_ts_bb_edge_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); ts_info.layer_ts_bb_coord_new.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); } /* This initializes the whole matrix to OPEN which is an invalid value*/ diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 4c29d64bfec..913140b07d7 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -75,7 +75,7 @@ class NetCostHandler { double& timing_delta_c); /** - * @brief Finds the bb cost from scratch (based on 3D BB). + * @brief Finds the bb cost from scratch. * Done only when the placement has been radically changed * (i.e. after initial placement). Otherwise find the cost * change incrementally. If method check is NORMAL, we find @@ -84,23 +84,10 @@ class NetCostHandler { * non_updateable_bb routine, to provide a cost which can be * used to check the correctness of the other routine. * @param method The method used to calculate placement cost. - * @return The bounding box cost of the placement, computed by the 3D method. + * @return The bounding box cost of the placement. */ double comp_bb_cost(e_cost_methods method); - /** - * @brief Finds the bb cost from scratch (based on per-layer BB). - * Done only when the placement has been radically changed - * (i.e. after initial placement). Otherwise find the cost change - * incrementally. If method check is NORMAL, we find bounding boxes - * that are updateable for the larger nets. If method is CHECK, all - * bounding boxes are found via the non_updateable_bb routine, to provide - * a cost which can be used to check the correctness of the other routine. - * @param method The method used to calculate placement cost. - * @return The placement bounding box cost, computed by the per layer method. - */ - double comp_layer_bb_cost(e_cost_methods method); - /** * @brief Reset the net cost function flags (proposed_net_cost and bb_updated_before) */ @@ -169,6 +156,8 @@ class NetCostHandler { bool cube_bb_ = false; PlacerContext& placer_ctx_; + std::function comp_bb_cost_functor_; + private: /** * @brief Update the bounding box (3D) of the net connected to blk_pin. The old and new locations of the pin are @@ -415,4 +404,7 @@ class NetCostHandler { std::vector& bb_edge_new, std::vector& bb_coord_new); + double comp_per_layer_bb_cost_(e_cost_methods method); + double comp_3d_bb_cost_(e_cost_methods method); + }; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 061b5ac00e9..352042e82fc 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -497,12 +497,7 @@ void try_place(const Netlist<>& net_list, /* Gets initial cost and loads bounding boxes. */ if (placer_opts.place_algorithm.is_timing_driven()) { - if (cube_bb) { - costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); - } else { - VTR_ASSERT_SAFE(!cube_bb); - costs.bb_cost = net_cost_handler.comp_layer_bb_cost(e_cost_methods::NORMAL); - } + costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); first_crit_exponent = placer_opts.td_place_exp_first; /*this will be modified when rlim starts to change */ @@ -578,12 +573,7 @@ void try_place(const Netlist<>& net_list, VTR_ASSERT(placer_opts.place_algorithm == BOUNDING_BOX_PLACE); /* Total cost is the same as wirelength cost normalized*/ - if (cube_bb) { - costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); - } else { - VTR_ASSERT_SAFE(!cube_bb); - costs.bb_cost = net_cost_handler.comp_layer_bb_cost(e_cost_methods::NORMAL); - } + costs.bb_cost = net_cost_handler.comp_bb_cost(e_cost_methods::NORMAL); costs.bb_cost_norm = 1 / costs.bb_cost; /* Timing cost and normalization factors are not used */ @@ -2029,17 +2019,9 @@ static int check_placement_costs(const t_placer_costs& costs, PlacerContext& placer_ctx, NetCostHandler& net_cost_handler) { int error = 0; - double bb_cost_check; double timing_cost_check; - const bool cube_bb = g_vpr_ctx.placement().cube_bb; - - if (cube_bb) { - bb_cost_check = net_cost_handler.comp_bb_cost(e_cost_methods::CHECK); - } else { - VTR_ASSERT_SAFE(!cube_bb); - bb_cost_check = net_cost_handler.comp_layer_bb_cost(e_cost_methods::CHECK); - } + double bb_cost_check = net_cost_handler.comp_bb_cost(e_cost_methods::CHECK); if (fabs(bb_cost_check - costs.bb_cost) > costs.bb_cost * ERROR_TOL) { VTR_LOG_ERROR( From 78e7dba5a59e5c181609e017fb81f929155d5f90 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 18:51:12 -0400 Subject: [PATCH 06/36] remove static ts_info from net_cost_handler --- libs/libvtrutil/src/vtr_memory.h | 2 +- vpr/src/place/net_cost_handler.cpp | 110 +++++++++++------------------ vpr/src/place/net_cost_handler.h | 45 ++++++------ 3 files changed, 65 insertions(+), 92 deletions(-) diff --git a/libs/libvtrutil/src/vtr_memory.h b/libs/libvtrutil/src/vtr_memory.h index 46a486569d2..80ab73766f2 100644 --- a/libs/libvtrutil/src/vtr_memory.h +++ b/libs/libvtrutil/src/vtr_memory.h @@ -14,7 +14,7 @@ namespace vtr { /** * @brief This function will force the container to be cleared * - * It release it's held memory. + * It release its held memory. * For efficiency, STL containers usually don't * release their actual heap-allocated memory until * destruction (even if Container::clear() is called). diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 35251a9a582..7b2d4274238 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -106,34 +106,17 @@ struct PLNetCost { /* The following arrays are used by the try_swap function for speed. */ -/** - * @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. - */ -struct TSInfo { - /* [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*/ - vtr::vector> layer_ts_bb_edge_new, layer_ts_bb_coord_new; - /* [0...cluster_ctx.clb_nlist.nets().size()-1][0...num_layers-1] -> number of sink pins on a layer*/ - vtr::Matrix ts_layer_sink_pin_count; - /* [0...num_afftected_nets] -> net_id of the affected nets */ - std::vector ts_nets_to_update; - // TSInfo(const TSInfo&) = delete; - // TSInfo(TSInfo&&) = delete; -}; + +//struct TSInfo { +// +//}; } // namespace static struct PLNetCost pl_net_cost; -static struct TSInfo ts_info; - /** * @param net @@ -143,17 +126,6 @@ static struct TSInfo ts_info; static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks); - - - -/** - * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. - * @param net ID of a net affected by a move - */ -static void record_affected_net(const ClusterNetId net); - - - /** * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer * and return the sum of the costs @@ -385,12 +357,12 @@ void NetCostHandler::update_td_delta_costs_(const PlaceDelayModel* delay_model, } ///@brief Record effected nets. -static void record_affected_net(const ClusterNetId net) { +void NetCostHandler::record_affected_net_(const ClusterNetId net) { /* Record effected nets. */ if (pl_net_cost.proposed_net_cost[net] < 0.) { /* Net not marked yet. */ - VTR_ASSERT_SAFE(ts_info.ts_nets_to_update.size() < ts_info.ts_nets_to_update.capacity()); - ts_info.ts_nets_to_update.push_back(net); + VTR_ASSERT_SAFE(ts_nets_to_update_.size() < ts_nets_to_update_.capacity()); + ts_nets_to_update_.push_back(net); /* Flag to say we've marked this net. */ pl_net_cost.proposed_net_cost[net] = 1.; @@ -418,7 +390,7 @@ void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place } /* Record effected nets */ - record_affected_net(net_id); + record_affected_net_(net_id); /* Update the net bounding boxes. */ update_net_bb_(net_id, blk_id, pin_id, moving_blk_inf); @@ -1557,7 +1529,7 @@ static double wirelength_crossing_count(size_t fanout) { } void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { - for (const ClusterNetId ts_net: ts_info.ts_nets_to_update) { + for (const ClusterNetId ts_net: ts_nets_to_update_) { ClusterNetId net_id = ts_net; pl_net_cost.proposed_net_cost[net_id] = get_net_cost_(net_id); @@ -1576,7 +1548,7 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm VTR_ASSERT_SAFE(timing_delta_c == 0.); auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; - ts_info.ts_nets_to_update.resize(0); + ts_nets_to_update_.resize(0); /* Go through all the blocks moved. */ for (const auto& block : blocks_affected.moved_blocks) { @@ -1693,13 +1665,13 @@ void NetCostHandler::update_move_nets() { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& place_move_ctx = placer_ctx_.mutable_move(); - for (const ClusterNetId ts_net : ts_info.ts_nets_to_update) { + for (const ClusterNetId ts_net : ts_nets_to_update_) { ClusterNetId net_id = ts_net; 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_info.ts_layer_sink_pin_count[size_t(net_id)][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]; } if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET) { @@ -1716,7 +1688,7 @@ void NetCostHandler::update_move_nets() { void NetCostHandler::reset_move_nets() { /* Reset the net cost function flags first. */ - for (const ClusterNetId ts_net : ts_info.ts_nets_to_update) { + for (const ClusterNetId ts_net : ts_nets_to_update_) { ClusterNetId net_id = ts_net; pl_net_cost.proposed_net_cost[net_id] = -1; pl_net_cost.bb_update_status[net_id] = NetUpdateState::NOT_UPDATED_YET; @@ -1897,12 +1869,12 @@ void NetCostHandler::free_place_move_structs() { } void NetCostHandler::free_try_swap_net_cost_structs() { - vtr::release_memory(ts_info.ts_bb_edge_new); - vtr::release_memory(ts_info.ts_bb_coord_new); - vtr::release_memory(ts_info.layer_ts_bb_edge_new); - vtr::release_memory(ts_info.layer_ts_bb_coord_new); - ts_info.ts_layer_sink_pin_count.clear(); - vtr::release_memory(ts_info.ts_nets_to_update); + vtr::release_memory(ts_bb_edge_new_); + vtr::release_memory(ts_bb_coord_new_); + vtr::release_memory(layer_ts_bb_edge_new_); + vtr::release_memory(layer_ts_bb_coord_new_); + ts_layer_sink_pin_count_.clear(); + vtr::release_memory(ts_nets_to_update_); } NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) @@ -1912,19 +1884,19 @@ NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool // Either 3D BB or per layer BB data structure are used, not both. if (cube_bb_) { - ts_info.ts_bb_edge_new.resize(num_nets, t_bb()); - ts_info.ts_bb_coord_new.resize(num_nets, t_bb()); + ts_bb_edge_new_.resize(num_nets, t_bb()); + ts_bb_coord_new_.resize(num_nets, t_bb()); comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_bb_cost_, this, std::placeholders::_1); } else { - ts_info.layer_ts_bb_edge_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); - ts_info.layer_ts_bb_coord_new.resize(num_nets, std::vector(num_layers, t_2D_bb())); + 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())); comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_per_layer_bb_cost_, this, std::placeholders::_1); } /* This initializes the whole matrix to OPEN which is an invalid value*/ - ts_info.ts_layer_sink_pin_count.resize({num_nets, size_t(num_layers)}, OPEN); + ts_layer_sink_pin_count_.resize({num_nets, size_t(num_layers)}, OPEN); - ts_info.ts_nets_to_update.resize(num_nets, ClusterNetId::INVALID()); + ts_nets_to_update_.resize(num_nets, ClusterNetId::INVALID()); pl_net_cost.net_cost.resize(num_nets, -1.); pl_net_cost.proposed_net_cost.resize(num_nets, -1.); @@ -1940,31 +1912,31 @@ NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { if (cube_bb_) { get_non_updatable_bb_(net, - ts_info.ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); + ts_bb_coord_new_[net], + ts_layer_sink_pin_count_[size_t(net)]); } else { get_non_updatable_layer_bb_(net, - ts_info.layer_ts_bb_coord_new[net], - ts_info.ts_layer_sink_pin_count[size_t(net)]); + layer_ts_bb_coord_new_[net], + ts_layer_sink_pin_count_[size_t(net)]); } } void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { if (cube_bb_) { update_bb_(net_id, - ts_info.ts_bb_edge_new[net_id], - ts_info.ts_bb_coord_new[net_id], - ts_info.ts_layer_sink_pin_count[size_t(net_id)], + ts_bb_edge_new_[net_id], + ts_bb_coord_new_[net_id], + ts_layer_sink_pin_count_[size_t(net_id)], pin_old_loc, pin_new_loc, is_driver); } else { update_layer_bb_(net_id, - ts_info.layer_ts_bb_edge_new[net_id], - ts_info.layer_ts_bb_coord_new[net_id], - ts_info.ts_layer_sink_pin_count[size_t(net_id)], + layer_ts_bb_edge_new_[net_id], + layer_ts_bb_coord_new_[net_id], + ts_layer_sink_pin_count_[size_t(net_id)], pin_old_loc, pin_new_loc, is_driver); @@ -1973,27 +1945,27 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old double NetCostHandler::get_net_cost_(const ClusterNetId net_id) { if (cube_bb_) { - return ::get_net_cost(net_id, ts_info.ts_bb_coord_new[net_id]); + return ::get_net_cost(net_id, ts_bb_coord_new_[net_id]); } else { - return ::get_net_layer_bb_wire_cost(net_id, ts_info.layer_ts_bb_coord_new[net_id], ts_info.ts_layer_sink_pin_count[size_t(net_id)]); + return ::get_net_layer_bb_wire_cost(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); } } void NetCostHandler::set_ts_bb_coord_(const ClusterNetId net_id) { auto& place_move_ctx = placer_ctx_.mutable_move(); if (cube_bb_) { - place_move_ctx.bb_coords[net_id] = ts_info.ts_bb_coord_new[net_id]; + place_move_ctx.bb_coords[net_id] = ts_bb_coord_new_[net_id]; } else { - place_move_ctx.layer_bb_coords[net_id] = ts_info.layer_ts_bb_coord_new[net_id]; + place_move_ctx.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_ctx_.mutable_move(); if (cube_bb_) { - place_move_ctx.bb_num_on_edges[net_id] = ts_info.ts_bb_edge_new[net_id]; + place_move_ctx.bb_num_on_edges[net_id] = ts_bb_edge_new_[net_id]; } else { - place_move_ctx.layer_bb_num_on_edges[net_id] = ts_info.layer_ts_bb_edge_new[net_id]; + place_move_ctx.layer_bb_num_on_edges[net_id] = layer_ts_bb_edge_new_[net_id]; } } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 913140b07d7..8fc207506ba 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -130,34 +130,29 @@ class NetCostHandler { */ void free_try_swap_net_cost_structs(); -// private: - /** - * @brief This class is used to hide control flows needed to distinguish 2d and 3d placement - */ -// class BBUpdater { -// public: -// BBUpdater() = delete; -// BBUpdater(const BBUpdater&) = delete; -// BBUpdater(BBUpdater&&) = delete; -// BBUpdater& operator=(const BBUpdater&) = delete; -// BBUpdater& operator=(BBUpdater&&) = delete; -// -// BBUpdater(PlacerContext& placer_ctx_, size_t num_nets, bool cube_bb); -// -// private: -// -// PlacerContext& placer_ctx_; -// -// public: -// -// }; - private: bool cube_bb_ = false; PlacerContext& placer_ctx_; std::function comp_bb_cost_functor_; + + /** + * @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. + */ + /* [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*/ + vtr::vector> layer_ts_bb_edge_new_, layer_ts_bb_coord_new_; + /* [0...cluster_ctx.clb_nlist.nets().size()-1][0...num_layers-1] -> number of sink pins on a layer*/ + vtr::Matrix ts_layer_sink_pin_count_; + /* [0...num_afftected_nets] -> net_id of the affected nets */ + std::vector ts_nets_to_update_; + private: /** * @brief Update the bounding box (3D) of the net connected to blk_pin. The old and new locations of the pin are @@ -407,4 +402,10 @@ class NetCostHandler { double comp_per_layer_bb_cost_(e_cost_methods method); double comp_3d_bb_cost_(e_cost_methods method); + /** + * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. + * @param net ID of a net affected by a move + */ + void record_affected_net_(const ClusterNetId net); + }; \ No newline at end of file From f30780e1bc93acef86f9f9674730665668187c2c Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 18:58:30 -0400 Subject: [PATCH 07/36] remove NetCostHandler::free_try_swap_net_cost_structs() --- vpr/src/place/net_cost_handler.cpp | 18 ------------------ vpr/src/place/net_cost_handler.h | 5 ----- vpr/src/place/place.cpp | 8 +++----- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 7b2d4274238..9bf293d1bb3 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -104,15 +104,6 @@ struct PLNetCost { vtr::vector bb_update_status; }; -/* The following arrays are used by the try_swap function for speed. */ - - - -//struct TSInfo { -// -//}; - - } // namespace static struct PLNetCost pl_net_cost; @@ -1868,15 +1859,6 @@ void NetCostHandler::free_place_move_structs() { vtr::release_memory(pl_net_cost.bb_update_status); } -void NetCostHandler::free_try_swap_net_cost_structs() { - vtr::release_memory(ts_bb_edge_new_); - vtr::release_memory(ts_bb_coord_new_); - vtr::release_memory(layer_ts_bb_edge_new_); - vtr::release_memory(layer_ts_bb_coord_new_); - ts_layer_sink_pin_count_.clear(); - vtr::release_memory(ts_nets_to_update_); -} - NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) : cube_bb_(cube_bb) , placer_ctx_(placer_ctx) { diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 8fc207506ba..d091135da16 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -125,11 +125,6 @@ class NetCostHandler { */ void free_place_move_structs(); - /** - * @brief Free (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update data structures. - */ - void free_try_swap_net_cost_structs(); - private: bool cube_bb_ = false; PlacerContext& placer_ctx_; diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 352042e82fc..a3c66098acc 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -195,7 +195,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac PlacerContext& placer_ctx); static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, const bool cube_bb, float place_cost_exp); -static void free_try_swap_structs(NetCostHandler& net_cost_handler); +static void free_try_swap_structs(); static void free_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, @@ -1948,7 +1948,7 @@ static void free_placement_structs(const t_placer_opts& placer_opts, net_cost_handler.free_chan_w_factors_for_place_cost(); - free_try_swap_structs(net_cost_handler); + free_try_swap_structs(); if (noc_opts.noc) { free_noc_placement_structs(); @@ -1967,9 +1967,7 @@ static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, return {placer_ctx, num_nets, cube_bb, place_cost_exp}; } -static void free_try_swap_structs(NetCostHandler& net_cost_handler) { - net_cost_handler.free_try_swap_net_cost_structs(); - +static void free_try_swap_structs() { auto& place_ctx = g_vpr_ctx.mutable_placement(); vtr::release_memory(place_ctx.compressed_block_grids); } From 22c4ea86dc41b41e1f5c0cd5bf9053436199f46c Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 19:10:41 -0400 Subject: [PATCH 08/36] remove static pl_net_cost from net_cost_handler.cpp --- vpr/src/place/net_cost_handler.cpp | 154 ++++++++++------------------- vpr/src/place/net_cost_handler.h | 46 ++++++++- vpr/src/place/place.cpp | 2 - 3 files changed, 94 insertions(+), 108 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 9bf293d1bb3..52bf87eca1f 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -40,15 +40,6 @@ using std::max; using std::min; -/** - * @brief for the states of the bounding box. - * Stored as char for memory efficiency. - */ -enum class NetUpdateState { - NOT_UPDATED_YET, - UPDATED_ONCE, - GOT_FROM_SCRATCH -}; static constexpr int MAX_FANOUT_CROSSING_COUNT = 50; @@ -80,34 +71,9 @@ static vtr::NdMatrix chanx_place_cost_fac({0, 0}); // [0...device_ctx. static vtr::NdMatrix chany_place_cost_fac({0, 0}); // [0...device_ctx.grid.height()-2] namespace { -/** - * @brief For each of the vectors in this struct, there is one entry per cluster level net: - * [0...cluster_ctx.clb_nlist.nets().size()-1]. - * net_cost and proposed_net_cost: Cost of a net, and a temporary cost of a net used during move assessment. - * We also use negative cost values in proposed_net_cost as a flag to indicate that - * the cost of a net has not yet been updated. - * bb_update_status: Flag array to indicate whether the specific bounding box has been updated - * in this particular swap or not. If it has been updated before, the code - * must use the updated data, instead of the out-of-date data passed into the - * subroutine, particularly used in try_swap(). The value NOT_UPDATED_YET - * indicates that the net has not been updated before, UPDATED_ONCE indicated - * that the net has been updated once, if it is going to be updated again, the - * values from the previous update must be used. GOT_FROM_SCRATCH is only - * applicable for nets larger than SMALL_NETS and it indicates that the - * particular bounding box is not incrementally updated, and hence the - * bounding box is got from scratch, so the bounding box would definitely be - * right, DO NOT update again. - */ -struct PLNetCost { - vtr::vector net_cost; - vtr::vector proposed_net_cost; - vtr::vector bb_update_status; -}; -} // namespace - -static struct PLNetCost pl_net_cost; +} // namespace /** * @param net @@ -188,13 +154,6 @@ static double get_net_cost(ClusterNetId net_id, const t_bb& bb); */ static double get_net_wirelength_estimate(ClusterNetId net_id, const t_bb& bb); -/** - * @brief To mitigate round-off errors, every once in a while, the costs of nets are summed up from scratch. - * This functions is called to do that for bb cost. It doesn't calculate the BBs from scratch, it would only add the costs again. - * @return Total bb (wirelength) cost for the placement - */ -static double recompute_bb_cost(); - /** * @brief To get the wirelength cost/est, BB perimeter is multiplied by a factor to approximately correct for the half-perimeter * bounding box wirelength's underestimate of wiring for nets with fanout greater than 2. @@ -233,7 +192,7 @@ void NetCostHandler::update_net_bb_(const ClusterNetId net, if (cluster_ctx.clb_nlist.net_sinks(net).size() < SMALL_NET) { //For small nets brute-force bounding box update is faster - if (pl_net_cost.bb_update_status[net] == NetUpdateState::NOT_UPDATED_YET) { //Only once per-net + if (bb_update_status_[net] == NetUpdateState::NOT_UPDATED_YET) { //Only once per-net get_non_updatable_bb_(net); } } else { @@ -350,13 +309,13 @@ void NetCostHandler::update_td_delta_costs_(const PlaceDelayModel* delay_model, ///@brief Record effected nets. void NetCostHandler::record_affected_net_(const ClusterNetId net) { /* Record effected nets. */ - if (pl_net_cost.proposed_net_cost[net] < 0.) { + if (proposed_net_cost_[net] < 0.) { /* Net not marked yet. */ VTR_ASSERT_SAFE(ts_nets_to_update_.size() < ts_nets_to_update_.capacity()); ts_nets_to_update_.push_back(net); /* Flag to say we've marked this net. */ - pl_net_cost.proposed_net_cost[net] = 1.; + proposed_net_cost_[net] = 1.; } } @@ -556,18 +515,18 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, pin_old_loc.layer_num = max(min(pin_old_loc.layer_num, device_ctx.grid.get_num_layers() - 1), 0); /* Check if the net had been updated before. */ - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { /* The net had been updated from scratch, DO NOT update again! */ return; } - vtr::NdMatrixProxy curr_num_sink_pin_layer = (pl_net_cost.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) ? place_move_ctx.num_sink_pin_layer[size_t(net_id)] : num_sink_pin_layer_new; - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::NOT_UPDATED_YET) { + 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]; - pl_net_cost.bb_update_status[net_id] = NetUpdateState::UPDATED_ONCE; + bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } else { /* The net had been updated before, must use the new values */ curr_bb_coord = &bb_coord_new; @@ -583,7 +542,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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.xmax = curr_bb_edge->xmax - 1; @@ -615,7 +574,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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.xmin = curr_bb_edge->xmin - 1; @@ -656,7 +615,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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.ymax = curr_bb_edge->ymax - 1; @@ -688,7 +647,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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.ymin = curr_bb_edge->ymin - 1; @@ -738,7 +697,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, 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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.layer_max = curr_bb_edge->layer_max - 1; @@ -764,7 +723,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, 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); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { bb_edge_new.layer_min = curr_bb_edge->layer_min - 1; @@ -800,8 +759,8 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, bb_edge_new.layer_max = curr_bb_edge->layer_max; } - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::NOT_UPDATED_YET) { - pl_net_cost.bb_update_status[net_id] = NetUpdateState::UPDATED_ONCE; + if (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) { + bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } } @@ -821,19 +780,19 @@ void NetCostHandler::update_layer_bb_(ClusterNetId net_id, pin_old_loc.y = max(min(pin_old_loc.y, device_ctx.grid.height() - 2), 1); //-2 for no perim channels /* Check if the net had been updated before. */ - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { /* The net had been updated from scratch, DO NOT update again! */ return; } - const vtr::NdMatrixProxy curr_layer_pin_sink_count = (pl_net_cost.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) ? place_move_ctx.num_sink_pin_layer[size_t(net_id)] : bb_pin_sink_count_new; const std::vector*curr_bb_edge, *curr_bb_coord; - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::NOT_UPDATED_YET) { + 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]; - pl_net_cost.bb_update_status[net_id] = NetUpdateState::UPDATED_ONCE; + bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } else { /* The net had been updated before, must use the new values */ curr_bb_edge = &bb_edge_new; @@ -875,8 +834,8 @@ void NetCostHandler::update_layer_bb_(ClusterNetId net_id, bb_coord_new); } - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::NOT_UPDATED_YET) { - pl_net_cost.bb_update_status[net_id] = NetUpdateState::UPDATED_ONCE; + if (bb_update_status_[net_id] == NetUpdateState::NOT_UPDATED_YET) { + bb_update_status_[net_id] = NetUpdateState::UPDATED_ONCE; } } @@ -907,7 +866,7 @@ inline void NetCostHandler::update_bb_same_layer_(ClusterNetId net_id, curr_bb_coord[layer_num].xmax, bb_edge_new[layer_num].xmax, bb_coord_new[layer_num].xmax); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -930,7 +889,7 @@ inline void NetCostHandler::update_bb_same_layer_(ClusterNetId net_id, curr_bb_coord[layer_num].xmin, bb_edge_new[layer_num].xmin, bb_coord_new[layer_num].xmin); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -954,7 +913,7 @@ inline void NetCostHandler::update_bb_same_layer_(ClusterNetId net_id, curr_bb_coord[layer_num].ymax, bb_edge_new[layer_num].ymax, bb_coord_new[layer_num].ymax); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -977,7 +936,7 @@ inline void NetCostHandler::update_bb_same_layer_(ClusterNetId net_id, curr_bb_coord[layer_num].ymin, bb_edge_new[layer_num].ymin, bb_coord_new[layer_num].ymin); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -1022,7 +981,7 @@ inline void NetCostHandler::update_bb_layer_changed_(ClusterNetId net_id, curr_bb_coord[old_layer_num].xmax, bb_edge_new[old_layer_num].xmax, bb_coord_new[old_layer_num].xmax); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } else if (x_old == curr_bb_coord[old_layer_num].xmin) { @@ -1034,7 +993,7 @@ inline void NetCostHandler::update_bb_layer_changed_(ClusterNetId net_id, curr_bb_coord[old_layer_num].xmin, bb_edge_new[old_layer_num].xmin, bb_coord_new[old_layer_num].xmin); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -1048,7 +1007,7 @@ inline void NetCostHandler::update_bb_layer_changed_(ClusterNetId net_id, curr_bb_coord[old_layer_num].ymax, bb_edge_new[old_layer_num].ymax, bb_coord_new[old_layer_num].ymax); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } else if (y_old == curr_bb_coord[old_layer_num].ymin) { @@ -1060,7 +1019,7 @@ inline void NetCostHandler::update_bb_layer_changed_(ClusterNetId net_id, curr_bb_coord[old_layer_num].ymin, bb_edge_new[old_layer_num].ymin, bb_coord_new[old_layer_num].ymin); - if (pl_net_cost.bb_update_status[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { + if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { return; } } @@ -1100,7 +1059,7 @@ inline void NetCostHandler::update_bb_edge_(ClusterNetId net_id, bb_edge_new, bb_coord_new, bb_layer_pin_sink_count); - pl_net_cost.bb_update_status[net_id] = NetUpdateState::GOT_FROM_SCRATCH; + bb_update_status_[net_id] = NetUpdateState::GOT_FROM_SCRATCH; return; } else { new_num_block_on_edge = old_num_block_on_edge - 1; @@ -1493,19 +1452,19 @@ static double get_net_wirelength_from_layer_bb(ClusterNetId /* net_id */, return (ncost); } -static double recompute_bb_cost() { +double NetCostHandler::recompute_bb_cost_() { double cost = 0; auto& cluster_ctx = g_vpr_ctx.clustering(); - for (auto net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ + for (ClusterNetId net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ /* Bounding boxes don't have to be recomputed; they're correct. */ - cost += pl_net_cost.net_cost[net_id]; + cost += net_cost_[net_id]; } } - return (cost); + return cost; } static double wirelength_crossing_count(size_t fanout) { @@ -1523,9 +1482,9 @@ void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { for (const ClusterNetId ts_net: ts_nets_to_update_) { ClusterNetId net_id = ts_net; - pl_net_cost.proposed_net_cost[net_id] = get_net_cost_(net_id); + proposed_net_cost_[net_id] = get_net_cost_(net_id); - bb_delta_c += pl_net_cost.proposed_net_cost[net_id] - pl_net_cost.net_cost[net_id]; + bb_delta_c += proposed_net_cost_[net_id] - net_cost_[net_id]; } } @@ -1596,8 +1555,8 @@ double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - pl_net_cost.net_cost[net_id] = get_net_cost(net_id, place_move_ctx.bb_coords[net_id]); - cost += pl_net_cost.net_cost[net_id]; + net_cost_[net_id] = get_net_cost(net_id, place_move_ctx.bb_coords[net_id]); + cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); } @@ -1632,10 +1591,10 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - pl_net_cost.net_cost[net_id] = get_net_layer_bb_wire_cost(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); - cost += pl_net_cost.net_cost[net_id]; + net_cost_[net_id] = get_net_layer_bb_wire_cost(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) expected_wirelength += get_net_wirelength_from_layer_bb(net_id, place_move_ctx.layer_bb_coords[net_id], @@ -1669,11 +1628,11 @@ void NetCostHandler::update_move_nets() { set_ts_edge_(net_id); } - pl_net_cost.net_cost[net_id] = pl_net_cost.proposed_net_cost[net_id]; + net_cost_[net_id] = proposed_net_cost_[net_id]; /* negative proposed_net_cost value is acting as a flag to mean not computed yet. */ - pl_net_cost.proposed_net_cost[net_id] = -1; - pl_net_cost.bb_update_status[net_id] = NetUpdateState::NOT_UPDATED_YET; + proposed_net_cost_[net_id] = -1; + bb_update_status_[net_id] = NetUpdateState::NOT_UPDATED_YET; } } @@ -1681,8 +1640,8 @@ void NetCostHandler::reset_move_nets() { /* Reset the net cost function flags first. */ for (const ClusterNetId ts_net : ts_nets_to_update_) { ClusterNetId net_id = ts_net; - pl_net_cost.proposed_net_cost[net_id] = -1; - pl_net_cost.bb_update_status[net_id] = NetUpdateState::NOT_UPDATED_YET; + proposed_net_cost_[net_id] = -1; + bb_update_status_[net_id] = NetUpdateState::NOT_UPDATED_YET; } } @@ -1702,7 +1661,7 @@ void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_op } }; - double new_bb_cost = recompute_bb_cost(); + double new_bb_cost = recompute_bb_cost_(); check_and_print_cost(new_bb_cost, costs->bb_cost, "bb_cost"); costs->bb_cost = new_bb_cost; @@ -1840,8 +1799,7 @@ void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_c chany_place_cost_fac[high][low] = 1.0f; } - chany_place_cost_fac[high][low] = (high - low + 1.) - / chany_place_cost_fac[high][low]; + chany_place_cost_fac[high][low] = (high - low + 1.) / chany_place_cost_fac[high][low]; chany_place_cost_fac[high][low] = pow( (double)chany_place_cost_fac[high][low], (double)place_cost_exp); @@ -1853,12 +1811,6 @@ void NetCostHandler::free_chan_w_factors_for_place_cost() { chany_place_cost_fac.clear(); } -void NetCostHandler::free_place_move_structs() { - vtr::release_memory(pl_net_cost.net_cost); - vtr::release_memory(pl_net_cost.proposed_net_cost); - vtr::release_memory(pl_net_cost.bb_update_status); -} - NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) : cube_bb_(cube_bb) , placer_ctx_(placer_ctx) { @@ -1880,12 +1832,12 @@ NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool ts_nets_to_update_.resize(num_nets, ClusterNetId::INVALID()); - pl_net_cost.net_cost.resize(num_nets, -1.); - pl_net_cost.proposed_net_cost.resize(num_nets, -1.); + net_cost_.resize(num_nets, -1.); + proposed_net_cost_.resize(num_nets, -1.); /* Used to store costs for moves not yet made and to indicate when a net's * * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * * been recomputed. */ - pl_net_cost.bb_update_status.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); + bb_update_status_.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index d091135da16..033d4cb85dd 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -120,17 +120,22 @@ class NetCostHandler { */ void free_chan_w_factors_for_place_cost(); - /** - * @brief Free net_cost, proposed_net_cost, and bb_updated_before data structures. - */ - void free_place_move_structs(); - private: bool cube_bb_ = false; PlacerContext& placer_ctx_; std::function comp_bb_cost_functor_; + /** + * @brief for the states of the bounding box. + * Stored as char for memory efficiency. + */ + enum class NetUpdateState { + NOT_UPDATED_YET, + UPDATED_ONCE, + GOT_FROM_SCRATCH + }; + /** * @brief The wire length estimation is based on the bounding box of the net. In the case of the 2D architecture, @@ -148,6 +153,30 @@ class NetCostHandler { /* [0...num_afftected_nets] -> net_id of the affected nets */ std::vector ts_nets_to_update_; + + /** + * @brief For each of the vectors in this struct, there is one entry per cluster level net: + * [0...cluster_ctx.clb_nlist.nets().size()-1]. + * net_cost and proposed_net_cost: Cost of a net, and a temporary cost of a net used during move assessment. + * We also use negative cost values in proposed_net_cost as a flag to indicate that + * the cost of a net has not yet been updated. + * bb_update_status: Flag array to indicate whether the specific bounding box has been updated + * in this particular swap or not. If it has been updated before, the code + * must use the updated data, instead of the out-of-date data passed into the + * subroutine, particularly used in try_swap(). The value NOT_UPDATED_YET + * indicates that the net has not been updated before, UPDATED_ONCE indicated + * that the net has been updated once, if it is going to be updated again, the + * values from the previous update must be used. GOT_FROM_SCRATCH is only + * applicable for nets larger than SMALL_NETS and it indicates that the + * particular bounding box is not incrementally updated, and hence the + * bounding box is got from scratch, so the bounding box would definitely be + * right, DO NOT update again. + */ + vtr::vector net_cost_; + vtr::vector proposed_net_cost_; + vtr::vector bb_update_status_; + + private: /** * @brief Update the bounding box (3D) of the net connected to blk_pin. The old and new locations of the pin are @@ -403,4 +432,11 @@ class NetCostHandler { */ void record_affected_net_(const ClusterNetId net); + /** + * @brief To mitigate round-off errors, every once in a while, the costs of nets are summed up from scratch. + * This functions is called to do that for bb cost. It doesn't calculate the BBs from scratch, it would only add the costs again. + * @return Total bb (wirelength) cost for the placement + */ + double recompute_bb_cost_(); + }; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index a3c66098acc..6fb1daeb0a3 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -1935,8 +1935,6 @@ static void free_placement_structs(const t_placer_opts& placer_opts, free_placement_macros_structs(); - net_cost_handler.free_place_move_structs(); - vtr::release_memory(place_move_ctx.bb_coords); vtr::release_memory(place_move_ctx.bb_num_on_edges); vtr::release_memory(place_move_ctx.bb_coords); From 45a4af43c345f830eca81347a1934b25689cf9fd Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 5 Aug 2024 19:23:12 -0400 Subject: [PATCH 09/36] remove static chanx_place_cost_fac and chany_place_cost_fac from net_cost_handler --- vpr/src/place/net_cost_handler.cpp | 108 ++++++++--------------------- vpr/src/place/net_cost_handler.h | 38 ++++++++-- vpr/src/place/place.cpp | 10 +-- 3 files changed, 66 insertions(+), 90 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 52bf87eca1f..16c982d1b8c 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -34,9 +34,6 @@ #include "noc_place_utils.h" #include "vtr_math.h" -#include -#include - using std::max; using std::min; @@ -58,23 +55,6 @@ static const float cross_count[MAX_FANOUT_CROSSING_COUNT] = {/* [0..49] */ 1.0, 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148, 2.7410, 2.7671, 2.7933}; -/** - * @brief Matrices below are used to precompute the inverse of the average - * number of tracks per channel between [subhigh] and [sublow]. Access - * them as chan?_place_cost_fac[subhigh][sublow]. They are used to - * speed up the computation of the cost function that takes the length - * of the net bounding box in each dimension, divided by the average - * number of tracks in that direction; for other cost functions they - * will never be used. - */ -static vtr::NdMatrix chanx_place_cost_fac({0, 0}); // [0...device_ctx.grid.width()-2] -static vtr::NdMatrix chany_place_cost_fac({0, 0}); // [0...device_ctx.grid.height()-2] - -namespace { - - -} // namespace - /** * @param net * @param moved_blocks @@ -83,17 +63,6 @@ namespace { static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks); -/** - * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer - * and return the sum of the costs - * @param net_id ID of the net which cost is requested - * @param bb Per-layer bounding box of the net - * @return Wirelength cost of the net - */ -static double get_net_layer_bb_wire_cost(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count); - /** * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer * and return the sum of the lengths @@ -138,13 +107,7 @@ static void add_block_to_bb(const t_physical_tile_loc& new_pin_loc, t_2D_bb& bb_edge_new, t_2D_bb& bb_coord_new); -/** - * @brief Given the 3D BB, calculate the wire-length cost of the net - * @param net_id ID of the net which cost is requested - * @param bb Bounding box of the net - * @return Wirelength cost of the net - */ -static double get_net_cost(ClusterNetId net_id, const t_bb& bb); + /** * @brief Given the 3D BB, calculate the wire-length estimate of the net @@ -621,7 +584,7 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, bb_edge_new.ymax = curr_bb_edge->ymax - 1; bb_coord_new.ymax = curr_bb_coord->ymax; } - } else { /* Move down, old postion was not at ymax. */ + } else { /* Move down, old position was not at ymax. */ bb_coord_new.ymax = curr_bb_coord->ymax; bb_edge_new.ymax = curr_bb_edge->ymax; } @@ -1340,7 +1303,7 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, } } -static double get_net_cost(ClusterNetId net_id, const t_bb& bb) { +double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { /* Finds the cost due to one net by looking at its coordinate bounding * * box. */ auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1355,15 +1318,15 @@ static double get_net_cost(ClusterNetId net_id, const t_bb& bb) { * channel capacity. Do this for x, then y direction and add. */ double ncost; - ncost = (bb.xmax - bb.xmin + 1) * crossing * chanx_place_cost_fac[bb.ymax][bb.ymin - 1]; - ncost += (bb.ymax - bb.ymin + 1) * crossing * chany_place_cost_fac[bb.xmax][bb.xmin - 1]; + ncost = (bb.xmax - bb.xmin + 1) * crossing * chanx_place_cost_fac_[bb.ymax][bb.ymin - 1]; + ncost += (bb.ymax - bb.ymin + 1) * crossing * chany_place_cost_fac_[bb.xmax][bb.xmin - 1]; return (ncost); } -static double get_net_layer_bb_wire_cost(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count) { +double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, + const std::vector& bb, + const vtr::NdMatrixProxy layer_pin_sink_count) { /* Finds the cost due to one net by looking at its coordinate bounding * * box. */ @@ -1391,10 +1354,10 @@ static double get_net_layer_bb_wire_cost(ClusterNetId /* net_id */, * channel capacity. Do this for x, then y direction and add. */ ncost += (bb[layer_num].xmax - bb[layer_num].xmin + 1) * crossing - * chanx_place_cost_fac[bb[layer_num].ymax][bb[layer_num].ymin - 1]; + * chanx_place_cost_fac_[bb[layer_num].ymax][bb[layer_num].ymin - 1]; ncost += (bb[layer_num].ymax - bb[layer_num].ymin + 1) * crossing - * chany_place_cost_fac[bb[layer_num].xmax][bb[layer_num].xmin - 1]; + * chany_place_cost_fac_[bb[layer_num].xmax][bb[layer_num].xmin - 1]; } return (ncost); @@ -1414,7 +1377,6 @@ static double get_net_wirelength_estimate(ClusterNetId net_id, const t_bb& bb) { double ncost; ncost = (bb.xmax - bb.xmin + 1) * crossing; - ncost += (bb.ymax - bb.ymin + 1) * crossing; return ncost; @@ -1555,7 +1517,7 @@ double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - net_cost_[net_id] = get_net_cost(net_id, place_move_ctx.bb_coords[net_id]); + net_cost_[net_id] = get_net_cost_(net_id, place_move_ctx.bb_coords[net_id]); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); @@ -1591,7 +1553,7 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - net_cost_[net_id] = get_net_layer_bb_wire_cost(net_id, + net_cost_[net_id] = get_net_layer_bb_wire_cost_(net_id, place_move_ctx.layer_bb_coords[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); cost += net_cost_[net_id]; @@ -1730,18 +1692,18 @@ void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_c for simplicity so we can use the vtr utility matrix functions. */ - chanx_place_cost_fac.resize({device_ctx.grid.height(), device_ctx.grid.height() + 1}); - chany_place_cost_fac.resize({device_ctx.grid.width(), device_ctx.grid.width() + 1}); + chanx_place_cost_fac_.resize({device_ctx.grid.height(), device_ctx.grid.height() + 1}); + chany_place_cost_fac_.resize({device_ctx.grid.width(), device_ctx.grid.width() + 1}); /* First compute the number of tracks between channel high and channel * * low, inclusive, in an efficient manner. */ - chanx_place_cost_fac[0][0] = device_ctx.chan_width.x_list[0]; + chanx_place_cost_fac_[0][0] = device_ctx.chan_width.x_list[0]; for (size_t high = 1; high < device_ctx.grid.height(); high++) { - chanx_place_cost_fac[high][high] = device_ctx.chan_width.x_list[high]; + chanx_place_cost_fac_[high][high] = device_ctx.chan_width.x_list[high]; for (size_t low = 0; low < high; low++) { - chanx_place_cost_fac[high][low] = chanx_place_cost_fac[high - 1][low] + device_ctx.chan_width.x_list[high]; + chanx_place_cost_fac_[high][low] = chanx_place_cost_fac_[high - 1][low] + device_ctx.chan_width.x_list[high]; } } @@ -1760,27 +1722,24 @@ void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_c * will result in infinite wiring capacity normalization * * factor, and extremely bad placer behaviour. Hence we change * * this to a small (1 track) channel capacity instead. */ - if (chanx_place_cost_fac[high][low] == 0.0f) { + if (chanx_place_cost_fac_[high][low] == 0.0f) { VTR_LOG_WARN("CHANX place cost fac is 0 at %d %d\n", high, low); - chanx_place_cost_fac[high][low] = 1.0f; + chanx_place_cost_fac_[high][low] = 1.0f; } - chanx_place_cost_fac[high][low] = (high - low + 1.) - / chanx_place_cost_fac[high][low]; - chanx_place_cost_fac[high][low] = pow( - (double)chanx_place_cost_fac[high][low], - (double)place_cost_exp); + chanx_place_cost_fac_[high][low] = (high - low + 1.) / chanx_place_cost_fac_[high][low]; + chanx_place_cost_fac_[high][low] = pow((double)chanx_place_cost_fac_[high][low], (double)place_cost_exp); } /* Now do the same thing for the y-directed channels. First get the * * number of tracks between channel high and channel low, inclusive. */ - chany_place_cost_fac[0][0] = device_ctx.chan_width.y_list[0]; + chany_place_cost_fac_[0][0] = device_ctx.chan_width.y_list[0]; for (size_t high = 1; high < device_ctx.grid.width(); high++) { - chany_place_cost_fac[high][high] = device_ctx.chan_width.y_list[high]; + chany_place_cost_fac_[high][high] = device_ctx.chan_width.y_list[high]; for (size_t low = 0; low < high; low++) { - chany_place_cost_fac[high][low] = chany_place_cost_fac[high - 1][low] + device_ctx.chan_width.y_list[high]; + chany_place_cost_fac_[high][low] = chany_place_cost_fac_[high - 1][low] + device_ctx.chan_width.y_list[high]; } } @@ -1794,23 +1753,16 @@ void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_c * will result in infinite wiring capacity normalization * * factor, and extremely bad placer behaviour. Hence we change * * this to a small (1 track) channel capacity instead. */ - if (chany_place_cost_fac[high][low] == 0.0f) { + if (chany_place_cost_fac_[high][low] == 0.0f) { VTR_LOG_WARN("CHANY place cost fac is 0 at %d %d\n", high, low); - chany_place_cost_fac[high][low] = 1.0f; + chany_place_cost_fac_[high][low] = 1.0f; } - chany_place_cost_fac[high][low] = (high - low + 1.) / chany_place_cost_fac[high][low]; - chany_place_cost_fac[high][low] = pow( - (double)chany_place_cost_fac[high][low], - (double)place_cost_exp); + chany_place_cost_fac_[high][low] = (high - low + 1.) / chany_place_cost_fac_[high][low]; + chany_place_cost_fac_[high][low] = pow((double)chany_place_cost_fac_[high][low], (double)place_cost_exp); } } -void NetCostHandler::free_chan_w_factors_for_place_cost() { - chanx_place_cost_fac.clear(); - chany_place_cost_fac.clear(); -} - NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) : cube_bb_(cube_bb) , placer_ctx_(placer_ctx) { @@ -1879,10 +1831,10 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old double NetCostHandler::get_net_cost_(const ClusterNetId net_id) { if (cube_bb_) { - return ::get_net_cost(net_id, ts_bb_coord_new_[net_id]); + return get_net_cost_(net_id, ts_bb_coord_new_[net_id]); } else { - return ::get_net_layer_bb_wire_cost(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); + return get_net_layer_bb_wire_cost_(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); } } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 033d4cb85dd..fb7f53822aa 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -4,6 +4,8 @@ #include "move_transactions.h" #include "place_util.h" +#include + class PlacerContext; /** @@ -115,11 +117,6 @@ class NetCostHandler { const PlacerCriticalities* criticalities, t_placer_costs* costs); - /** - * @brief Frees the chanx_place_cost_fac and chany_place_cost_fac arrays. - */ - void free_chan_w_factors_for_place_cost(); - private: bool cube_bb_ = false; PlacerContext& placer_ctx_; @@ -176,6 +173,18 @@ class NetCostHandler { vtr::vector proposed_net_cost_; vtr::vector bb_update_status_; + /** + * @brief Matrices below are used to precompute the inverse of the average + * number of tracks per channel between [subhigh] and [sublow]. Access + * them as chan?_place_cost_fac[subhigh][sublow]. They are used to + * speed up the computation of the cost function that takes the length + * of the net bounding box in each dimension, divided by the average + * number of tracks in that direction; for other cost functions they + * will never be used. + */ + vtr::NdMatrix chanx_place_cost_fac_; // [0...device_ctx.grid.width()-2] + vtr::NdMatrix chany_place_cost_fac_; // [0...device_ctx.grid.height()-2] + private: /** @@ -439,4 +448,23 @@ class NetCostHandler { */ double recompute_bb_cost_(); + /** + * @brief Given the 3D BB, calculate the wire-length cost of the net + * @param net_id ID of the net which cost is requested + * @param bb Bounding box of the net + * @return Wirelength cost of the net + */ + double get_net_cost_(ClusterNetId net_id, const t_bb& bb); + + /** + * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer + * and return the sum of the costs + * @param net_id ID of the net which cost is requested + * @param bb Per-layer bounding box of the net + * @return Wirelength cost of the net + */ + double get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, + const std::vector& bb, + const vtr::NdMatrixProxy layer_pin_sink_count); + }; \ No newline at end of file diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 6fb1daeb0a3..36428cff692 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -199,8 +199,7 @@ static void free_try_swap_structs(); static void free_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx, - NetCostHandler& net_cost_handler); + PlacerContext& placer_ctx); static e_move_result try_swap(const t_annealing_state* state, t_placer_costs* costs, @@ -976,7 +975,7 @@ void try_place(const Netlist<>& net_list, write_noc_placement_file(noc_opts.noc_placement_file_name, blk_loc_registry.block_locs()); } - free_placement_structs(placer_opts, noc_opts, placer_ctx, net_cost_handler); + free_placement_structs(placer_opts, noc_opts, placer_ctx); free_try_swap_arrays(); print_timing_stats("Placement Quench", post_quench_timing_stats, @@ -1918,8 +1917,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac * elsewhere). */ static void free_placement_structs(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, - PlacerContext& placer_ctx, - NetCostHandler& net_cost_handler) { + PlacerContext& placer_ctx) { auto& place_move_ctx = placer_ctx.mutable_move(); if (placer_opts.place_algorithm.is_timing_driven()) { @@ -1944,8 +1942,6 @@ static void free_placement_structs(const t_placer_opts& placer_opts, place_move_ctx.num_sink_pin_layer.clear(); - net_cost_handler.free_chan_w_factors_for_place_cost(); - free_try_swap_structs(); if (noc_opts.noc) { From 72ebdab085a1613f2db305d767438a6485115555 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 11:47:57 -0400 Subject: [PATCH 10/36] remove alloc_and_load_try_swap_structs() --- vpr/src/place/place.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 36428cff692..53d6d6af98f 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -194,7 +194,6 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac int num_directs, PlacerContext& placer_ctx); -static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, const bool cube_bb, float place_cost_exp); static void free_try_swap_structs(); static void free_placement_structs(const t_placer_opts& placer_opts, @@ -1910,7 +1909,10 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac allocate_and_load_noc_placement_structs(); } - return alloc_and_load_try_swap_structs(placer_ctx, place_ctx.cube_bb, placer_opts.place_cost_exp); + + place_ctx.compressed_block_grids = create_compressed_block_grids(); + + return {placer_ctx, num_nets, place_ctx.cube_bb, placer_opts.place_cost_exp}; } /* Frees the major structures needed by the placer (and not needed * @@ -1949,18 +1951,6 @@ static void free_placement_structs(const t_placer_opts& placer_opts, } } -static NetCostHandler alloc_and_load_try_swap_structs(PlacerContext& placer_ctx, const bool cube_bb, float place_cost_exp) { - /* Allocate the local bb_coordinate storage, etc. only once. */ - /* Allocate with size cluster_ctx.clb_nlist.nets().size() for any number of nets affected. */ - auto& cluster_ctx = g_vpr_ctx.clustering(); - - auto& place_ctx = g_vpr_ctx.mutable_placement(); - place_ctx.compressed_block_grids = create_compressed_block_grids(); - - size_t num_nets = cluster_ctx.clb_nlist.nets().size(); - return {placer_ctx, num_nets, cube_bb, place_cost_exp}; -} - static void free_try_swap_structs() { auto& place_ctx = g_vpr_ctx.mutable_placement(); vtr::release_memory(place_ctx.compressed_block_grids); From 6fa05202656d6e00aec2132da5def366592cc863 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 12:43:16 -0400 Subject: [PATCH 11/36] added some comments --- vpr/src/place/net_cost_handler.cpp | 432 ++++++++++++++--------------- vpr/src/place/net_cost_handler.h | 49 ++-- 2 files changed, 240 insertions(+), 241 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 16c982d1b8c..f258711ffe0 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -128,6 +128,213 @@ static double wirelength_crossing_count(size_t fanout); /******************************* End of Function definitions ************************************/ + +NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) + : cube_bb_(cube_bb) + , placer_ctx_(placer_ctx) { + const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); + + // Either 3D BB or per layer BB data structure are used, not both. + if (cube_bb_) { + ts_bb_edge_new_.resize(num_nets, t_bb()); + ts_bb_coord_new_.resize(num_nets, t_bb()); + comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_bb_cost_, this, std::placeholders::_1); + } 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())); + comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_per_layer_bb_cost_, this, std::placeholders::_1); + } + + /* 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); + + ts_nets_to_update_.resize(num_nets, ClusterNetId::INVALID()); + + // negative net costs mean the cost is not valid. + net_cost_.resize(num_nets, -1.); + proposed_net_cost_.resize(num_nets, -1.); + + /* Used to store costs for moves not yet made and to indicate when a net's + * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't + * been recomputed. */ + bb_update_status_.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); + + alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); +} + +void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp) { + /* Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac * + * arrays with the inverse of the average number of tracks per channel * + * between [subhigh] and [sublow]. This is only useful for the cost * + * function that takes the length of the net bounding box in each * + * dimension divided by the average number of tracks in that direction. * + * For other cost functions, you don't have to bother calling this * + * routine; when using the cost function described above, however, you * + * must always call this routine after you call init_chan and before * + * you do any placement cost determination. The place_cost_exp factor * + * specifies to what power the width of the channel should be taken -- * + * larger numbers make narrower channels more expensive. */ + + auto& device_ctx = g_vpr_ctx.device(); + + const size_t grid_height = device_ctx.grid.height(); + const size_t grid_width = device_ctx.grid.width(); + + /* Access arrays below as chan?_place_cost_fac[subhigh][sublow]. Since subhigh must be greater than or + * equal to sublow, we will only access the lower half of a matrix, but we allocate the whole matrix anyway + * for simplicity, so we can use the vtr utility matrix functions. */ + chanx_place_cost_fac_.resize({grid_height, grid_height + 1}); + chany_place_cost_fac_.resize({grid_width, grid_width + 1}); + + // First compute the number of tracks between channel high and channel low, inclusive. + chanx_place_cost_fac_[0][0] = device_ctx.chan_width.x_list[0]; + + for (size_t high = 1; high < grid_height; high++) { + chanx_place_cost_fac_[high][high] = device_ctx.chan_width.x_list[high]; + for (size_t low = 0; low < high; low++) { + chanx_place_cost_fac_[high][low] = chanx_place_cost_fac_[high - 1][low] + device_ctx.chan_width.x_list[high]; + } + } + + /* Now compute the inverse of the average number of tracks per channel * + * between high and low. The cost function divides by the average * + * number of tracks per channel, so by storing the inverse I convert * + * this to a faster multiplication. Take this final number to the * + * place_cost_exp power -- numbers other than one mean this is no * + * longer a simple "average number of tracks"; it is some power of * + * that, allowing greater penalization of narrow channels. */ + for (size_t high = 0; high < grid_height; high++) + for (size_t low = 0; low <= high; low++) { + /* Since we will divide the wiring cost by the average channel * + * capacity between high and low, having only 0 width channels * + * will result in infinite wiring capacity normalization * + * factor, and extremely bad placer behaviour. Hence we change * + * this to a small (1 track) channel capacity instead. */ + if (chanx_place_cost_fac_[high][low] == 0.0f) { + VTR_LOG_WARN("CHANX place cost fac is 0 at %d %d\n", high, low); + chanx_place_cost_fac_[high][low] = 1.0f; + } + + chanx_place_cost_fac_[high][low] = (high - low + 1.) / chanx_place_cost_fac_[high][low]; + chanx_place_cost_fac_[high][low] = pow((double)chanx_place_cost_fac_[high][low], (double)place_cost_exp); + } + + /* Now do the same thing for the y-directed channels. First get the + * number of tracks between channel high and channel low, inclusive. */ + chany_place_cost_fac_[0][0] = device_ctx.chan_width.y_list[0]; + + for (size_t high = 1; high < grid_width; high++) { + chany_place_cost_fac_[high][high] = device_ctx.chan_width.y_list[high]; + for (size_t low = 0; low < high; low++) { + chany_place_cost_fac_[high][low] = chany_place_cost_fac_[high - 1][low] + device_ctx.chan_width.y_list[high]; + } + } + + /* Now compute the inverse of the average number of tracks per channel + * between high and low. Take to specified power. */ + for (size_t high = 0; high < grid_width; high++) + for (size_t low = 0; low <= high; low++) { + /* Since we will divide the wiring cost by the average channel * + * capacity between high and low, having only 0 width channels * + * will result in infinite wiring capacity normalization * + * factor, and extremely bad placer behaviour. Hence we change * + * this to a small (1 track) channel capacity instead. */ + if (chany_place_cost_fac_[high][low] == 0.0f) { + VTR_LOG_WARN("CHANY place cost fac is 0 at %d %d\n", high, low); + chany_place_cost_fac_[high][low] = 1.0f; + } + + chany_place_cost_fac_[high][low] = (high - low + 1.) / chany_place_cost_fac_[high][low]; + chany_place_cost_fac_[high][low] = pow((double)chany_place_cost_fac_[high][low], (double)place_cost_exp); + } +} + +double NetCostHandler::comp_bb_cost(e_cost_methods method) { + return comp_bb_cost_functor_(method); +} + +double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { + auto& cluster_ctx = g_vpr_ctx.clustering(); + auto& place_move_ctx = placer_ctx_.mutable_move(); + + double cost = 0; + double expected_wirelength = 0.0; + + for (ClusterNetId net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ + if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ + /* 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)]); + } else { + get_non_updatable_bb_(net_id, + place_move_ctx.bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + } + + net_cost_[net_id] = get_net_cost_(net_id, place_move_ctx.bb_coords[net_id]); + cost += net_cost_[net_id]; + if (method == e_cost_methods::CHECK) { + expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); + } + } + } + + if (method == e_cost_methods::CHECK) { + VTR_LOG("\n"); + VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n", + expected_wirelength); + } + + return cost; +} + +double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { + auto& cluster_ctx = g_vpr_ctx.clustering(); + auto& place_move_ctx = placer_ctx_.mutable_move(); + + double cost = 0; + double expected_wirelength = 0.0; + + for (ClusterNetId net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ + if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ + /* 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_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)]); + } else { + get_non_updatable_layer_bb_(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + } + + net_cost_[net_id] = get_net_layer_bb_wire_cost_(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + cost += net_cost_[net_id]; + if (method == e_cost_methods::CHECK) { + expected_wirelength += get_net_wirelength_from_layer_bb(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + } + } + } + + if (method == e_cost_methods::CHECK) { + VTR_LOG("\n"); + VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n", + expected_wirelength); + } + + return cost; +} + //Returns true if 'net' is driven by one of the blocks in 'blocks_affected' static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks) { @@ -321,8 +528,8 @@ void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place } void NetCostHandler::get_non_updatable_bb_(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer) { + t_bb& bb_coord_new, + vtr::NdMatrixProxy num_sink_pin_layer) { //TODO: account for multiple physical pin instances per logical pin auto& cluster_ctx = g_vpr_ctx.clustering(); auto& device_ctx = g_vpr_ctx.device(); @@ -1074,9 +1281,9 @@ 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) { + t_bb& coords, + t_bb& num_on_edges, + vtr::NdMatrixProxy num_sink_pin_layer) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& device_ctx = g_vpr_ctx.device(); auto& grid = device_ctx.grid; @@ -1173,8 +1380,7 @@ void NetCostHandler::get_bb_from_scratch_(ClusterNetId net_id, num_sink_pin_layer[pin_layer]++; } - /* Copy the coordinates and number on edges information into the proper * - * structures. */ + // Copy the coordinates and number on edges information into the proper structures. coords.xmin = xmin; coords.xmax = xmax; coords.ymin = ymin; @@ -1213,7 +1419,6 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, std::vector num_sink_pin_layer(num_layers, 0); - ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; int pnum_src = placer_ctx_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); @@ -1304,11 +1509,10 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, } double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { - /* Finds the cost due to one net by looking at its coordinate bounding * - * box. */ + // Finds the cost due to one net by looking at its coordinate bounding box. auto& cluster_ctx = g_vpr_ctx.clustering(); - double crossing = wirelength_crossing_count( cluster_ctx.clb_nlist.net_pins(net_id).size()); + double crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size()); /* Could insert a check for xmin == xmax. In that case, assume * * connection will be made with no bends and hence no x-cost. * @@ -1321,7 +1525,7 @@ double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { ncost = (bb.xmax - bb.xmin + 1) * crossing * chanx_place_cost_fac_[bb.ymax][bb.ymin - 1]; ncost += (bb.ymax - bb.ymin + 1) * crossing * chany_place_cost_fac_[bb.xmax][bb.xmin - 1]; - return (ncost); + return ncost; } double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, @@ -1492,86 +1696,6 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm set_bb_delta_cost_(bb_delta_c); } -double NetCostHandler::comp_bb_cost(e_cost_methods method) { - return comp_bb_cost_functor_(method); -} - -double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { - double cost = 0; - double expected_wirelength = 0.0; - auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& place_move_ctx = placer_ctx_.mutable_move(); - - for (auto net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ - if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ - /* 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)]); - } else { - get_non_updatable_bb_(net_id, - place_move_ctx.bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); - } - - net_cost_[net_id] = get_net_cost_(net_id, place_move_ctx.bb_coords[net_id]); - cost += net_cost_[net_id]; - if (method == e_cost_methods::CHECK) - expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); - } - } - - if (method == e_cost_methods::CHECK) { - VTR_LOG("\n"); - VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n", - expected_wirelength); - } - return cost; -} - -double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { - double cost = 0; - double expected_wirelength = 0.0; - auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& place_move_ctx = placer_ctx_.mutable_move(); - - for (auto net_id : cluster_ctx.clb_nlist.nets()) { /* for each net ... */ - if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */ - /* 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_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)]); - } else { - get_non_updatable_layer_bb_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); - } - - net_cost_[net_id] = get_net_layer_bb_wire_cost_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); - cost += net_cost_[net_id]; - if (method == e_cost_methods::CHECK) - expected_wirelength += get_net_wirelength_from_layer_bb(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); - } - } - - if (method == e_cost_methods::CHECK) { - VTR_LOG("\n"); - VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n", - expected_wirelength); - } - return cost; -} - void NetCostHandler::update_move_nets() { /* update net cost functions and reset flags. */ auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1671,130 +1795,6 @@ void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_op } } -void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp) { - /* Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac * - * arrays with the inverse of the average number of tracks per channel * - * between [subhigh] and [sublow]. This is only useful for the cost * - * function that takes the length of the net bounding box in each * - * dimension divided by the average number of tracks in that direction. * - * For other cost functions, you don't have to bother calling this * - * routine; when using the cost function described above, however, you * - * must always call this routine after you call init_chan and before * - * you do any placement cost determination. The place_cost_exp factor * - * specifies to what power the width of the channel should be taken -- * - * larger numbers make narrower channels more expensive. */ - - auto& device_ctx = g_vpr_ctx.device(); - - /* - Access arrays below as chan?_place_cost_fac[subhigh][sublow]. Since subhigh must be greater than or - equal to sublow, we will only access the lower half of a matrix, but we allocate the whole matrix anyway - for simplicity so we can use the vtr utility matrix functions. - */ - - chanx_place_cost_fac_.resize({device_ctx.grid.height(), device_ctx.grid.height() + 1}); - chany_place_cost_fac_.resize({device_ctx.grid.width(), device_ctx.grid.width() + 1}); - - /* First compute the number of tracks between channel high and channel * - * low, inclusive, in an efficient manner. */ - - chanx_place_cost_fac_[0][0] = device_ctx.chan_width.x_list[0]; - - for (size_t high = 1; high < device_ctx.grid.height(); high++) { - chanx_place_cost_fac_[high][high] = device_ctx.chan_width.x_list[high]; - for (size_t low = 0; low < high; low++) { - chanx_place_cost_fac_[high][low] = chanx_place_cost_fac_[high - 1][low] + device_ctx.chan_width.x_list[high]; - } - } - - /* Now compute the inverse of the average number of tracks per channel * - * between high and low. The cost function divides by the average * - * number of tracks per channel, so by storing the inverse I convert * - * this to a faster multiplication. Take this final number to the * - * place_cost_exp power -- numbers other than one mean this is no * - * longer a simple "average number of tracks"; it is some power of * - * that, allowing greater penalization of narrow channels. */ - - for (size_t high = 0; high < device_ctx.grid.height(); high++) - for (size_t low = 0; low <= high; low++) { - /* Since we will divide the wiring cost by the average channel * - * capacity between high and low, having only 0 width channels * - * will result in infinite wiring capacity normalization * - * factor, and extremely bad placer behaviour. Hence we change * - * this to a small (1 track) channel capacity instead. */ - if (chanx_place_cost_fac_[high][low] == 0.0f) { - VTR_LOG_WARN("CHANX place cost fac is 0 at %d %d\n", high, low); - chanx_place_cost_fac_[high][low] = 1.0f; - } - - chanx_place_cost_fac_[high][low] = (high - low + 1.) / chanx_place_cost_fac_[high][low]; - chanx_place_cost_fac_[high][low] = pow((double)chanx_place_cost_fac_[high][low], (double)place_cost_exp); - } - - /* Now do the same thing for the y-directed channels. First get the * - * number of tracks between channel high and channel low, inclusive. */ - - chany_place_cost_fac_[0][0] = device_ctx.chan_width.y_list[0]; - - for (size_t high = 1; high < device_ctx.grid.width(); high++) { - chany_place_cost_fac_[high][high] = device_ctx.chan_width.y_list[high]; - for (size_t low = 0; low < high; low++) { - chany_place_cost_fac_[high][low] = chany_place_cost_fac_[high - 1][low] + device_ctx.chan_width.y_list[high]; - } - } - - /* Now compute the inverse of the average number of tracks per channel * - * between high and low. Take to specified power. */ - - for (size_t high = 0; high < device_ctx.grid.width(); high++) - for (size_t low = 0; low <= high; low++) { - /* Since we will divide the wiring cost by the average channel * - * capacity between high and low, having only 0 width channels * - * will result in infinite wiring capacity normalization * - * factor, and extremely bad placer behaviour. Hence we change * - * this to a small (1 track) channel capacity instead. */ - if (chany_place_cost_fac_[high][low] == 0.0f) { - VTR_LOG_WARN("CHANY place cost fac is 0 at %d %d\n", high, low); - chany_place_cost_fac_[high][low] = 1.0f; - } - - chany_place_cost_fac_[high][low] = (high - low + 1.) / chany_place_cost_fac_[high][low]; - chany_place_cost_fac_[high][low] = pow((double)chany_place_cost_fac_[high][low], (double)place_cost_exp); - } -} - -NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) - : cube_bb_(cube_bb) - , placer_ctx_(placer_ctx) { - const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); - - // Either 3D BB or per layer BB data structure are used, not both. - if (cube_bb_) { - ts_bb_edge_new_.resize(num_nets, t_bb()); - ts_bb_coord_new_.resize(num_nets, t_bb()); - comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_bb_cost_, this, std::placeholders::_1); - } 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())); - comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_per_layer_bb_cost_, this, std::placeholders::_1); - } - - /* 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); - - ts_nets_to_update_.resize(num_nets, ClusterNetId::INVALID()); - - net_cost_.resize(num_nets, -1.); - proposed_net_cost_.resize(num_nets, -1.); - /* Used to store costs for moves not yet made and to indicate when a net's * - * cost has been recomputed. proposed_net_cost[inet] < 0 means net's cost hasn't * - * been recomputed. */ - bb_update_status_.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); - - alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); -} - - void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { if (cube_bb_) { get_non_updatable_bb_(net, diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index fb7f53822aa..91c8d5795ad 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -16,7 +16,7 @@ constexpr double ERROR_TOL = .01; /** * @brief The method used to calculate placement cost - * @details For comp_cost. NORMAL means use the method that generates updatable bounding boxes for speed. + * @details For comp_cost. NORMAL means use the method that generates updatable bounding boxes for speed. * CHECK means compute all bounding boxes from scratch using a very simple routine to allow checks * of the other costs. * NORMAL: Compute cost efficiently using incremental techniques. @@ -46,6 +46,20 @@ class NetCostHandler { */ NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp); + /** + * @brief Finds the bb cost from scratch. + * Done only when the placement has been radically changed + * (i.e. after initial placement). Otherwise find the cost + * change incrementally. If method check is NORMAL, we find + * bounding boxes that are updatable for the larger nets. + * If method is CHECK, all bounding boxes are found via the + * non_updateable_bb routine, to provide a cost which can be + * used to check the correctness of the other routine. + * @param method The method used to calculate placement cost. + * @return The bounding box cost of the placement. + */ + double comp_bb_cost(e_cost_methods method); + /** * @brief Find all the nets and pins affected by this swap and update costs. * @@ -76,20 +90,6 @@ class NetCostHandler { double& bb_delta_c, double& timing_delta_c); - /** - * @brief Finds the bb cost from scratch. - * Done only when the placement has been radically changed - * (i.e. after initial placement). Otherwise find the cost - * change incrementally. If method check is NORMAL, we find - * bounding boxes that are updatable for the larger nets. - * If method is CHECK, all bounding boxes are found via the - * non_updateable_bb routine, to provide a cost which can be - * used to check the correctness of the other routine. - * @param method The method used to calculate placement cost. - * @return The bounding box cost of the placement. - */ - double comp_bb_cost(e_cost_methods method); - /** * @brief Reset the net cost function flags (proposed_net_cost and bb_updated_before) */ @@ -144,15 +144,15 @@ class NetCostHandler { /* [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*/ - vtr::vector> layer_ts_bb_edge_new_, layer_ts_bb_coord_new_; + vtr::vector> layer_ts_bb_coord_new_, layer_ts_bb_edge_new_; /* [0...cluster_ctx.clb_nlist.nets().size()-1][0...num_layers-1] -> number of sink pins on a layer*/ vtr::Matrix ts_layer_sink_pin_count_; - /* [0...num_afftected_nets] -> net_id of the affected nets */ + /* [0...num_affected_nets] -> net_id of the affected nets */ std::vector ts_nets_to_update_; /** - * @brief For each of the vectors in this struct, there is one entry per cluster level net: + * @brief In each of these vectors, there is one entry per cluster level net: * [0...cluster_ctx.clb_nlist.nets().size()-1]. * net_cost and proposed_net_cost: Cost of a net, and a temporary cost of a net used during move assessment. * We also use negative cost values in proposed_net_cost as a flag to indicate that @@ -228,11 +228,10 @@ class NetCostHandler { void set_bb_delta_cost_(double& bb_delta_c); /** - * @brief Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac - * arrays with the inverse of the average number of tracks per channel - * between [subhigh] and [sublow]. - * @param place_cost_exp It is an exponent to which you take the average inverse channel - * capacity; a higher value would favour wider channels more over narrower channels during placement (usually we use 1). + * @brief Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac arrays with the inverse of + * the average number of tracks per channelbetween [subhigh] and [sublow]. + * @param place_cost_exp It is an exponent to which you take the average inverse channel capacity; + * a higher value would favour wider channels more over narrower channels during placement (usually we use 1). */ void alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp); @@ -290,8 +289,8 @@ class NetCostHandler { /** * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. - * @details This routine finds the bounding box of each net from scratch (i.e. from only the block location information). It updates both the - * coordinate and number of pins on each edge information. It should only be called when the bounding box + * @details This routine finds the bounding box of each net from scratch (i.e. from only the block location information). + * 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 From cd005be4ae1ecfe1d96be55eb370388ba8a9cf37 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 13:10:13 -0400 Subject: [PATCH 12/36] remove local vectors in get_non_updatable_layer_bb_() and get_layer_bb_from_scratch_() --- vpr/src/place/net_cost_handler.cpp | 131 +++++++++++------------------ 1 file changed, 50 insertions(+), 81 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index f258711ffe0..d3613741648 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -600,17 +600,15 @@ void NetCostHandler::get_non_updatable_bb_(ClusterNetId net_id, } void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer) { + std::vector& bb_coord_new, + vtr::NdMatrixProxy num_sink_layer) { //TODO: account for multiple physical pin instances per logical pin auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); auto& block_locs = placer_ctx_.block_locs(); - int num_layers = device_ctx.grid.get_num_layers(); - for (int layer_num = 0; layer_num < device_ctx.grid.get_num_layers(); layer_num++) { - num_sink_layer[layer_num] = 0; - } + const int num_layers = device_ctx.grid.get_num_layers(); + VTR_ASSERT_DEBUG(bb_coord_new.size() == num_layers); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; @@ -619,10 +617,10 @@ void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, int src_x = block_locs[bnum].loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; int src_y = block_locs[bnum].loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; - std::vector xmin(num_layers, src_x); - std::vector ymin(num_layers, src_y); - std::vector xmax(num_layers, src_x); - std::vector ymax(num_layers, src_y); + for (int layer_num = 0; layer_num < num_layers; layer_num++) { + bb_coord_new[layer_num] = t_2D_bb{src_x, src_y, src_x, src_y, layer_num}; + num_sink_layer[layer_num] = 0; + } for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { bnum = cluster_ctx.clb_nlist.pin_block(pin_id); @@ -633,16 +631,17 @@ void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, int layer_num = block_locs[bnum].loc.layer; num_sink_layer[layer_num]++; - if (x < xmin[layer_num]) { - xmin[layer_num] = x; - } else if (x > xmax[layer_num]) { - xmax[layer_num] = x; + + if (x < bb_coord_new[layer_num].xmin) { + bb_coord_new[layer_num].xmin = x; + } else if (x > bb_coord_new[layer_num].xmax) { + bb_coord_new[layer_num].xmax = x; } - if (y < ymin[layer_num]) { - ymin[layer_num] = y; - } else if (y > ymax[layer_num]) { - ymax[layer_num] = y; + if (y < bb_coord_new[layer_num].ymin) { + bb_coord_new[layer_num].ymin = y; + } else if (y > bb_coord_new[layer_num].ymax) { + bb_coord_new[layer_num].ymax = y; } } @@ -655,10 +654,10 @@ void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, * is 0). See route_common.cpp for a channel diagram. */ for (int layer_num = 0; layer_num < num_layers; layer_num++) { bb_coord_new[layer_num].layer_num = layer_num; - bb_coord_new[layer_num].xmin = max(min(xmin[layer_num], device_ctx.grid.width() - 2), 1); //-2 for no perim channels - bb_coord_new[layer_num].ymin = max(min(ymin[layer_num], device_ctx.grid.height() - 2), 1); //-2 for no perim channels - bb_coord_new[layer_num].xmax = max(min(xmax[layer_num], device_ctx.grid.width() - 2), 1); //-2 for no perim channels - bb_coord_new[layer_num].ymax = max(min(ymax[layer_num], device_ctx.grid.height() - 2), 1); //-2 for no perim channels + bb_coord_new[layer_num].xmin = max(min(bb_coord_new[layer_num].xmin, device_ctx.grid.width() - 2), 1); //-2 for no perim channels + bb_coord_new[layer_num].ymin = max(min(bb_coord_new[layer_num].ymin, device_ctx.grid.height() - 2), 1); //-2 for no perim channels + bb_coord_new[layer_num].xmax = max(min(bb_coord_new[layer_num].xmax, device_ctx.grid.width() - 2), 1); //-2 for no perim channels + bb_coord_new[layer_num].ymax = max(min(bb_coord_new[layer_num].ymax, device_ctx.grid.height() - 2), 1); //-2 for no perim channels } } @@ -1399,25 +1398,17 @@ void NetCostHandler::get_bb_from_scratch_(ClusterNetId net_id, } void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, - std::vector& num_on_edges, - std::vector& coords, - vtr::NdMatrixProxy layer_pin_sink_count) { + std::vector& num_on_edges, + std::vector& coords, + vtr::NdMatrixProxy layer_pin_sink_count) { auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); auto& grid = device_ctx.grid; auto& block_locs = placer_ctx_.block_locs(); const int num_layers = device_ctx.grid.get_num_layers(); - std::vector xmin(num_layers, OPEN); - std::vector xmax(num_layers, OPEN); - std::vector ymin(num_layers, OPEN); - std::vector ymax(num_layers, OPEN); - std::vector xmin_edge(num_layers, OPEN); - std::vector xmax_edge(num_layers, OPEN); - std::vector ymin_edge(num_layers, OPEN); - std::vector ymax_edge(num_layers, OPEN); - - std::vector num_sink_pin_layer(num_layers, 0); + VTR_ASSERT_DEBUG(coords.size() == num_layers); + VTR_ASSERT_DEBUG(num_on_edges.size() == num_layers); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; @@ -1433,14 +1424,9 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, // when per-layer bounding box is used, we want the bounding box on each layer to also include // the location of source since the connection on each layer starts from that location. for (int layer_num = 0; layer_num < num_layers; layer_num++) { - xmin[layer_num] = x_src; - ymin[layer_num] = y_src; - xmax[layer_num] = x_src; - ymax[layer_num] = y_src; - xmin_edge[layer_num] = 1; - ymin_edge[layer_num] = 1; - xmax_edge[layer_num] = 1; - ymax_edge[layer_num] = 1; + coords[layer_num] = t_2D_bb{x_src, y_src, x_src, y_src, layer_num}; + num_on_edges[layer_num] = t_2D_bb{1, 1, 1, 1, layer_num}; + layer_pin_sink_count[layer_num] = 0; } for (ClusterPinId pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) { @@ -1449,7 +1435,7 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, int pnum = placer_ctx_.blk_loc_registry().tile_pin_index(pin_id); int layer = block_locs[bnum].loc.layer; VTR_ASSERT_SAFE(layer >= 0 && layer < num_layers); - num_sink_pin_layer[layer]++; + layer_pin_sink_count[layer]++; int x = block_loc.x + physical_tile_type(block_loc)->pin_width_offset[pnum]; int y = block_loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; @@ -1463,49 +1449,32 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, x = max(min(x, grid.width() - 2), 1); //-2 for no perim channels y = max(min(y, grid.height() - 2), 1); //-2 for no perim channels - if (x == xmin[layer]) { - xmin_edge[layer]++; + if (x == coords[layer].xmin) { + num_on_edges[layer].xmin++; } - if (x == xmax[layer]) { /* Recall that xmin could equal xmax -- don't use else */ - xmax_edge[layer]++; - } else if (x < xmin[layer]) { - xmin[layer] = x; - xmin_edge[layer] = 1; - } else if (x > xmax[layer]) { - xmax[layer] = x; - xmax_edge[layer] = 1; + if (x == coords[layer].xmax) { /* Recall that xmin could equal xmax -- don't use else */ + num_on_edges[layer].xmax++; + } else if (x < coords[layer].xmin) { + coords[layer].xmin = x; + num_on_edges[layer].xmin = 1; + } else if (x > coords[layer].xmax) { + coords[layer].xmax = x; + num_on_edges[layer].xmax = 1; } - if (y == ymin[layer]) { - ymin_edge[layer]++; + if (y == coords[layer].ymin) { + num_on_edges[layer].ymin++; } - if (y == ymax[layer]) { - ymax_edge[layer]++; - } else if (y < ymin[layer]) { - ymin[layer] = y; - ymin_edge[layer] = 1; - } else if (y > ymax[layer]) { - ymax[layer] = y; - ymax_edge[layer] = 1; + if (y == coords[layer].ymax) { + num_on_edges[layer].ymax++; + } else if (y < coords[layer].ymin) { + coords[layer].ymin = y; + num_on_edges[layer].ymin = 1; + } else if (y > coords[layer].ymax) { + coords[layer].ymax = y; + num_on_edges[layer].ymax = 1; } } - - /* Copy the coordinates and number on edges information into the proper * - * structures. */ - for (int layer_num = 0; layer_num < num_layers; layer_num++) { - layer_pin_sink_count[layer_num] = num_sink_pin_layer[layer_num]; - coords[layer_num].xmin = xmin[layer_num]; - coords[layer_num].xmax = xmax[layer_num]; - coords[layer_num].ymin = ymin[layer_num]; - coords[layer_num].ymax = ymax[layer_num]; - coords[layer_num].layer_num = layer_num; - - num_on_edges[layer_num].xmin = xmin_edge[layer_num]; - num_on_edges[layer_num].xmax = xmax_edge[layer_num]; - num_on_edges[layer_num].ymin = ymin_edge[layer_num]; - num_on_edges[layer_num].ymax = ymax_edge[layer_num]; - num_on_edges[layer_num].layer_num = layer_num; - } } double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { From 3f70ff22a6e7495026059bc2bc6620f9ea72d8ac Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 13:40:21 -0400 Subject: [PATCH 13/36] add a private const t_placer_opts& placer_opts_ to NetCostHandler --- vpr/src/place/move_transactions.h | 2 +- vpr/src/place/net_cost_handler.cpp | 41 ++++++++++++++---------------- vpr/src/place/net_cost_handler.h | 3 ++- vpr/src/place/place.cpp | 2 +- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/vpr/src/place/move_transactions.h b/vpr/src/place/move_transactions.h index 3bd4df73a6f..4b32002195a 100644 --- a/vpr/src/place/move_transactions.h +++ b/vpr/src/place/move_transactions.h @@ -30,7 +30,7 @@ struct t_pl_moved_block { * placement. * * Store the information on the blocks to be moved in a swap during * * placement, in the form of array of structs instead of struct with * - * arrays for cache effifiency * + * arrays for cache efficiency * * * moved blocks: a list of moved blocks data structure with * * information on the move. * diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index d3613741648..6c1deff76a3 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -129,9 +129,13 @@ static double wirelength_crossing_count(size_t fanout); /******************************* End of Function definitions ************************************/ -NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp) +NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, + PlacerContext& placer_ctx, + size_t num_nets, + bool cube_bb) : cube_bb_(cube_bb) - , placer_ctx_(placer_ctx) { + , placer_ctx_(placer_ctx) + , placer_opts_(placer_opts) { const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); // Either 3D BB or per layer BB data structure are used, not both. @@ -159,7 +163,7 @@ NetCostHandler::NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool * been recomputed. */ bb_update_status_.resize(num_nets, NetUpdateState::NOT_UPDATED_YET); - alloc_and_load_chan_w_factors_for_place_cost_(place_cost_exp); + alloc_and_load_chan_w_factors_for_place_cost_(placer_opts_.place_cost_exp); } void NetCostHandler::alloc_and_load_chan_w_factors_for_place_cost_(float place_cost_exp) { @@ -1500,11 +1504,9 @@ double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, const std::vector& bb, const vtr::NdMatrixProxy layer_pin_sink_count) { - /* Finds the cost due to one net by looking at its coordinate bounding * - * box. */ + // Finds the cost due to one net by looking at its coordinate bounding box. double ncost = 0.; - double crossing = 0.; int num_layers = g_vpr_ctx.device().grid.get_num_layers(); for (int layer_num = 0; layer_num < num_layers; layer_num++) { @@ -1512,12 +1514,10 @@ double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, if (layer_pin_sink_count[layer_num] == 0) { continue; } - /* - adjust the bounding box half perimeter by the wirelength correction - factor based on terminal count, which is 1 for the source + the number - of sinks on this layer. - */ - crossing = wirelength_crossing_count(layer_pin_sink_count[layer_num] + 1); + /* Adjust the bounding box half perimeter by the wirelength correction + * factor based on terminal count, which is 1 for the source + the number + * of sinks on this layer. */ + double crossing = wirelength_crossing_count(layer_pin_sink_count[layer_num] + 1); /* Could insert a check for xmin == xmax. In that case, assume * * connection will be made with no bends and hence no x-cost. * @@ -1533,7 +1533,7 @@ double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, * chany_place_cost_fac_[bb[layer_num].xmax][bb[layer_num].xmin - 1]; } - return (ncost); + return ncost; } static double get_net_wirelength_estimate(ClusterNetId net_id, const t_bb& bb) { @@ -1562,15 +1562,14 @@ static double get_net_wirelength_from_layer_bb(ClusterNetId /* net_id */, * its coordinate bounding box. */ double ncost = 0.; - double crossing = 0.; - int num_layers = g_vpr_ctx.device().grid.get_num_layers(); + const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); for (int layer_num = 0; layer_num < num_layers; layer_num++) { VTR_ASSERT_SAFE(layer_pin_sink_count[layer_num] != OPEN); if (layer_pin_sink_count[layer_num] == 0) { continue; } - crossing = wirelength_crossing_count(layer_pin_sink_count[layer_num] + 1); + double crossing = wirelength_crossing_count(layer_pin_sink_count[layer_num] + 1); /* Could insert a check for xmin == xmax. In that case, assume * * connection will be made with no bends and hence no x-cost. * @@ -1580,11 +1579,10 @@ static double get_net_wirelength_from_layer_bb(ClusterNetId /* net_id */, * channel capacity. Do this for x, then y direction and add. */ ncost += (bb[layer_num].xmax - bb[layer_num].xmin + 1) * crossing; - ncost += (bb[layer_num].ymax - bb[layer_num].ymin + 1) * crossing; } - return (ncost); + return ncost; } double NetCostHandler::recompute_bb_cost_() { @@ -1636,10 +1634,9 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm ts_nets_to_update_.resize(0); /* Go through all the blocks moved. */ - for (const auto& block : blocks_affected.moved_blocks) { - const auto& moving_block_inf = block; + for (const t_pl_moved_block& moving_block : blocks_affected.moved_blocks) { auto& affected_pins = blocks_affected.affected_pins; - ClusterBlockId blk = block.block_num; + ClusterBlockId blk = moving_block.block_num; /* Go through all the pins in the moved block. */ for (ClusterPinId blk_pin : clb_nlist.block_pins(blk)) { @@ -1653,7 +1650,7 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm criticalities, blk, blk_pin, - moving_block_inf, + moving_block, affected_pins, timing_delta_c, is_src_moving); diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 91c8d5795ad..c78e6747d16 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -44,7 +44,7 @@ class NetCostHandler { * @param cube_bb True if the 3D bounding box should be used, false otherwise. * @param place_cost_exp It is an exponent to which you take the average inverse channel */ - NetCostHandler(PlacerContext& placer_ctx, size_t num_nets, bool cube_bb, float place_cost_exp); + NetCostHandler(const t_placer_opts& placer_opts, PlacerContext& placer_ctx, size_t num_nets, bool cube_bb); /** * @brief Finds the bb cost from scratch. @@ -120,6 +120,7 @@ class NetCostHandler { private: bool cube_bb_ = false; PlacerContext& placer_ctx_; + const t_placer_opts& placer_opts_; std::function comp_bb_cost_functor_; diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 53d6d6af98f..3fd75a47580 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -1912,7 +1912,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac place_ctx.compressed_block_grids = create_compressed_block_grids(); - return {placer_ctx, num_nets, place_ctx.cube_bb, placer_opts.place_cost_exp}; + return {placer_opts, placer_ctx, num_nets, place_ctx.cube_bb}; } /* Frees the major structures needed by the placer (and not needed * From dc9c01891447547782e96cb063e7130dee5b4b33 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 14:16:51 -0400 Subject: [PATCH 14/36] remove args of type t_place_algorithm and t_placer_opts --- vpr/src/place/net_cost_handler.cpp | 90 ++++++++++++++---------------- vpr/src/place/net_cost_handler.h | 13 +---- vpr/src/place/place.cpp | 7 +-- 3 files changed, 49 insertions(+), 61 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 6c1deff76a3..0486d8ec3f9 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -56,9 +56,9 @@ static const float cross_count[MAX_FANOUT_CROSSING_COUNT] = {/* [0..49] */ 1.0, 2.7933}; /** - * @param net - * @param moved_blocks - * @return True if the driver block of the net is among the moving blocks + * @param net The unique identifier of the net of interest. + * @param moved_blocks A vector of moving clustered blocks. + * @return True if the driver block of the net is among the moving blocks. */ static bool driven_by_moved_block(const ClusterNetId net, const std::vector& moved_blocks); @@ -339,23 +339,6 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { return cost; } -//Returns true if 'net' is driven by one of the blocks in 'blocks_affected' -static bool driven_by_moved_block(const ClusterNetId net, - const std::vector& moved_blocks) { - auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; - bool is_driven_by_move_blk = false; - ClusterBlockId net_driver_block = clb_nlist.net_driver_block(net); - - for (const auto& block : moved_blocks) { - if (net_driver_block == block.block_num) { - is_driven_by_move_blk = true; - break; - } - } - - return is_driven_by_move_blk; -} - void NetCostHandler::update_net_bb_(const ClusterNetId net, const ClusterBlockId blk, const ClusterPinId blk_pin, @@ -493,16 +476,15 @@ void NetCostHandler::record_affected_net_(const ClusterNetId net) { } } -void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, +void NetCostHandler::update_net_info_on_pin_move_(const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, - const ClusterBlockId blk_id, const ClusterPinId pin_id, const t_pl_moved_block& moving_blk_inf, std::vector& affected_pins, double& timing_delta_c, bool is_src_moving) { const auto& cluster_ctx = g_vpr_ctx.clustering(); + const ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(pin_id); VTR_ASSERT_SAFE_MSG(net_id, "Only valid nets should be found in compressed netlist block pins"); @@ -516,10 +498,11 @@ void NetCostHandler::update_net_info_on_pin_move_(const t_place_algorithm& place /* Record effected nets */ record_affected_net_(net_id); + ClusterBlockId blk_id = moving_blk_inf.block_num; /* Update the net bounding boxes. */ update_net_bb_(net_id, blk_id, pin_id, moving_blk_inf); - if (place_algorithm.is_timing_driven()) { + if (placer_opts_.place_algorithm.is_timing_driven()) { /* Determine the change in connection delay and timing cost. */ update_td_delta_costs_(delay_model, *criticalities, @@ -1621,8 +1604,7 @@ void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { } } -void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, +void NetCostHandler::find_affected_nets_and_update_costs(const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, t_pl_blocks_to_be_moved& blocks_affected, double& bb_delta_c, @@ -1636,19 +1618,17 @@ void NetCostHandler::find_affected_nets_and_update_costs(const t_place_algorithm /* Go through all the blocks moved. */ for (const t_pl_moved_block& moving_block : blocks_affected.moved_blocks) { auto& affected_pins = blocks_affected.affected_pins; - ClusterBlockId blk = moving_block.block_num; + ClusterBlockId blk_id = moving_block.block_num; /* Go through all the pins in the moved block. */ - for (ClusterPinId blk_pin : clb_nlist.block_pins(blk)) { + for (ClusterPinId blk_pin : clb_nlist.block_pins(blk_id)) { bool is_src_moving = false; if (clb_nlist.pin_type(blk_pin) == PinType::SINK) { ClusterNetId net_id = clb_nlist.pin_net(blk_pin); is_src_moving = driven_by_moved_block(net_id, blocks_affected.moved_blocks); } - update_net_info_on_pin_move_(place_algorithm, - delay_model, + update_net_info_on_pin_move_(delay_model, criticalities, - blk, blk_pin, moving_block, affected_pins, @@ -1697,8 +1677,7 @@ void NetCostHandler::reset_move_nets() { } } -void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, +void NetCostHandler::recompute_costs_from_scratch(const t_noc_opts& noc_opts, const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, t_placer_costs* costs) { @@ -1717,13 +1696,13 @@ void NetCostHandler::recompute_costs_from_scratch(const t_placer_opts& placer_op check_and_print_cost(new_bb_cost, costs->bb_cost, "bb_cost"); costs->bb_cost = new_bb_cost; - if (placer_opts.place_algorithm.is_timing_driven()) { + if (placer_opts_.place_algorithm.is_timing_driven()) { double new_timing_cost = 0.; comp_td_costs(delay_model, *criticalities, placer_ctx_, &new_timing_cost); check_and_print_cost(new_timing_cost, costs->timing_cost, "timing_cost"); costs->timing_cost = new_timing_cost; } else { - VTR_ASSERT(placer_opts.place_algorithm == BOUNDING_BOX_PLACE); + VTR_ASSERT(placer_opts_.place_algorithm == BOUNDING_BOX_PLACE); costs->cost = new_bb_cost * costs->bb_cost_norm; } @@ -1777,21 +1756,21 @@ void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { if (cube_bb_) { update_bb_(net_id, - ts_bb_edge_new_[net_id], - ts_bb_coord_new_[net_id], - ts_layer_sink_pin_count_[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); + ts_bb_edge_new_[net_id], + ts_bb_coord_new_[net_id], + ts_layer_sink_pin_count_[size_t(net_id)], + pin_old_loc, + pin_new_loc, + is_driver); } else { update_layer_bb_(net_id, - layer_ts_bb_edge_new_[net_id], - layer_ts_bb_coord_new_[net_id], - ts_layer_sink_pin_count_[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); + layer_ts_bb_edge_new_[net_id], + layer_ts_bb_coord_new_[net_id], + ts_layer_sink_pin_count_[size_t(net_id)], + pin_old_loc, + pin_new_loc, + is_driver); } } @@ -1821,3 +1800,20 @@ void NetCostHandler::set_ts_edge_(const ClusterNetId net_id) { place_move_ctx.layer_bb_num_on_edges[net_id] = layer_ts_bb_edge_new_[net_id]; } } + + +static bool driven_by_moved_block(const ClusterNetId net, + const std::vector& moved_blocks) { + auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; + bool is_driven_by_move_blk = false; + ClusterBlockId net_driver_block = clb_nlist.net_driver_block(net); + + for (const t_pl_moved_block& block : moved_blocks) { + if (net_driver_block == block.block_num) { + is_driven_by_move_blk = true; + break; + } + } + + return is_driven_by_move_blk; +} \ No newline at end of file diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index c78e6747d16..687613a965b 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -83,8 +83,7 @@ class NetCostHandler { * * @return The number of affected nets. */ - void find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, + void find_affected_nets_and_update_costs(const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, t_pl_blocks_to_be_moved& blocks_affected, double& bb_delta_c, @@ -105,14 +104,12 @@ class NetCostHandler { * @brief re-calculates different terms of the cost function (wire-length, timing, NoC) and update "costs" accordingly. It is important to note that * in this function bounding box and connection delays are not calculated from scratch. However, it iterates over all nets and connections and updates * their costs by a complete summation, rather than incrementally. - * @param placer_opts * @param noc_opts * @param delay_model * @param criticalities * @param costs passed by reference and computed by this routine (i.e. returned by reference) */ - void recompute_costs_from_scratch(const t_placer_opts& placer_opts, - const t_noc_opts& noc_opts, + void recompute_costs_from_scratch(const t_noc_opts& noc_opts, const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, t_placer_costs* costs); @@ -201,20 +198,16 @@ class NetCostHandler { /** * @brief Call suitable function based on the bounding box type to update the bounding box of the net connected to pin_id. Also, * call the function to update timing information if the placement algorithm is timing-driven. - * @param place_algorithm Placement algorithm * @param delay_model Timing delay model used by placer * @param criticalities Connections timing criticalities - * @param blk_id Block ID of that the moving pin belongs to. * @param pin_id Pin ID of the moving pin * @param moving_blk_inf Data structure that holds information, e.g., old location and new location, about all moving blocks * @param affected_pins Netlist pins which are affected, in terms placement cost, by the proposed move. * @param timing_delta_c Timing cost change based on the proposed move * @param is_src_moving Is the moving pin the source of a net. */ - void update_net_info_on_pin_move_(const t_place_algorithm& place_algorithm, - const PlaceDelayModel* delay_model, + void update_net_info_on_pin_move_(const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, - const ClusterBlockId blk_id, const ClusterPinId pin_id, const t_pl_moved_block& moving_blk_inf, std::vector& affected_pins, diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 3fd75a47580..1fb66c9ebdb 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -1112,8 +1112,7 @@ static void placement_inner_loop(const t_annealing_state* state, ++(*moves_since_cost_recompute); if (*moves_since_cost_recompute > MAX_MOVES_BEFORE_RECOMPUTE) { //VTR_LOG("recomputing costs from scratch, old bb_cost is %g\n", costs->bb_cost); - net_cost_handler.recompute_costs_from_scratch(placer_opts, noc_opts, delay_model, - criticalities, costs); + net_cost_handler.recompute_costs_from_scratch(noc_opts, delay_model, criticalities, costs); //VTR_LOG("new_bb_cost is %g\n", costs->bb_cost); *moves_since_cost_recompute = 0; } @@ -1381,8 +1380,8 @@ static e_move_result try_swap(const t_annealing_state* state, // //Also find all the pins affected by the swap, and calculates new connection //delays and timing costs and store them in proposed_* data structures. - net_cost_handler.find_affected_nets_and_update_costs(place_algorithm, delay_model, criticalities, - blocks_affected, bb_delta_c, timing_delta_c); + net_cost_handler.find_affected_nets_and_update_costs(delay_model, criticalities, blocks_affected, + bb_delta_c, timing_delta_c); //For setup slack analysis, we first do a timing analysis to get the newest //slack values resulted from the proposed block moves. If the move turns out From 1deb8b082950fcc6cb31fdcf04ec4babfb166b5f Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 6 Aug 2024 15:09:50 -0400 Subject: [PATCH 15/36] added update_bb_functor_ --- vpr/src/place/net_cost_handler.cpp | 70 ++++++++++++------------------ vpr/src/place/net_cost_handler.h | 21 +++------ 2 files changed, 34 insertions(+), 57 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 0486d8ec3f9..3ea92e0079b 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -143,10 +143,14 @@ NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, ts_bb_edge_new_.resize(num_nets, t_bb()); ts_bb_coord_new_.resize(num_nets, t_bb()); comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_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); } 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())); 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); } /* This initializes the whole matrix to OPEN which is an invalid value*/ @@ -363,14 +367,14 @@ void NetCostHandler::update_net_bb_(const ClusterNetId net, bool is_driver = cluster_ctx.clb_nlist.pin_type(blk_pin) == PinType::DRIVER; //Incremental bounding box update - update_bb_(net, - {pl_moved_block.old_loc.x + pin_width_offset, - pl_moved_block.old_loc.y + pin_height_offset, - pl_moved_block.old_loc.layer}, - {pl_moved_block.new_loc.x + pin_width_offset, - pl_moved_block.new_loc.y + pin_height_offset, - pl_moved_block.new_loc.layer}, - is_driver); + update_bb_functor_(net, + {pl_moved_block.old_loc.x + pin_width_offset, + pl_moved_block.old_loc.y + pin_height_offset, + pl_moved_block.old_loc.layer}, + {pl_moved_block.new_loc.x + pin_width_offset, + pl_moved_block.new_loc.y + pin_height_offset, + pl_moved_block.new_loc.layer}, + is_driver); } } @@ -649,12 +653,9 @@ void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, } void NetCostHandler::update_bb_(ClusterNetId net_id, - t_bb& bb_edge_new, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool src_pin) { + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool src_pin) { //TODO: account for multiple physical pin instances per logical pin const t_bb *curr_bb_edge, *curr_bb_coord; @@ -663,6 +664,10 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, const int num_layers = device_ctx.grid.get_num_layers(); + t_bb& bb_edge_new = ts_bb_edge_new_[net_id]; + t_bb& bb_coord_new = ts_bb_coord_new_[net_id]; + vtr::NdMatrixProxy num_sink_pin_layer_new = ts_layer_sink_pin_count_[size_t(net_id)]; + pin_new_loc.x = max(min(pin_new_loc.x, device_ctx.grid.width() - 2), 1); //-2 for no perim channels pin_new_loc.y = max(min(pin_new_loc.y, device_ctx.grid.height() - 2), 1); //-2 for no perim channels pin_new_loc.layer_num = max(min(pin_new_loc.layer_num, device_ctx.grid.get_num_layers() - 1), 0); @@ -921,12 +926,9 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, } void NetCostHandler::update_layer_bb_(ClusterNetId net_id, - std::vector& bb_edge_new, - std::vector& bb_coord_new, - vtr::NdMatrixProxy bb_pin_sink_count_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool is_output_pin) { + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool is_output_pin) { auto& device_ctx = g_vpr_ctx.device(); auto& place_move_ctx = placer_ctx_.move(); @@ -935,6 +937,10 @@ void NetCostHandler::update_layer_bb_(ClusterNetId net_id, pin_old_loc.x = max(min(pin_old_loc.x, device_ctx.grid.width() - 2), 1); //-2 for no perim channels pin_old_loc.y = max(min(pin_old_loc.y, device_ctx.grid.height() - 2), 1); //-2 for no perim channels + 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)]; + /* Check if the net had been updated before. */ if (bb_update_status_[net_id] == NetUpdateState::GOT_FROM_SCRATCH) { /* The net had been updated from scratch, DO NOT update again! */ @@ -1753,32 +1759,10 @@ void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { } } -void NetCostHandler::update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver) { - if (cube_bb_) { - update_bb_(net_id, - ts_bb_edge_new_[net_id], - ts_bb_coord_new_[net_id], - ts_layer_sink_pin_count_[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); - } - else { - update_layer_bb_(net_id, - layer_ts_bb_edge_new_[net_id], - layer_ts_bb_coord_new_[net_id], - ts_layer_sink_pin_count_[size_t(net_id)], - pin_old_loc, - pin_new_loc, - is_driver); - } -} - double NetCostHandler::get_net_cost_(const ClusterNetId net_id) { if (cube_bb_) { return get_net_cost_(net_id, ts_bb_coord_new_[net_id]); - } - else { + } else { return get_net_layer_bb_wire_cost_(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); } } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 687613a965b..278c6e13886 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -120,6 +120,7 @@ class NetCostHandler { const t_placer_opts& placer_opts_; std::function comp_bb_cost_functor_; + std::function update_bb_functor_; /** * @brief for the states of the bounding box. @@ -251,8 +252,6 @@ class NetCostHandler { void get_non_updatable_bb_(const ClusterNetId net); - void update_bb_(ClusterNetId net_id, t_physical_tile_loc pin_old_loc, t_physical_tile_loc pin_new_loc, bool is_driver); - double get_net_cost_(const ClusterNetId net_id); void set_ts_bb_coord_(const ClusterNetId net_id); @@ -328,12 +327,9 @@ class NetCostHandler { * @param src_pin Is the moving pin driving the net */ void update_bb_(ClusterNetId net_id, - t_bb& bb_edge_new, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool src_pin); + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool src_pin); /** * @brief Update the per-layer bounding box of "net_id" incrementally based on the old and new locations of a pin on that net @@ -352,12 +348,9 @@ class NetCostHandler { * @param is_output_pin Is the moving pin of the type output */ void update_layer_bb_(ClusterNetId net_id, - std::vector& bb_edge_new, - std::vector& bb_coord_new, - vtr::NdMatrixProxy bb_pin_sink_count_new, - t_physical_tile_loc pin_old_loc, - t_physical_tile_loc pin_new_loc, - bool is_output_pin); + t_physical_tile_loc pin_old_loc, + t_physical_tile_loc pin_new_loc, + bool is_output_pin); /** * @brief Update the data structure for large nets that keep track of From a37e82a2c18154db85159a30fd965b26ce1f0204 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 7 Aug 2024 19:49:40 -0400 Subject: [PATCH 16/36] remove dead code --- vpr/src/util/vpr_utils.cpp | 44 -------------------------------------- 1 file changed, 44 deletions(-) diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 049f75cb6f5..1bde9355c05 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -2063,50 +2063,6 @@ void print_switch_usage() { delete[] inward_switch_inf; } -/* - * Motivation: - * to see what portion of long wires are utilized - * potentially a good measure for router look ahead quality - */ -/* - * void print_usage_by_wire_length() { - * map used_wire_count; - * map total_wire_count; - * auto& device_ctx = g_vpr_ctx.device(); - * for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()){ - * if (rr_graph.node_type(rr_id) == CHANX || rr_graph.node_type(rr_id) == CHANY) { - * //int length = abs(rr_graph.node_xhigh(rr_id) + rr_graph.node_yhigh(rr_id) - * // - rr_graph.node_xlow(rr_id) - rr_graph.node_ylow(rr_id)); - * int length = device_ctx.rr_nodes[(size_t)rr_id].get_length(); - * if (rr_node_route_inf[(size_t)rr_id].occ() > 0) { - * if (used_wire_count.count(length) == 0) - * used_wire_count[length] = 0; - * used_wire_count[length] ++; - * } - * if (total_wire_count.count(length) == 0) - * total_wire_count[length] = 0; - * total_wire_count[length] ++; - * } - * } - * int total_wires = 0; - * map::iterator itr; - * for (itr = total_wire_count.begin(); itr != total_wire_count.end(); itr++) { - * total_wires += itr->second; - * } - * VTR_LOG("\n\t-=-=-=-=-=-=-=-=-=-=- wire usage stats -=-=-=-=-=-=-=-=-=-=-\n"); - * for (itr = total_wire_count.begin(); itr != total_wire_count.end(); itr++) - * VTR_LOG("\ttotal number: wire of length %d, ratio to all length of wires: %g\n", itr->first, ((float)itr->second) / total_wires); - * for (itr = used_wire_count.begin(); itr != used_wire_count.end(); itr++) { - * float ratio_to_same_type_total = ((float)itr->second) / total_wire_count[itr->first]; - * float ratio_to_all_type_total = ((float)itr->second) / total_wires; - * VTR_LOG("\t\tratio to same type of wire: %g\tratio to all types of wire: %g\n", ratio_to_same_type_total, ratio_to_all_type_total); - * } - * VTR_LOG("\n\t-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"); - * used_wire_count.clear(); - * total_wire_count.clear(); - * } - */ - void place_sync_external_block_connections(ClusterBlockId iblk, BlkLocRegistry& blk_loc_registry) { const auto& cluster_ctx = g_vpr_ctx.clustering(); From 59c2c71cb86facedfbd0c0f5f4baf29f2bd7e369 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 21 Aug 2024 11:32:59 -0400 Subject: [PATCH 17/36] change the order of args in t_2D_bb constructor to be consistent with vtr::Rect --- vpr/src/base/vpr_types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index c5187013dd5..01e3d1e53a0 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -624,10 +624,10 @@ struct t_bb { */ struct t_2D_bb { t_2D_bb() = default; - t_2D_bb(int xmin_, int xmax_, int ymin_, int ymax_, int layer_num_) + t_2D_bb(int xmin_, int ymin_, int xmax_, int ymax_, int layer_num_) : xmin(xmin_) - , xmax(xmax_) , ymin(ymin_) + , xmax(xmax_) , ymax(ymax_) , layer_num(layer_num_) { VTR_ASSERT(xmax_ >= xmin_); @@ -635,8 +635,8 @@ struct t_2D_bb { VTR_ASSERT(layer_num_ >= 0); } int xmin = OPEN; - int xmax = OPEN; int ymin = OPEN; + int xmax = OPEN; int ymax = OPEN; int layer_num = OPEN; }; From 97d0813afb68866ad65d1d9bbde8f56bd44212b0 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 21 Aug 2024 13:10:10 -0400 Subject: [PATCH 18/36] add reward_function_ to MoveGenerator --- vpr/src/place/RL_agent_util.cpp | 11 +++++++--- vpr/src/place/centroid_move_generator.cpp | 8 ++++--- vpr/src/place/centroid_move_generator.h | 4 +++- .../place/critical_uniform_move_generator.cpp | 5 +++-- .../place/critical_uniform_move_generator.h | 3 ++- vpr/src/place/directed_moves_util.h | 9 ++++---- .../place/feasible_region_move_generator.cpp | 5 +++-- .../place/feasible_region_move_generator.h | 3 ++- vpr/src/place/manual_move_generator.cpp | 2 +- vpr/src/place/manual_move_generator.h | 2 +- vpr/src/place/median_move_generator.cpp | 5 +++-- vpr/src/place/median_move_generator.h | 3 ++- vpr/src/place/move_generator.h | 6 ++++-- vpr/src/place/simpleRL_move_generator.h | 21 +++++++++++-------- vpr/src/place/static_move_generator.cpp | 17 ++++++++------- vpr/src/place/static_move_generator.h | 1 + vpr/src/place/uniform_move_generator.cpp | 5 +++-- vpr/src/place/uniform_move_generator.h | 3 ++- .../weighted_centroid_move_generator.cpp | 5 +++-- .../place/weighted_centroid_move_generator.h | 3 ++- .../place/weighted_median_move_generator.cpp | 5 +++-- .../place/weighted_median_move_generator.h | 3 ++- 22 files changed, 79 insertions(+), 50 deletions(-) diff --git a/vpr/src/place/RL_agent_util.cpp b/vpr/src/place/RL_agent_util.cpp index 78984f49928..19ed06edd9c 100644 --- a/vpr/src/place/RL_agent_util.cpp +++ b/vpr/src/place/RL_agent_util.cpp @@ -6,9 +6,10 @@ std::pair, std::unique_ptr> create const t_placer_opts& placer_opts, int move_lim, double noc_attraction_weight) { - + e_reward_function reward_fun = string_to_reward(placer_opts.place_reward_fun); std::pair, std::unique_ptr> move_generators; + if (!placer_opts.RL_agent_placement) { // RL agent is disabled auto move_types = placer_opts.place_static_move_prob; move_types.resize((int)e_move_type::NUMBER_OF_AUTO_MOVES, 0.0f); @@ -20,8 +21,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, placer_opts.place_static_move_prob); - move_generators.second = std::make_unique(placer_state, placer_opts.place_static_move_prob); + move_generators.first = std::make_unique(placer_state, reward_fun, placer_opts.place_static_move_prob); + move_generators.second = std::make_unique(placer_state, reward_fun, 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) * @@ -74,6 +75,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, + reward_fun, karmed_bandit_agent1, noc_attraction_weight, placer_opts.place_high_fanout_net); @@ -83,6 +85,7 @@ std::pair, std::unique_ptr> create placer_opts.place_agent_epsilon); karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.second = std::make_unique(placer_state, + reward_fun, karmed_bandit_agent2, noc_attraction_weight, placer_opts.place_high_fanout_net); @@ -100,6 +103,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, + reward_fun, karmed_bandit_agent1, noc_attraction_weight, placer_opts.place_high_fanout_net); @@ -108,6 +112,7 @@ std::pair, std::unique_ptr> create e_agent_space::MOVE_TYPE); karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim); move_generators.second = std::make_unique(placer_state, + reward_fun, karmed_bandit_agent2, noc_attraction_weight, placer_opts.place_high_fanout_net); diff --git a/vpr/src/place/centroid_move_generator.cpp b/vpr/src/place/centroid_move_generator.cpp index 508d8cc75da..7fafa7743f8 100644 --- a/vpr/src/place/centroid_move_generator.cpp +++ b/vpr/src/place/centroid_move_generator.cpp @@ -16,15 +16,17 @@ vtr::vector CentroidMoveGenerator::cluster_to_noc_gr std::map CentroidMoveGenerator::noc_router_to_noc_group_; -CentroidMoveGenerator::CentroidMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) +CentroidMoveGenerator::CentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) , noc_attraction_w_(0.0f) , noc_attraction_enabled_(false) {} CentroidMoveGenerator::CentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, float noc_attraction_weight, size_t high_fanout_net) - : MoveGenerator(placer_state) + : MoveGenerator(placer_state, reward_function) , noc_attraction_w_(noc_attraction_weight) , noc_attraction_enabled_(true) { VTR_ASSERT(noc_attraction_weight > 0.0 && noc_attraction_weight <= 1.0); diff --git a/vpr/src/place/centroid_move_generator.h b/vpr/src/place/centroid_move_generator.h index fb8176aa1bd..dc7311f81e9 100644 --- a/vpr/src/place/centroid_move_generator.h +++ b/vpr/src/place/centroid_move_generator.h @@ -27,7 +27,8 @@ class CentroidMoveGenerator : public MoveGenerator { * @param placer_state A mutable reference to the placement state which will * be stored in this object. */ - explicit CentroidMoveGenerator(PlacerState& placer_state); + CentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); /** * The move generator created by calling this constructor considers both @@ -45,6 +46,7 @@ class CentroidMoveGenerator : public MoveGenerator { * ignored when forming NoC groups. */ CentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, float noc_attraction_weight, size_t high_fanout_net); diff --git a/vpr/src/place/critical_uniform_move_generator.cpp b/vpr/src/place/critical_uniform_move_generator.cpp index 9f6641a732e..712e309ca7c 100644 --- a/vpr/src/place/critical_uniform_move_generator.cpp +++ b/vpr/src/place/critical_uniform_move_generator.cpp @@ -4,8 +4,9 @@ #include "placer_state.h" #include "move_utils.h" -CriticalUniformMoveGenerator::CriticalUniformMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +CriticalUniformMoveGenerator::CriticalUniformMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} 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/critical_uniform_move_generator.h b/vpr/src/place/critical_uniform_move_generator.h index 8de342a788e..73fb9717218 100644 --- a/vpr/src/place/critical_uniform_move_generator.h +++ b/vpr/src/place/critical_uniform_move_generator.h @@ -17,7 +17,8 @@ class CriticalUniformMoveGenerator : public MoveGenerator { public: CriticalUniformMoveGenerator() = delete; - explicit CriticalUniformMoveGenerator(PlacerState& placer_state); + CriticalUniformMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/directed_moves_util.h b/vpr/src/place/directed_moves_util.h index cef889d5e4e..4b78e424d92 100644 --- a/vpr/src/place/directed_moves_util.h +++ b/vpr/src/place/directed_moves_util.h @@ -8,10 +8,11 @@ * @brief enum represents the different reward functions */ enum class e_reward_function { - BASIC, ///@ directly uses the change of the annealing cost function - NON_PENALIZING_BASIC, ///@ same as basic reward function but with 0 reward if it's a hill-climbing one - RUNTIME_AWARE, ///@ same as NON_PENALIZING_BASIC but with normalizing with the runtime factor of each move type - WL_BIASED_RUNTIME_AWARE ///@ same as RUNTIME_AWARE but more biased to WL cost (the factor of the bias is REWARD_BB_TIMING_RELATIVE_WEIGHT) + BASIC, ///@ directly uses the change of the annealing cost function + NON_PENALIZING_BASIC, ///@ same as basic reward function but with 0 reward if it's a hill-climbing one + RUNTIME_AWARE, ///@ same as NON_PENALIZING_BASIC but with normalizing with the runtime factor of each move type + WL_BIASED_RUNTIME_AWARE, ///@ same as RUNTIME_AWARE but more biased to WL cost (the factor of the bias is REWARD_BB_TIMING_RELATIVE_WEIGHT) + UNDEFINED_REWARD ///@ Used for manual moves }; e_reward_function string_to_reward(const std::string& st); diff --git a/vpr/src/place/feasible_region_move_generator.cpp b/vpr/src/place/feasible_region_move_generator.cpp index d321f0d2ebd..5d4e55f7656 100644 --- a/vpr/src/place/feasible_region_move_generator.cpp +++ b/vpr/src/place/feasible_region_move_generator.cpp @@ -8,8 +8,9 @@ #include #include -FeasibleRegionMoveGenerator::FeasibleRegionMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +FeasibleRegionMoveGenerator::FeasibleRegionMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} e_create_move FeasibleRegionMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/feasible_region_move_generator.h b/vpr/src/place/feasible_region_move_generator.h index 1d0e3a9224e..29405104aeb 100644 --- a/vpr/src/place/feasible_region_move_generator.h +++ b/vpr/src/place/feasible_region_move_generator.h @@ -21,7 +21,8 @@ class FeasibleRegionMoveGenerator : public MoveGenerator { public: FeasibleRegionMoveGenerator() = delete; - explicit FeasibleRegionMoveGenerator(PlacerState& placer_state); + FeasibleRegionMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/manual_move_generator.cpp b/vpr/src/place/manual_move_generator.cpp index 36d198acd09..4146cfb3eeb 100644 --- a/vpr/src/place/manual_move_generator.cpp +++ b/vpr/src/place/manual_move_generator.cpp @@ -19,7 +19,7 @@ #endif //NO_GRAPHICS ManualMoveGenerator::ManualMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} + : MoveGenerator(placer_state, e_reward_function::UNDEFINED_REWARD) {} //Manual Move Generator function e_create_move ManualMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/manual_move_generator.h b/vpr/src/place/manual_move_generator.h index 684b110ba3b..6543c2c3a3a 100644 --- a/vpr/src/place/manual_move_generator.h +++ b/vpr/src/place/manual_move_generator.h @@ -27,7 +27,7 @@ class ManualMoveGenerator : public MoveGenerator { public: ManualMoveGenerator() = delete; - explicit ManualMoveGenerator(PlacerState& placer_state); + ManualMoveGenerator(PlacerState& placer_state); //Evaluates if move is successful and legal or unable to do. e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/median_move_generator.cpp b/vpr/src/place/median_move_generator.cpp index 3f116fe71c8..44e1732e6d2 100644 --- a/vpr/src/place/median_move_generator.cpp +++ b/vpr/src/place/median_move_generator.cpp @@ -7,8 +7,9 @@ #include -MedianMoveGenerator::MedianMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +MedianMoveGenerator::MedianMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/median_move_generator.h b/vpr/src/place/median_move_generator.h index be932f78d1f..15bda1dae33 100644 --- a/vpr/src/place/median_move_generator.h +++ b/vpr/src/place/median_move_generator.h @@ -18,7 +18,8 @@ class MedianMoveGenerator : public MoveGenerator { public: MedianMoveGenerator() = delete; - explicit MedianMoveGenerator(PlacerState& placer_state); + MedianMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/move_generator.h b/vpr/src/place/move_generator.h index 15315e4b01a..a99931acd23 100644 --- a/vpr/src/place/move_generator.h +++ b/vpr/src/place/move_generator.h @@ -44,8 +44,9 @@ struct MoveTypeStat { */ class MoveGenerator { public: - MoveGenerator(PlacerState& placer_state) - : placer_state_(placer_state) {} + MoveGenerator(PlacerState& placer_state, e_reward_function reward_function) + : placer_state_(placer_state) + , reward_func_(reward_function) {} MoveGenerator() = delete; virtual ~MoveGenerator() = default; @@ -83,6 +84,7 @@ class MoveGenerator { protected: std::reference_wrapper placer_state_; + e_reward_function reward_func_; }; #endif diff --git a/vpr/src/place/simpleRL_move_generator.h b/vpr/src/place/simpleRL_move_generator.h index 25317d52ad6..c057b9d093f 100644 --- a/vpr/src/place/simpleRL_move_generator.h +++ b/vpr/src/place/simpleRL_move_generator.h @@ -217,6 +217,7 @@ class SimpleRLMoveGenerator : public MoveGenerator { template::value || std::is_same::value>::type> explicit SimpleRLMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, std::unique_ptr& agent, float noc_attraction_weight, size_t high_fanout_thresh); @@ -234,25 +235,27 @@ class SimpleRLMoveGenerator : public MoveGenerator { template SimpleRLMoveGenerator::SimpleRLMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, std::unique_ptr& agent, float noc_attraction_weight, size_t high_fanout_thresh) - : MoveGenerator(placer_state) { + : MoveGenerator(placer_state, reward_function) { 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); - all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state); - all_moves[e_move_type::CENTROID] = std::make_unique(placer_state); - all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state); - all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state); - all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state); - all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state); + all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, reward_function); if (noc_attraction_weight > 0.0f) { - all_moves[e_move_type::NOC_ATTRACTION_CENTROID] = std::make_unique(placer_state, noc_attraction_weight, high_fanout_thresh); + all_moves[e_move_type::NOC_ATTRACTION_CENTROID] = std::make_unique(placer_state, reward_function, + noc_attraction_weight, high_fanout_thresh); } karmed_bandit_agent = std::move(agent); diff --git a/vpr/src/place/static_move_generator.cpp b/vpr/src/place/static_move_generator.cpp index ed54455621d..e48214f8d6a 100644 --- a/vpr/src/place/static_move_generator.cpp +++ b/vpr/src/place/static_move_generator.cpp @@ -13,17 +13,18 @@ #include "vtr_assert.h" StaticMoveGenerator::StaticMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, const vtr::vector& move_probs) - : MoveGenerator(placer_state) { + : MoveGenerator(placer_state, reward_function) { all_moves.resize((int)e_move_type::NUMBER_OF_AUTO_MOVES); - all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state); - all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state); - all_moves[e_move_type::CENTROID] = std::make_unique(placer_state); - all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state); - all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state); - all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state); - all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state); + all_moves[e_move_type::UNIFORM] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::MEDIAN] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::CENTROID] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::W_CENTROID] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::W_MEDIAN] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::CRIT_UNIFORM] = std::make_unique(placer_state, reward_function); + all_moves[e_move_type::FEASIBLE_REGION] = std::make_unique(placer_state, reward_function); initialize_move_prob(move_probs); } diff --git a/vpr/src/place/static_move_generator.h b/vpr/src/place/static_move_generator.h index 1d63e7486a1..997782a6cd3 100644 --- a/vpr/src/place/static_move_generator.h +++ b/vpr/src/place/static_move_generator.h @@ -19,6 +19,7 @@ class StaticMoveGenerator : public MoveGenerator { public: StaticMoveGenerator() = delete; StaticMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function, const vtr::vector& move_probs); e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/uniform_move_generator.cpp b/vpr/src/place/uniform_move_generator.cpp index fc4e74dc56c..9f6e844c34d 100644 --- a/vpr/src/place/uniform_move_generator.cpp +++ b/vpr/src/place/uniform_move_generator.cpp @@ -5,8 +5,9 @@ #include "placer_state.h" #include "move_utils.h" -UniformMoveGenerator::UniformMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +UniformMoveGenerator::UniformMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} 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/uniform_move_generator.h b/vpr/src/place/uniform_move_generator.h index 190a9fb7d31..e9fd28686dd 100644 --- a/vpr/src/place/uniform_move_generator.h +++ b/vpr/src/place/uniform_move_generator.h @@ -11,7 +11,8 @@ class UniformMoveGenerator : public MoveGenerator { public: UniformMoveGenerator() = delete; - explicit UniformMoveGenerator(PlacerState& placer_state); + UniformMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/weighted_centroid_move_generator.cpp b/vpr/src/place/weighted_centroid_move_generator.cpp index 3350c486508..b6c6f7683f8 100644 --- a/vpr/src/place/weighted_centroid_move_generator.cpp +++ b/vpr/src/place/weighted_centroid_move_generator.cpp @@ -6,8 +6,9 @@ #include "placer_state.h" #include "move_utils.h" -WeightedCentroidMoveGenerator::WeightedCentroidMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +WeightedCentroidMoveGenerator::WeightedCentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} e_create_move WeightedCentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/weighted_centroid_move_generator.h b/vpr/src/place/weighted_centroid_move_generator.h index 30725bcd3ac..30ed146941c 100644 --- a/vpr/src/place/weighted_centroid_move_generator.h +++ b/vpr/src/place/weighted_centroid_move_generator.h @@ -15,7 +15,8 @@ class WeightedCentroidMoveGenerator : public MoveGenerator { public: WeightedCentroidMoveGenerator() = delete; - explicit WeightedCentroidMoveGenerator(PlacerState& placer_state); + WeightedCentroidMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, diff --git a/vpr/src/place/weighted_median_move_generator.cpp b/vpr/src/place/weighted_median_move_generator.cpp index e1581a24123..1e600defa31 100644 --- a/vpr/src/place/weighted_median_move_generator.cpp +++ b/vpr/src/place/weighted_median_move_generator.cpp @@ -10,8 +10,9 @@ #define CRIT_MULT_FOR_W_MEDIAN 10 -WeightedMedianMoveGenerator::WeightedMedianMoveGenerator(PlacerState& placer_state) - : MoveGenerator(placer_state) {} +WeightedMedianMoveGenerator::WeightedMedianMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function) + : MoveGenerator(placer_state, reward_function) {} e_create_move WeightedMedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, t_propose_action& proposed_action, diff --git a/vpr/src/place/weighted_median_move_generator.h b/vpr/src/place/weighted_median_move_generator.h index e6a3b11be89..6ba0ccc9544 100644 --- a/vpr/src/place/weighted_median_move_generator.h +++ b/vpr/src/place/weighted_median_move_generator.h @@ -15,7 +15,8 @@ class WeightedMedianMoveGenerator : public MoveGenerator { public: WeightedMedianMoveGenerator() = delete; - explicit WeightedMedianMoveGenerator(PlacerState& placer_state); + WeightedMedianMoveGenerator(PlacerState& placer_state, + e_reward_function reward_function); private: e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, From 6530b8b66325d9f2218fb0af00f38fbc7697e0db Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 21 Aug 2024 13:24:13 -0400 Subject: [PATCH 19/36] moved calculate_reward_and_process_outcome() to MoveGenerator --- vpr/src/place/move_generator.cpp | 31 +++++++++++++++++++++++ vpr/src/place/move_generator.h | 7 ++++++ vpr/src/place/place.cpp | 43 +------------------------------- 3 files changed, 39 insertions(+), 42 deletions(-) create mode 100644 vpr/src/place/move_generator.cpp diff --git a/vpr/src/place/move_generator.cpp b/vpr/src/place/move_generator.cpp new file mode 100644 index 00000000000..2a8f7fd0161 --- /dev/null +++ b/vpr/src/place/move_generator.cpp @@ -0,0 +1,31 @@ + +#include "move_generator.h" + +#include "vpr_error.h" + +void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, + double delta_c, + float timing_bb_factor) { + if (reward_func_ == e_reward_function::BASIC) { + process_outcome(-1 * delta_c, reward_func_); + } else if (reward_func_ == e_reward_function::NON_PENALIZING_BASIC || reward_func_ == e_reward_function::RUNTIME_AWARE) { + if (delta_c < 0) { + process_outcome(-1 * delta_c, reward_func_); + } else { + process_outcome(0, reward_func_); + } + } else if (reward_func_ == e_reward_function::WL_BIASED_RUNTIME_AWARE) { + if (delta_c < 0) { + float reward = -1 + * (move_outcome_stats.delta_cost_norm + + (0.5 - timing_bb_factor) + * move_outcome_stats.delta_timing_cost_norm + + timing_bb_factor + * move_outcome_stats.delta_bb_cost_norm); + process_outcome(reward, reward_func_); + } else { + VTR_ASSERT_SAFE(reward_func_ == e_reward_function::UNDEFINED_REWARD); + VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); + } + } +} diff --git a/vpr/src/place/move_generator.h b/vpr/src/place/move_generator.h index a99931acd23..90688e77981 100644 --- a/vpr/src/place/move_generator.h +++ b/vpr/src/place/move_generator.h @@ -82,6 +82,13 @@ class MoveGenerator { */ virtual void process_outcome(double /*reward*/, e_reward_function /*reward_fun*/) {} + /** + * @brief Calculates the agent's reward and the total process outcome + */ + void calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, + double delta_c, + float timing_bb_factor); + protected: std::reference_wrapper placer_state_; e_reward_function reward_func_; diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 182ece6c49f..d9037354bc9 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -324,13 +324,6 @@ static void generate_post_place_timing_reports(const t_placer_opts& placer_opts, bool is_flat, const BlkLocRegistry& blk_loc_registry); -//calculate the agent's reward and the total process outcome -static void calculate_reward_and_process_outcome(const t_placer_opts& placer_opts, - const MoveOutcomeStats& move_outcome_stats, - double delta_c, - float timing_bb_factor, - MoveGenerator& move_generator); - static void print_place_status_header(bool noc_enabled); static void print_place_status(const t_annealing_state& state, @@ -1563,8 +1556,7 @@ static e_move_result try_swap(const t_annealing_state* state, // the move generators status since this outcome is not a direct // consequence of the move generator if (!router_block_move) { - calculate_reward_and_process_outcome(placer_opts, move_outcome_stats, - delta_c, timing_bb_factor, move_generator); + move_generator.calculate_reward_and_process_outcome(move_outcome_stats, delta_c, timing_bb_factor); } #ifdef VTR_ENABLE_DEBUG_LOGGING @@ -2348,39 +2340,6 @@ static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat) VTR_LOG("\n"); } -static void calculate_reward_and_process_outcome(const t_placer_opts& placer_opts, - const MoveOutcomeStats& move_outcome_stats, - double delta_c, - float timing_bb_factor, - MoveGenerator& move_generator) { - static std::optional reward_fun; - if (!reward_fun.has_value()) { - reward_fun = string_to_reward(placer_opts.place_reward_fun); - } - - if (reward_fun == e_reward_function::BASIC) { - move_generator.process_outcome(-1 * delta_c, reward_fun.value()); - } else if (reward_fun == e_reward_function::NON_PENALIZING_BASIC || reward_fun == e_reward_function::RUNTIME_AWARE) { - if (delta_c < 0) { - move_generator.process_outcome(-1 * delta_c, reward_fun.value()); - } else { - move_generator.process_outcome(0, reward_fun.value()); - } - } else if (reward_fun == e_reward_function::WL_BIASED_RUNTIME_AWARE) { - if (delta_c < 0) { - float reward = -1 - * (move_outcome_stats.delta_cost_norm - + (0.5 - timing_bb_factor) - * move_outcome_stats.delta_timing_cost_norm - + timing_bb_factor - * move_outcome_stats.delta_bb_cost_norm); - move_generator.process_outcome(reward, reward_fun.value()); - } else { - move_generator.process_outcome(0, reward_fun.value()); - } - } -} - static void copy_locs_to_global_state(const BlkLocRegistry& blk_loc_registry) { auto& place_ctx = g_vpr_ctx.mutable_placement(); From 70f08212b89ad83ca8fc00cb097db0c1cc45ce6a Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 21 Aug 2024 13:37:21 -0400 Subject: [PATCH 20/36] don't use unique_ptr for manual_move_generator --- vpr/src/place/place.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index d9037354bc9..d00b74c520e 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -441,7 +441,7 @@ void try_place(const Netlist<>& net_list, NetCostHandler net_cost_handler = alloc_and_load_placement_structs(placer_opts, noc_opts, directs, num_directs, placer_state); - std::unique_ptr manual_move_generator = std::make_unique(placer_state); + ManualMoveGenerator manual_move_generator(placer_state); vtr::ScopedStartFinishTimer timer("Placement"); @@ -690,7 +690,7 @@ void try_place(const Netlist<>& net_list, state.t = starting_t(&state, &costs, annealing_sched, place_delay_model.get(), placer_criticalities.get(), placer_setup_slacks.get(), timing_info.get(), *move_generator, - *manual_move_generator, pin_timing_invalidator.get(), + manual_move_generator, pin_timing_invalidator.get(), blocks_affected, placer_opts, noc_opts, move_type_stat, swap_stats, placer_state, net_cost_handler); @@ -762,7 +762,7 @@ void try_place(const Netlist<>& net_list, &stats, &costs, &moves_since_cost_recompute, pin_timing_invalidator.get(), place_delay_model.get(), placer_criticalities.get(), placer_setup_slacks.get(), - *current_move_generator, *manual_move_generator, + *current_move_generator, manual_move_generator, blocks_affected, timing_info.get(), placer_opts.place_algorithm, move_type_stat, timing_bb_factor, @@ -829,7 +829,7 @@ void try_place(const Netlist<>& net_list, &stats, &costs, &moves_since_cost_recompute, pin_timing_invalidator.get(), place_delay_model.get(), placer_criticalities.get(), placer_setup_slacks.get(), - *current_move_generator, *manual_move_generator, + *current_move_generator, manual_move_generator, blocks_affected, timing_info.get(), placer_opts.place_quench_algorithm, move_type_stat, timing_bb_factor, From 01358fa3022bcd408b745e9cbf9dbcd6870055f6 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Sat, 24 Aug 2024 14:50:41 -0400 Subject: [PATCH 21/36] fixed failing assertion for UNDEFINED_REWARD --- vpr/src/place/move_generator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vpr/src/place/move_generator.cpp b/vpr/src/place/move_generator.cpp index 2a8f7fd0161..b044d5e97f9 100644 --- a/vpr/src/place/move_generator.cpp +++ b/vpr/src/place/move_generator.cpp @@ -24,8 +24,10 @@ void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& * move_outcome_stats.delta_bb_cost_norm); process_outcome(reward, reward_func_); } else { - VTR_ASSERT_SAFE(reward_func_ == e_reward_function::UNDEFINED_REWARD); - VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); + process_outcome(0, reward_func_); } + } else { + VTR_ASSERT_SAFE(reward_func_ == e_reward_function::UNDEFINED_REWARD); + VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); } } From 3033773404dc38a0823f54db99946aa59cabf813 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 26 Aug 2024 13:34:56 -0400 Subject: [PATCH 22/36] call std::max and std::min instead of using std::max and std::min --- vpr/src/place/place.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index d00b74c520e..4297025ecfe 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -84,9 +84,6 @@ static constexpr float REWARD_BB_TIMING_RELATIVE_WEIGHT = 0.4; # include "draw_color.h" #endif -using std::max; -using std::min; - /************** Types and defines local to place.c ***************************/ /* This defines the maximum number of swap attempts before invoking the * * once-in-a-while placement legality check as well as floating point * @@ -676,7 +673,7 @@ void try_place(const Netlist<>& net_list, move_type_stat.rejected_moves.resize({device_ctx.logical_block_types.size(), (int)e_move_type::NUMBER_OF_AUTO_MOVES}, 0); /* Get the first range limiter */ - float first_rlim = (float)max(device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); + float first_rlim = (float)std::max(device_ctx.grid.width() - 1, device_ctx.grid.height() - 1); place_move_ctx.first_rlim = first_rlim; t_annealing_state state(annealing_sched, @@ -1846,7 +1843,7 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac int max_pins_per_clb = 0; for (const t_physical_tile_type& type : device_ctx.physical_tile_types) { - max_pins_per_clb = max(max_pins_per_clb, type.num_pins); + max_pins_per_clb = std::max(max_pins_per_clb, type.num_pins); } if (placer_opts.place_algorithm.is_timing_driven()) { From c710d8e4a6069006c5c6d65e2e45f27da5395816 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 26 Aug 2024 13:35:26 -0400 Subject: [PATCH 23/36] remove free_try_swap_structs() and free_try_swap_arrays() --- vpr/src/place/place.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 4297025ecfe..92ef82a0bfa 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -191,9 +191,6 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac int num_directs, PlacerState& placer_state); - -static void free_try_swap_structs(); - static void free_placement_structs(const t_noc_opts& noc_opts); static e_move_result try_swap(const t_annealing_state* state, @@ -277,8 +274,6 @@ static void update_placement_cost_normalization_factors(t_placer_costs* costs, c static double get_total_cost(t_placer_costs* costs, const t_placer_opts& placer_opts, const t_noc_opts& noc_opts); -static void free_try_swap_arrays(); - static void outer_loop_update_timing_info(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, t_placer_costs* costs, @@ -965,7 +960,6 @@ void try_place(const Netlist<>& net_list, } free_placement_structs(noc_opts); - free_try_swap_arrays(); print_timing_stats("Placement Quench", post_quench_timing_stats, pre_quench_timing_stats); @@ -1910,18 +1904,14 @@ static NetCostHandler alloc_and_load_placement_structs(const t_placer_opts& plac static void free_placement_structs(const t_noc_opts& noc_opts) { free_placement_macros_structs(); - free_try_swap_structs(); + auto& place_ctx = g_vpr_ctx.mutable_placement(); + vtr::release_memory(place_ctx.compressed_block_grids); if (noc_opts.noc) { free_noc_placement_structs(); } } -static void free_try_swap_structs() { - auto& place_ctx = g_vpr_ctx.mutable_placement(); - vtr::release_memory(place_ctx.compressed_block_grids); -} - static void check_place(const t_placer_costs& costs, const PlaceDelayModel* delay_model, const PlacerCriticalities* criticalities, @@ -2136,10 +2126,6 @@ void print_clb_placement(const char* fname) { } #endif -static void free_try_swap_arrays() { - g_vpr_ctx.mutable_placement().compressed_block_grids.clear(); -} - static void generate_post_place_timing_reports(const t_placer_opts& placer_opts, const t_analysis_opts& analysis_opts, const SetupTimingInfo& timing_info, From 12093d605401ea76a814674358f86cc98e134c45 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 26 Aug 2024 14:03:44 -0400 Subject: [PATCH 24/36] move print_placement_move_types_stats() to move_generator.cpp --- vpr/src/place/move_generator.cpp | 52 +++++++++++++++++++++++++++++ vpr/src/place/move_generator.h | 4 +++ vpr/src/place/place.cpp | 56 +------------------------------- 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/vpr/src/place/move_generator.cpp b/vpr/src/place/move_generator.cpp index b044d5e97f9..4d7141584c9 100644 --- a/vpr/src/place/move_generator.cpp +++ b/vpr/src/place/move_generator.cpp @@ -31,3 +31,55 @@ void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); } } + +void MoveTypeStat::print_placement_move_types_stats() { + VTR_LOG("\n\nPlacement perturbation distribution by block and move type: \n"); + + VTR_LOG( + "------------------ ----------------- ---------------- ---------------- --------------- ------------ \n"); + VTR_LOG( + " Block Type Move Type (%%) of Total Accepted(%%) Rejected(%%) Aborted(%%)\n"); + VTR_LOG( + "------------------ ----------------- ---------------- ---------------- --------------- ------------ \n"); + + int total_moves = 0; + for (size_t i = 0; i < blk_type_moves.size(); ++i) { + total_moves += blk_type_moves.get(i); + } + + auto& device_ctx = g_vpr_ctx.device(); + int count = 0; + int num_of_avail_moves = blk_type_moves.size() / device_ctx.logical_block_types.size(); + + //Print placement information for each block type + for (const auto& itype : device_ctx.logical_block_types) { + //Skip non-existing block types in the netlist + if (itype.index == 0 || movable_blocks_per_type(itype).empty()) { + continue; + } + + count = 0; + for (int imove = 0; imove < num_of_avail_moves; imove++) { + const auto& move_name = move_type_to_string(e_move_type(imove)); + int moves = blk_type_moves[itype.index][imove]; + if (moves != 0) { + int accepted = accepted_moves[itype.index][imove]; + int rejected = rejected_moves[itype.index][imove]; + int aborted = moves - (accepted + rejected); + if (count == 0) { + VTR_LOG("%-18.20s", itype.name); + } else { + VTR_LOG(" "); + } + VTR_LOG( + " %-22.20s %-16.2f %-15.2f %-14.2f %-13.2f\n", + move_name.c_str(), 100.0f * (float)moves / (float)total_moves, + 100.0f * (float)accepted / (float)moves, 100.0f * (float)rejected / (float)moves, + 100.0f * (float)aborted / (float)moves); + } + count++; + } + VTR_LOG("\n"); + } + VTR_LOG("\n"); +} diff --git a/vpr/src/place/move_generator.h b/vpr/src/place/move_generator.h index 90688e77981..524147d48de 100644 --- a/vpr/src/place/move_generator.h +++ b/vpr/src/place/move_generator.h @@ -34,6 +34,8 @@ struct MoveTypeStat { vtr::NdMatrix blk_type_moves; vtr::NdMatrix accepted_moves; vtr::NdMatrix rejected_moves; + + void print_placement_move_types_stats(); }; /** @@ -49,6 +51,8 @@ class MoveGenerator { , reward_func_(reward_function) {} MoveGenerator() = delete; + MoveGenerator(const MoveGenerator&) = delete; + MoveGenerator& operator=(const MoveGenerator&) = delete; virtual ~MoveGenerator() = default; /** diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 92ef82a0bfa..fff204b22f9 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -332,8 +332,6 @@ static void print_resources_utilization(const BlkLocRegistry& blk_loc_registry); static void print_placement_swaps_stats(const t_annealing_state& state, const t_swap_stats& swap_stats); -static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat); - /** * @brief Copies the placement location variables into the global placement context. * @param blk_loc_registry The placement location variables to be copied. @@ -953,7 +951,7 @@ void try_place(const Netlist<>& net_list, print_placement_swaps_stats(state, swap_stats); - print_placement_move_types_stats(move_type_stat); + move_type_stat.print_placement_move_types_stats(); if (noc_opts.noc) { write_noc_placement_file(noc_opts.noc_placement_file_name, blk_loc_registry.block_locs()); @@ -2271,58 +2269,6 @@ static void print_placement_swaps_stats(const t_annealing_state& state, const t_ swap_stats.num_swap_aborted, 100 * abort_rate); } -static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat) { - VTR_LOG("\n\nPlacement perturbation distribution by block and move type: \n"); - - VTR_LOG( - "------------------ ----------------- ---------------- ---------------- --------------- ------------ \n"); - VTR_LOG( - " Block Type Move Type (%%) of Total Accepted(%%) Rejected(%%) Aborted(%%)\n"); - VTR_LOG( - "------------------ ----------------- ---------------- ---------------- --------------- ------------ \n"); - - int total_moves = 0; - for (size_t i = 0; i < move_type_stat.blk_type_moves.size(); ++i) { - total_moves += move_type_stat.blk_type_moves.get(i); - } - - auto& device_ctx = g_vpr_ctx.device(); - int count = 0; - int num_of_avail_moves = move_type_stat.blk_type_moves.size() / device_ctx.logical_block_types.size(); - - //Print placement information for each block type - for (const auto& itype : device_ctx.logical_block_types) { - //Skip non-existing block types in the netlist - if (itype.index == 0 || movable_blocks_per_type(itype).empty()) { - continue; - } - - count = 0; - for (int imove = 0; imove < num_of_avail_moves; imove++) { - const auto& move_name = move_type_to_string(e_move_type(imove)); - int moves = move_type_stat.blk_type_moves[itype.index][imove]; - if (moves != 0) { - int accepted = move_type_stat.accepted_moves[itype.index][imove]; - int rejected = move_type_stat.rejected_moves[itype.index][imove]; - int aborted = moves - (accepted + rejected); - if (count == 0) { - VTR_LOG("%-18.20s", itype.name); - } else { - VTR_LOG(" "); - } - VTR_LOG( - " %-22.20s %-16.2f %-15.2f %-14.2f %-13.2f\n", - move_name.c_str(), 100.0f * (float)moves / (float)total_moves, - 100.0f * (float)accepted / (float)moves, 100.0f * (float)rejected / (float)moves, - 100.0f * (float)aborted / (float)moves); - } - count++; - } - VTR_LOG("\n"); - } - VTR_LOG("\n"); -} - static void copy_locs_to_global_state(const BlkLocRegistry& blk_loc_registry) { auto& place_ctx = g_vpr_ctx.mutable_placement(); From 0b7bfa73743e74cc79b23841a7a14134cf07508f Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 3 Sep 2024 13:01:07 -0400 Subject: [PATCH 25/36] add some comments --- vpr/src/place/move_generator.h | 10 +++++++++- vpr/src/place/net_cost_handler.h | 26 +++++++++++++++++--------- vpr/src/place/place.cpp | 1 - 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/vpr/src/place/move_generator.h b/vpr/src/place/move_generator.h index 524147d48de..1b105b4d459 100644 --- a/vpr/src/place/move_generator.h +++ b/vpr/src/place/move_generator.h @@ -35,6 +35,9 @@ struct MoveTypeStat { vtr::NdMatrix accepted_moves; vtr::NdMatrix rejected_moves; + /** + * @brief Prints placement perturbation distribution by block and move type. + */ void print_placement_move_types_stats(); }; @@ -42,7 +45,6 @@ struct MoveTypeStat { * @brief a base class for move generators * * This class represents the base class for all move generators. - * All its functions are virtual functions. */ class MoveGenerator { public: @@ -88,6 +90,12 @@ class MoveGenerator { /** * @brief Calculates the agent's reward and the total process outcome + * + * @param move_outcome_stats Contains information about how much each cost term + * changes by this move and whether the move is accepted. + * @param delta_c The total change in cost by this move. + * @param timing_bb_factor This factor controls the weight of bb cost + * compared to the timing cost in the agent's reward function. */ void calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, double delta_c, diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 51b7d7a54a9..c45f735c5e6 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -95,18 +95,22 @@ class NetCostHandler { void reset_move_nets(); /** - * @brief update net cost data structures (in placer context and net_cost in .cpp file) and reset flags (proposed_net_cost and bb_updated_before). - * @param num_nets_affected The number of nets affected by the move. It is used to determine the index up to which elements in ts_nets_to_update are valid. + * @brief Update net cost data structures (in placer context and net_cost in .cpp file) + * and reset flags (proposed_net_cost and bb_updated_before). + * @param num_nets_affected The number of nets affected by the move. + * It is used to determine the index up to which elements in ts_nets_to_update are valid. */ void update_move_nets(); /** - * @brief re-calculates different terms of the cost function (wire-length, timing, NoC) and update "costs" accordingly. It is important to note that - * in this function bounding box and connection delays are not calculated from scratch. However, it iterates over all nets and connections and updates - * their costs by a complete summation, rather than incrementally. - * @param noc_opts - * @param delay_model - * @param criticalities + * @brief Re-calculates different terms of the cost function (wire-length, timing, NoC) + * and update "costs" accordingly. It is important to note that in this function bounding box + * and connection delays are not calculated from scratch. However, it iterates over all nets + * and connections and updates their costs by a complete summation, rather than incrementally. + * @param noc_opts Contains NoC cost weighting factors. + * @param delay_model Placement delay model. Used to compute timing cost. + * @param criticalities Contains the clustered netlist connection criticalities. + * Used to computed timing cost . * @param costs passed by reference and computed by this routine (i.e. returned by reference) */ void recompute_costs_from_scratch(const t_noc_opts& noc_opts, @@ -115,11 +119,15 @@ class NetCostHandler { t_placer_costs* costs); private: + ///@brief Specifies whether the bounding box is computed using cube method or per-layer method. bool cube_bb_ = false; + ///@brief A reference to the placer's state to be updated by this object. PlacerState& placer_state_; + ///@brief Contains some parameter that determine how the placement cost is computed. const t_placer_opts& placer_opts_; - + ///@brief Points to the proper method for computing the bounding box cost from scratch. std::function comp_bb_cost_functor_; + ///@brief Points to the proper method for updating the bounding box of a net. std::function update_bb_functor_; /** diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index fff204b22f9..164d2984a02 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -75,7 +75,6 @@ * compared to the timing cost in the agent's reward function. The reward is calculated as * * -1*(1.5-REWARD_BB_TIMING_RELATIVE_WEIGHT)*timing_cost + (1+REWARD_BB_TIMING_RELATIVE_WEIGHT)*bb_cost) */ - static constexpr float REWARD_BB_TIMING_RELATIVE_WEIGHT = 0.4; #ifdef VTR_ENABLE_DEBUG_LOGGING From 7f476f9395ac368eab64d32d8a1757fcfa783163 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 3 Sep 2024 13:21:22 -0400 Subject: [PATCH 26/36] move driven_by_moved_block() from net_cost_handler to t_pl_blocks_to_be_moved --- vpr/src/place/move_transactions.cpp | 16 +++++++ vpr/src/place/move_transactions.h | 20 +++++---- vpr/src/place/net_cost_handler.cpp | 65 +++++++---------------------- vpr/src/place/net_cost_handler.h | 8 ++++ 4 files changed, 53 insertions(+), 56 deletions(-) diff --git a/vpr/src/place/move_transactions.cpp b/vpr/src/place/move_transactions.cpp index 0065c70662d..c052c9976d1 100644 --- a/vpr/src/place/move_transactions.cpp +++ b/vpr/src/place/move_transactions.cpp @@ -165,3 +165,19 @@ void t_pl_blocks_to_be_moved::clear_move_blocks() { affected_pins.clear(); } + +bool t_pl_blocks_to_be_moved::driven_by_moved_block(const ClusterNetId net) const { + auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; + + bool is_driven_by_move_blk = false; + ClusterBlockId net_driver_block = clb_nlist.net_driver_block(net); + + for (const t_pl_moved_block& block : moved_blocks) { + if (net_driver_block == block.block_num) { + is_driven_by_move_blk = true; + break; + } + } + + return is_driven_by_move_blk; +} diff --git a/vpr/src/place/move_transactions.h b/vpr/src/place/move_transactions.h index 453e248cdea..b77115440e4 100644 --- a/vpr/src/place/move_transactions.h +++ b/vpr/src/place/move_transactions.h @@ -48,17 +48,23 @@ struct t_pl_blocks_to_be_moved { t_pl_blocks_to_be_moved(const t_pl_blocks_to_be_moved&) = delete; t_pl_blocks_to_be_moved(t_pl_blocks_to_be_moved&&) = delete; -/** - * @brief This function increments the size of the moved_blocks vector and return the index - * of the newly added last elements. - */ + /** + * @brief This function increments the size of the moved_blocks vector and return the index + * of the newly added last elements. + */ size_t get_size_and_increment(); -/** - * @brief This function clears all data structures of this struct. - */ + /** + * @brief This function clears all data structures of this struct. + */ void clear_move_blocks(); + /** + * @param net The unique identifier of the net of interest. + * @return True if the driver block of the net is among the moving blocks. + */ + bool driven_by_moved_block(const ClusterNetId net) const; + e_block_move_result record_block_move(ClusterBlockId blk, t_pl_loc to, diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index fa48dc39b77..577e69578d8 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -34,6 +34,8 @@ #include "noc_place_utils.h" #include "vtr_math.h" +#include + using std::max; using std::min; @@ -47,32 +49,14 @@ static constexpr int MAX_FANOUT_CROSSING_COUNT = 50; * for higher fanout nets. Each entry is the correction factor for the * fanout index-1 */ -static const float cross_count[MAX_FANOUT_CROSSING_COUNT] = {/* [0..49] */ 1.0, 1.0, 1.0, 1.0828, - 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974, 1.5455, 1.5937, - 1.6418, 1.6899, 1.7304, 1.7709, 1.8114, 1.8519, 1.8924, 1.9288, 1.9652, - 2.0015, 2.0379, 2.0743, 2.1061, 2.1379, 2.1698, 2.2016, 2.2334, 2.2646, - 2.2958, 2.3271, 2.3583, 2.3895, 2.4187, 2.4479, 2.4772, 2.5064, 2.5356, - 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148, 2.7410, 2.7671, - 2.7933}; +constexpr std::array cross_count = {1.0000, 1.0000, 1.0000, 1.0828, 1.1536, 1.2206, 1.2823, 1.3385, + 1.3991, 1.4493, 1.4974, 1.5455, 1.5937, 1.6418, 1.6899, 1.7304, + 1.7709, 1.8114, 1.8519, 1.8924, 1.9288, 1.9652, 2.0015, 2.0379, + 2.0743, 2.1061, 2.1379, 2.1698, 2.2016, 2.2334, 2.2646, 2.2958, + 2.3271, 2.3583, 2.3895, 2.4187, 2.4479, 2.4772, 2.5064, 2.5356, + 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148, 2.7410, + 2.7671, 2.7933}; -/** - * @param net The unique identifier of the net of interest. - * @param moved_blocks A vector of moving clustered blocks. - * @return True if the driver block of the net is among the moving blocks. - */ -static bool driven_by_moved_block(const ClusterNetId net, - const std::vector& moved_blocks); - -/** - * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer - * and return the sum of the lengths - * @param net_id ID of the net which wirelength estimate is requested - * @param bb Bounding box of the net - * @return Wirelength estimate of the net - */ -static double get_net_wirelength_from_layer_bb(ClusterNetId /*net_id*/, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count); @@ -327,9 +311,7 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { place_move_ctx.num_sink_pin_layer[size_t(net_id)]); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) { - expected_wirelength += get_net_wirelength_from_layer_bb(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + expected_wirelength += get_net_wirelength_from_layer_bb_(net_id); } } } @@ -1545,12 +1527,14 @@ static double get_net_wirelength_estimate(ClusterNetId net_id, const t_bb& bb) { return ncost; } -static double get_net_wirelength_from_layer_bb(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count) { +double NetCostHandler::get_net_wirelength_from_layer_bb_(ClusterNetId net_id) { /* 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 auto& layer_pin_sink_count = move_ctx.num_sink_pin_layer[size_t(net_id)]; + double ncost = 0.; const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); @@ -1632,7 +1616,7 @@ void NetCostHandler::find_affected_nets_and_update_costs(const PlaceDelayModel* bool is_src_moving = false; if (clb_nlist.pin_type(blk_pin) == PinType::SINK) { ClusterNetId net_id = clb_nlist.pin_net(blk_pin); - is_src_moving = driven_by_moved_block(net_id, blocks_affected.moved_blocks); + is_src_moving = blocks_affected.driven_by_moved_block(net_id); } update_net_info_on_pin_move_(delay_model, criticalities, @@ -1785,20 +1769,3 @@ void NetCostHandler::set_ts_edge_(const ClusterNetId net_id) { place_move_ctx.layer_bb_num_on_edges[net_id] = layer_ts_bb_edge_new_[net_id]; } } - - -static bool driven_by_moved_block(const ClusterNetId net, - const std::vector& moved_blocks) { - auto& clb_nlist = g_vpr_ctx.clustering().clb_nlist; - bool is_driven_by_move_blk = false; - ClusterBlockId net_driver_block = clb_nlist.net_driver_block(net); - - for (const t_pl_moved_block& block : moved_blocks) { - if (net_driver_block == block.block_num) { - is_driven_by_move_blk = true; - break; - } - } - - return is_driven_by_move_blk; -} \ No newline at end of file diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index c45f735c5e6..2992660d254 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -460,4 +460,12 @@ class NetCostHandler { const std::vector& bb, const vtr::NdMatrixProxy layer_pin_sink_count); + /** + * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer + * and return the sum of the lengths + * @param net_id ID of the net which wirelength estimate is requested + * @return Wirelength estimate of the net + */ + double get_net_wirelength_from_layer_bb_(ClusterNetId net_id); + }; From e233dab4c41900e7b326f323c46575eedd390396 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 3 Sep 2024 15:25:42 -0400 Subject: [PATCH 27/36] renamed some methods to avoid duplicate names --- vpr/src/place/net_cost_handler.cpp | 64 +++++++++++++++--------------- vpr/src/place/net_cost_handler.h | 24 +++++------ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 577e69578d8..4e0ca083103 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -126,7 +126,7 @@ 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()); - comp_bb_cost_functor_ = std::bind(&NetCostHandler::comp_3d_bb_cost_, this, std::placeholders::_1); + 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); } else { @@ -245,7 +245,7 @@ double NetCostHandler::comp_bb_cost(e_cost_methods method) { return comp_bb_cost_functor_(method); } -double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { +double NetCostHandler::comp_cube_bb_cost_(e_cost_methods method) { auto& cluster_ctx = g_vpr_ctx.clustering(); auto& place_move_ctx = placer_state_.mutable_move(); @@ -262,12 +262,12 @@ double NetCostHandler::comp_3d_bb_cost_(e_cost_methods method) { place_move_ctx.bb_num_on_edges[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } else { - get_non_updatable_bb_(net_id, - place_move_ctx.bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + get_non_updatable_cube_bb_(net_id, + place_move_ctx.bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - net_cost_[net_id] = get_net_cost_(net_id, place_move_ctx.bb_coords[net_id]); + net_cost_[net_id] = get_net_cube_bb_cost_(net_id, place_move_ctx.bb_coords[net_id]); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) { expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); @@ -301,14 +301,14 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { place_move_ctx.layer_bb_coords[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } else { - get_non_updatable_layer_bb_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + get_non_updatable_per_layer_bb_(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } - net_cost_[net_id] = get_net_layer_bb_wire_cost_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + net_cost_[net_id] = get_net_per_layer_bb_cost_(net_id, + place_move_ctx.layer_bb_coords[net_id], + place_move_ctx.num_sink_pin_layer[size_t(net_id)]); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) { expected_wirelength += get_net_wirelength_from_layer_bb_(net_id); @@ -500,9 +500,9 @@ void NetCostHandler::update_net_info_on_pin_move_(const PlaceDelayModel* delay_m } } -void NetCostHandler::get_non_updatable_bb_(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer) { +void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, + t_bb& bb_coord_new, + vtr::NdMatrixProxy num_sink_pin_layer) { //TODO: account for multiple physical pin instances per logical pin auto& cluster_ctx = g_vpr_ctx.clustering(); auto& device_ctx = g_vpr_ctx.device(); @@ -572,9 +572,9 @@ void NetCostHandler::get_non_updatable_bb_(ClusterNetId net_id, bb_coord_new.layer_max = max(min(layer_max, device_ctx.grid.get_num_layers() - 1), 0); } -void NetCostHandler::get_non_updatable_layer_bb_(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer) { +void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, + std::vector& bb_coord_new, + vtr::NdMatrixProxy num_sink_layer) { //TODO: account for multiple physical pin instances per logical pin auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1453,7 +1453,7 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, } } -double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { +double NetCostHandler::get_net_cube_bb_cost_(ClusterNetId net_id, const t_bb& bb) { // Finds the cost due to one net by looking at its coordinate bounding box. auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -1473,9 +1473,9 @@ double NetCostHandler::get_net_cost_(ClusterNetId net_id, const t_bb& bb) { return ncost; } -double NetCostHandler::get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count) { +double NetCostHandler::get_net_per_layer_bb_cost_(ClusterNetId /* net_id */, + const std::vector& bb, + const vtr::NdMatrixProxy layer_pin_sink_count) { // Finds the cost due to one net by looking at its coordinate bounding box. double ncost = 0.; @@ -1589,7 +1589,7 @@ void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { for (const ClusterNetId ts_net: ts_nets_to_update_) { ClusterNetId net_id = ts_net; - proposed_net_cost_[net_id] = get_net_cost_(net_id); + proposed_net_cost_[net_id] = get_net_bb_cost_(net_id); bb_delta_c += proposed_net_cost_[net_id] - net_cost_[net_id]; } @@ -1733,22 +1733,22 @@ void NetCostHandler::recompute_costs_from_scratch(const t_noc_opts& noc_opts, void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { if (cube_bb_) { - get_non_updatable_bb_(net, - ts_bb_coord_new_[net], - ts_layer_sink_pin_count_[size_t(net)]); + get_non_updatable_cube_bb_(net, + ts_bb_coord_new_[net], + ts_layer_sink_pin_count_[size_t(net)]); } else { - get_non_updatable_layer_bb_(net, - layer_ts_bb_coord_new_[net], - ts_layer_sink_pin_count_[size_t(net)]); + get_non_updatable_per_layer_bb_(net, + layer_ts_bb_coord_new_[net], + ts_layer_sink_pin_count_[size_t(net)]); } } -double NetCostHandler::get_net_cost_(const ClusterNetId net_id) { +double NetCostHandler::get_net_bb_cost_(const ClusterNetId net_id) { if (cube_bb_) { - return get_net_cost_(net_id, ts_bb_coord_new_[net_id]); + return get_net_cube_bb_cost_(net_id, ts_bb_coord_new_[net_id]); } else { - return get_net_layer_bb_wire_cost_(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); + return get_net_per_layer_bb_cost_(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); } } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 2992660d254..0a39adcafd9 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -259,7 +259,7 @@ class NetCostHandler { void get_non_updatable_bb_(const ClusterNetId net); - double get_net_cost_(const ClusterNetId net_id); + double get_net_bb_cost_(const ClusterNetId net_id); void set_ts_bb_coord_(const ClusterNetId net_id); @@ -272,9 +272,9 @@ class NetCostHandler { * @param bb_coord_new Computed by this function and returned by reference. * @param num_sink_pin_layer Store the number of sink pins of "net_id" on each layer */ - void get_non_updatable_bb_(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer); + void get_non_updatable_cube_bb_(ClusterNetId net_id, + t_bb& bb_coord_new, + vtr::NdMatrixProxy num_sink_pin_layer); /** * @brief Calculate the per-layer bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and @@ -283,9 +283,9 @@ class NetCostHandler { * @param bb_coord_new Computed by this function and returned by reference. * @param num_sink_layer Store the number of sink pins of "net_id" on each layer */ - void get_non_updatable_layer_bb_(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer); + void get_non_updatable_per_layer_bb_(ClusterNetId net_id, + std::vector& bb_coord_new, + vtr::NdMatrixProxy num_sink_layer); /** * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. @@ -426,7 +426,7 @@ class NetCostHandler { std::vector& bb_coord_new); double comp_per_layer_bb_cost_(e_cost_methods method); - double comp_3d_bb_cost_(e_cost_methods method); + double comp_cube_bb_cost_(e_cost_methods method); /** * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. @@ -447,7 +447,7 @@ class NetCostHandler { * @param bb Bounding box of the net * @return Wirelength cost of the net */ - double get_net_cost_(ClusterNetId net_id, const t_bb& bb); + double get_net_cube_bb_cost_(ClusterNetId net_id, const t_bb& bb); /** * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer @@ -456,9 +456,9 @@ class NetCostHandler { * @param bb Per-layer bounding box of the net * @return Wirelength cost of the net */ - double get_net_layer_bb_wire_cost_(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count); + double get_net_per_layer_bb_cost_(ClusterNetId /* net_id */, + const std::vector& bb, + const vtr::NdMatrixProxy layer_pin_sink_count); /** * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer From a2e8b4acbf5acb19e4889c06753cf205a85fcf2f Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Tue, 3 Sep 2024 16:04:09 -0400 Subject: [PATCH 28/36] remove unused header includes --- vpr/src/place/place_macro.cpp | 3 --- vpr/src/place/place_timing_update.cpp | 4 ++-- vpr/src/place/simpleRL_move_generator.cpp | 10 +++++++--- vpr/src/place/timing_place.cpp | 5 ----- vpr/src/place/timing_place_lookup.cpp | 20 ++++++-------------- 5 files changed, 15 insertions(+), 27 deletions(-) diff --git a/vpr/src/place/place_macro.cpp b/vpr/src/place/place_macro.cpp index 69c06503ca7..78c1a186d20 100644 --- a/vpr/src/place/place_macro.cpp +++ b/vpr/src/place/place_macro.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -12,8 +11,6 @@ #include "vpr_error.h" #include "physical_types.h" #include "globals.h" -#include "place.h" -#include "read_xml_arch_file.h" #include "place_macro.h" #include "vpr_utils.h" #include "echo_files.h" diff --git a/vpr/src/place/place_timing_update.cpp b/vpr/src/place/place_timing_update.cpp index 8c941bd1d81..d558f386c4b 100644 --- a/vpr/src/place/place_timing_update.cpp +++ b/vpr/src/place/place_timing_update.cpp @@ -168,7 +168,7 @@ void update_timing_cost(const PlaceDelayModel* delay_model, PlacerState& placer_state, double* timing_cost) { #ifdef INCR_COMP_TD_COSTS - update_td_costs(delay_model, *criticalities, block_locs, timing_cost); + update_td_costs(delay_model, *criticalities, placer_state, timing_cost); #else comp_td_costs(delay_model, *criticalities, placer_state, timing_cost); #endif @@ -298,7 +298,7 @@ void update_td_costs(const PlaceDelayModel* delay_model, #ifdef VTR_ASSERT_DEBUG_ENABLED double check_timing_cost = 0.; - comp_td_costs(delay_model, place_crit, &check_timing_cost); + comp_td_costs(delay_model, place_crit, placer_state, &check_timing_cost); VTR_ASSERT_DEBUG_MSG(check_timing_cost == *timing_cost, "Total timing cost calculated incrementally in update_td_costs() is " "not consistent with value calculated from scratch in comp_td_costs()"); diff --git a/vpr/src/place/simpleRL_move_generator.cpp b/vpr/src/place/simpleRL_move_generator.cpp index 3c1539d244c..62a6d933bf7 100644 --- a/vpr/src/place/simpleRL_move_generator.cpp +++ b/vpr/src/place/simpleRL_move_generator.cpp @@ -1,11 +1,15 @@ + #include "simpleRL_move_generator.h" + #include "globals.h" +#include "vtr_random.h" +#include "vtr_time.h" + #include #include #include -#include "vtr_random.h" -#include "vtr_time.h" + /* File-scope routines */ //a scaled and clipped exponential function static float scaled_clipped_exp(float x) { return std::exp(std::min(1000 * x, float(3.0))); } @@ -50,7 +54,7 @@ KArmedBanditAgent::KArmedBanditAgent(std::vector available_moves, e } /* - * If the agent selects both move type and block type, the would lool like this: + * If the agent selects both move type and block type, the action table would look like this: * * +---------------+---------------+---------------+---------------+ * | (blk0, move0) | (blk0, move1) | ............. | (blk0, moveN) | diff --git a/vpr/src/place/timing_place.cpp b/vpr/src/place/timing_place.cpp index 0ab198cb8cc..1e4985b7852 100644 --- a/vpr/src/place/timing_place.cpp +++ b/vpr/src/place/timing_place.cpp @@ -3,18 +3,13 @@ * @brief Stores the method definitions of classes defined in timing_place.h. */ -#include #include #include "vtr_util.h" -#include "vtr_memory.h" -#include "vtr_log.h" #include "vpr_types.h" #include "vpr_utils.h" -#include "globals.h" #include "net_delay.h" -#include "timing_place_lookup.h" #include "timing_place.h" #include "placer_state.h" diff --git a/vpr/src/place/timing_place_lookup.cpp b/vpr/src/place/timing_place_lookup.cpp index c16a0d6dbad..f55dcf4cbcc 100644 --- a/vpr/src/place/timing_place_lookup.cpp +++ b/vpr/src/place/timing_place_lookup.cpp @@ -1,7 +1,5 @@ -#include -#include + #include -#include #include #include "rr_graph_fwd.h" @@ -15,20 +13,14 @@ #include "vtr_geometry.h" #include "arch_util.h" - #include "vpr_types.h" #include "globals.h" #include "place_and_route.h" -#include "route_common.h" #include "route_net.h" -#include "route_export.h" -#include "rr_graph.h" #include "timing_place_lookup.h" #include "read_xml_arch_file.h" -#include "echo_files.h" #include "atom_netlist.h" -#include "rr_graph2.h" -#include "place_util.h" + // all functions in profiling:: namespace, which are only activated if PROFILE is defined #include "route_profiling.h" #include "router_delay_profiling.h" @@ -167,7 +159,7 @@ static int get_longest_segment_length(std::vector& segment_inf); static void fix_empty_coordinates(vtr::NdMatrix& delta_delays); static void fix_uninitialized_coordinates(vtr::NdMatrix& delta_delays); -static float find_neightboring_average(vtr::NdMatrix& matrix, t_physical_tile_loc tile_loc, int max_distance); +static float find_neighboring_average(vtr::NdMatrix& matrix, t_physical_tile_loc tile_loc, int max_distance); /******* Globally Accessible Functions **********/ @@ -894,7 +886,7 @@ float delay_reduce(std::vector& delays, e_reducer reducer) { * If no legal values are found to average over with a range of max_distance, * we return IMPOSSIBLE_DELTA. */ -static float find_neightboring_average( +static float find_neighboring_average( vtr::NdMatrix& matrix, t_physical_tile_loc tile_loc, int max_distance) { @@ -949,7 +941,7 @@ static void fix_empty_coordinates(vtr::NdMatrix& delta_delays) { for (int delta_x = 0; delta_x < (int)delta_delays.dim_size(1); ++delta_x) { for (int delta_y = 0; delta_y < (int)delta_delays.dim_size(2); ++delta_y) { if (delta_delays[layer_num][delta_x][delta_y] == EMPTY_DELTA) { - delta_delays[layer_num][delta_x][delta_y] = find_neightboring_average(delta_delays, {delta_x, delta_y, layer_num}, kMaxAverageDistance); + delta_delays[layer_num][delta_x][delta_y] = find_neighboring_average(delta_delays, {delta_x, delta_y, layer_num}, kMaxAverageDistance); } } } @@ -987,7 +979,7 @@ static void fill_impossible_coordinates(vtr::NdMatrix& delta_delays) { for (int delta_x = 0; delta_x < (int)delta_delays.dim_size(1); ++delta_x) { for (int delta_y = 0; delta_y < (int)delta_delays.dim_size(2); ++delta_y) { if (delta_delays[layer_num][delta_x][delta_y] == IMPOSSIBLE_DELTA) { - delta_delays[layer_num][delta_x][delta_y] = find_neightboring_average( + delta_delays[layer_num][delta_x][delta_y] = find_neighboring_average( delta_delays, {delta_x, delta_y, layer_num}, kMaxAverageDistance); } } From 845c4cbc235fb2522c109428cfee27f7fe613d9a Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 4 Sep 2024 15:33:33 -0400 Subject: [PATCH 29/36] applied PR comments --- vpr/src/place/move_generator.cpp | 53 +++++++++++++++++++------------- vpr/src/place/net_cost_handler.h | 7 ++--- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/vpr/src/place/move_generator.cpp b/vpr/src/place/move_generator.cpp index 4d7141584c9..7bc215f2388 100644 --- a/vpr/src/place/move_generator.cpp +++ b/vpr/src/place/move_generator.cpp @@ -6,29 +6,38 @@ void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, double delta_c, float timing_bb_factor) { - if (reward_func_ == e_reward_function::BASIC) { - process_outcome(-1 * delta_c, reward_func_); - } else if (reward_func_ == e_reward_function::NON_PENALIZING_BASIC || reward_func_ == e_reward_function::RUNTIME_AWARE) { - if (delta_c < 0) { + switch (reward_func_) { + case e_reward_function::WL_BIASED_RUNTIME_AWARE: + if (delta_c < 0) { + float reward = -1 + * (move_outcome_stats.delta_cost_norm + + (0.5 - timing_bb_factor) + * move_outcome_stats.delta_timing_cost_norm + + timing_bb_factor + * move_outcome_stats.delta_bb_cost_norm); + process_outcome(reward, reward_func_); + } else { + process_outcome(0, reward_func_); + } + break; + + case e_reward_function::BASIC: process_outcome(-1 * delta_c, reward_func_); - } else { - process_outcome(0, reward_func_); - } - } else if (reward_func_ == e_reward_function::WL_BIASED_RUNTIME_AWARE) { - if (delta_c < 0) { - float reward = -1 - * (move_outcome_stats.delta_cost_norm - + (0.5 - timing_bb_factor) - * move_outcome_stats.delta_timing_cost_norm - + timing_bb_factor - * move_outcome_stats.delta_bb_cost_norm); - process_outcome(reward, reward_func_); - } else { - process_outcome(0, reward_func_); - } - } else { - VTR_ASSERT_SAFE(reward_func_ == e_reward_function::UNDEFINED_REWARD); - VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); + break; + + case e_reward_function::NON_PENALIZING_BASIC: + case e_reward_function::RUNTIME_AWARE: + if (delta_c < 0) { + process_outcome(-1 * delta_c, reward_func_); + } else { + process_outcome(0, reward_func_); + } + break; + + default: + VTR_ASSERT_SAFE(reward_func_ == e_reward_function::UNDEFINED_REWARD); + VPR_ERROR(VPR_ERROR_PLACE, "Undefined reward function!\n"); + break; } } diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 0a39adcafd9..99b748d409e 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -132,7 +132,6 @@ class NetCostHandler { /** * @brief for the states of the bounding box. - * Stored as char for memory efficiency. */ enum class NetUpdateState { NOT_UPDATED_YET, @@ -231,7 +230,7 @@ class NetCostHandler { /** * @brief Allocates and loads the chanx_place_cost_fac and chany_place_cost_fac arrays with the inverse of - * the average number of tracks per channelbetween [subhigh] and [sublow]. + * the average number of tracks per channel between [subhigh] and [sublow]. * @param place_cost_exp It is an exponent to which you take the average inverse channel capacity; * a higher value would favour wider channels more over narrower channels during placement (usually we use 1). */ @@ -452,11 +451,11 @@ class NetCostHandler { /** * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer * and return the sum of the costs - * @param net_id ID of the net which cost is requested + * @param net_id ID of the net which cost is requested. Currently unused * @param bb Per-layer bounding box of the net * @return Wirelength cost of the net */ - double get_net_per_layer_bb_cost_(ClusterNetId /* net_id */, + double get_net_per_layer_bb_cost_(ClusterNetId net_id, const std::vector& bb, const vtr::NdMatrixProxy layer_pin_sink_count); From d2e9d8584411cd64453dd08f366d94ae7eb0b512 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Wed, 4 Sep 2024 15:47:38 -0400 Subject: [PATCH 30/36] revert the order of args in t_2D_bb's constructor --- vpr/src/base/vpr_types.h | 8 +++++--- vpr/src/place/net_cost_handler.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 74877a9be8f..fb006dc64a5 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -618,19 +618,21 @@ struct t_bb { */ struct t_2D_bb { t_2D_bb() = default; - t_2D_bb(int xmin_, int ymin_, int xmax_, int ymax_, int layer_num_) + t_2D_bb(int xmin_, int xmax_, int ymin_, int ymax_, int layer_num_) : xmin(xmin_) - , ymin(ymin_) , xmax(xmax_) + , ymin(ymin_) , ymax(ymax_) , layer_num(layer_num_) { VTR_ASSERT(xmax_ >= xmin_); VTR_ASSERT(ymax_ >= ymin_); VTR_ASSERT(layer_num_ >= 0); } + + int xmin = OPEN; - int ymin = OPEN; int xmax = OPEN; + int ymin = OPEN; int ymax = OPEN; int layer_num = OPEN; }; diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 4e0ca083103..4f20f89dc07 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -591,7 +591,7 @@ void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, int src_y = block_locs[bnum].loc.y + physical_tile_type(block_loc)->pin_height_offset[pnum]; for (int layer_num = 0; layer_num < num_layers; layer_num++) { - bb_coord_new[layer_num] = t_2D_bb{src_x, src_y, src_x, src_y, layer_num}; + bb_coord_new[layer_num] = t_2D_bb{src_x, src_x, src_y, src_y, layer_num}; num_sink_layer[layer_num] = 0; } @@ -1400,7 +1400,7 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, // when per-layer bounding box is used, we want the bounding box on each layer to also include // the location of source since the connection on each layer starts from that location. for (int layer_num = 0; layer_num < num_layers; layer_num++) { - coords[layer_num] = t_2D_bb{x_src, y_src, x_src, y_src, layer_num}; + coords[layer_num] = t_2D_bb{x_src, x_src, y_src, y_src, layer_num}; num_on_edges[layer_num] = t_2D_bb{1, 1, 1, 1, layer_num}; layer_pin_sink_count[layer_num] = 0; } From 9618d5313605d274280d520ca41e09cc884b1c01 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 11:50:03 -0400 Subject: [PATCH 31/36] fix typos and add comments --- vpr/src/base/vpr_types.h | 1 - vpr/src/place/centroid_move_generator.h | 2 ++ vpr/src/place/move_generator.h | 10 ++++++++++ vpr/src/place/move_transactions.cpp | 7 +++---- vpr/src/place/move_transactions.h | 3 +++ vpr/src/place/net_cost_handler.h | 1 + vpr/src/place/place.cpp | 4 ++-- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 58d82485489..b976a585400 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -629,7 +629,6 @@ struct t_2D_bb { VTR_ASSERT(layer_num_ >= 0); } - int xmin = OPEN; int xmax = OPEN; int ymin = OPEN; diff --git a/vpr/src/place/centroid_move_generator.h b/vpr/src/place/centroid_move_generator.h index dc7311f81e9..01ee259cbc8 100644 --- a/vpr/src/place/centroid_move_generator.h +++ b/vpr/src/place/centroid_move_generator.h @@ -26,6 +26,8 @@ class CentroidMoveGenerator : public MoveGenerator { * * @param placer_state A mutable reference to the placement state which will * be stored in this object. + * @param reward_function Specifies the reward function to update q-tables + * of the RL agent. */ CentroidMoveGenerator(PlacerState& placer_state, e_reward_function reward_function); diff --git a/vpr/src/place/move_generator.h b/vpr/src/place/move_generator.h index 1b105b4d459..d14c14312d0 100644 --- a/vpr/src/place/move_generator.h +++ b/vpr/src/place/move_generator.h @@ -48,6 +48,16 @@ struct MoveTypeStat { */ class MoveGenerator { public: + + /** + * @brief Initializes some protected member variables that are used + * by inheriting classes. + * + * @param placer_state A mutable reference to the placement state which will + * be stored in this object. + * @param reward_function Specifies the reward function to update q-tables + * of the RL agent. + */ MoveGenerator(PlacerState& placer_state, e_reward_function reward_function) : placer_state_(placer_state) , reward_func_(reward_function) {} diff --git a/vpr/src/place/move_transactions.cpp b/vpr/src/place/move_transactions.cpp index c052c9976d1..b12de81880b 100644 --- a/vpr/src/place/move_transactions.cpp +++ b/vpr/src/place/move_transactions.cpp @@ -94,8 +94,7 @@ void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, } } -//Commits the blocks in blocks_affected to their new locations (updates inverse -//lookups via place_ctx.grid_blocks) +//Commits the blocks in blocks_affected to their new locations (updates inverse lookups in grid_blocks) void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, GridBlock& grid_blocks) { @@ -138,9 +137,9 @@ void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, blk_loc_registry.mutable_block_locs()[blk].loc = old_loc; // get physical tile type of the old location - t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x,old_loc.y,old_loc.layer}); + t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x, old_loc.y, old_loc.layer}); // get physical tile type of the new location - t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x,new_loc.y, new_loc.layer}); + t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x, new_loc.y, new_loc.layer}); //if physical tile type of old location does not equal physical tile type of new location, sync the new physical pins if (old_type != new_type) { diff --git a/vpr/src/place/move_transactions.h b/vpr/src/place/move_transactions.h index b77115440e4..a70d43d214a 100644 --- a/vpr/src/place/move_transactions.h +++ b/vpr/src/place/move_transactions.h @@ -60,6 +60,9 @@ struct t_pl_blocks_to_be_moved { void clear_move_blocks(); /** + * @brief Determines if the given net is driven by at least of the + * moved blocks. + * * @param net The unique identifier of the net of interest. * @return True if the driver block of the net is among the moving blocks. */ diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 99b748d409e..c733cede4d6 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -1,4 +1,5 @@ #pragma once + #include "place_delay_model.h" #include "timing_place.h" #include "move_transactions.h" diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 65efe777e57..9df3966a4c9 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -754,8 +754,8 @@ void try_place(const Netlist<>& net_list, *current_move_generator, manual_move_generator, blocks_affected, timing_info.get(), placer_opts.place_algorithm, move_type_stat, - timing_bb_factor, - swap_stats, placer_state, net_cost_handler); + timing_bb_factor, swap_stats, + placer_state, net_cost_handler); //move the update used move_generator to its original variable update_move_generator(move_generator, move_generator2, agent_state, From 4598234bc1750a3acfc888d4cfa0c8d76b5aed43 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 13:11:27 -0400 Subject: [PATCH 32/36] move apply_move_blocks(), commit_move_blocks(), and revert_move_blocks() to BlkLocRegistry class --- vpr/src/base/blk_loc_registry.cpp | 80 +++++++++++++++++++++++ vpr/src/base/blk_loc_registry.h | 19 ++++++ vpr/src/place/initial_noc_placement.cpp | 6 +- vpr/src/place/move_transactions.cpp | 85 ------------------------- vpr/src/place/move_transactions.h | 10 --- vpr/src/place/net_cost_handler.cpp | 3 + vpr/src/place/net_cost_handler.h | 10 ++- vpr/src/place/place.cpp | 17 ++--- 8 files changed, 118 insertions(+), 112 deletions(-) diff --git a/vpr/src/base/blk_loc_registry.cpp b/vpr/src/base/blk_loc_registry.cpp index b8a6348dc1c..f3453ac794b 100644 --- a/vpr/src/base/blk_loc_registry.cpp +++ b/vpr/src/base/blk_loc_registry.cpp @@ -1,5 +1,7 @@ #include "blk_loc_registry.h" + +#include "move_transactions.h" #include "globals.h" const vtr::vector_map& BlkLocRegistry::block_locs() const { @@ -112,3 +114,81 @@ void BlkLocRegistry::place_sync_external_block_connections(ClusterBlockId iblk) } } } + +void BlkLocRegistry::apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { + auto& device_ctx = g_vpr_ctx.device(); + + // Swap the blocks, but don't swap the nets or update place_ctx.grid_blocks + // yet since we don't know whether the swap will be accepted + for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { + ClusterBlockId blk = moved_block.block_num; + + const t_pl_loc& old_loc = moved_block.old_loc; + const t_pl_loc& new_loc = moved_block.new_loc; + + // move the block to its new location + block_locs_[blk].loc = new_loc; + + // get physical tile type of the old location + t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x,old_loc.y,old_loc.layer}); + // get physical tile type of the new location + t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x,new_loc.y, new_loc.layer}); + + // if physical tile type of old location does not equal physical tile type of new location, sync the new physical pins + if (old_type != new_type) { + place_sync_external_block_connections(blk); + } + } +} + +void BlkLocRegistry::commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { + // Swap physical location + for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { + ClusterBlockId blk = moved_block.block_num; + + const t_pl_loc& to = moved_block.new_loc; + const t_pl_loc& from = moved_block.old_loc; + + // Remove from old location only if it hasn't already been updated by a previous block update + if (grid_blocks_.block_at_location(from) == blk) { + grid_blocks_.set_block_at_location(from, ClusterBlockId::INVALID()); + grid_blocks_.decrement_usage({from.x, from.y, from.layer}); + } + + // Add to new location + if (grid_blocks_.block_at_location(to) == ClusterBlockId::INVALID()) { + //Only need to increase usage if previously unused + grid_blocks_.increment_usage({to.x, to.y, to.layer}); + } + grid_blocks_.set_block_at_location(to, blk); + + } // Finish updating clb for all blocks +} + +void BlkLocRegistry::revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { + auto& device_ctx = g_vpr_ctx.device(); + + // Swap the blocks back, nets not yet swapped they don't need to be changed + for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { + ClusterBlockId blk = moved_block.block_num; + + const t_pl_loc& old_loc = moved_block.old_loc; + const t_pl_loc& new_loc = moved_block.new_loc; + + // return the block to where it was before the swap + block_locs_[blk].loc = old_loc; + + // get physical tile type of the old location + t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x, old_loc.y, old_loc.layer}); + // get physical tile type of the new location + t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x, new_loc.y, new_loc.layer}); + + // if physical tile type of old location does not equal physical tile type of new location, sync the new physical pins + if (old_type != new_type) { + place_sync_external_block_connections(blk); + } + + VTR_ASSERT_SAFE_MSG(grid_blocks_.block_at_location(old_loc) == blk, + "Grid blocks should only have been updated if swap committed (not reverted)"); + } +} diff --git a/vpr/src/base/blk_loc_registry.h b/vpr/src/base/blk_loc_registry.h index 99567d17e0a..703066e74f6 100644 --- a/vpr/src/base/blk_loc_registry.h +++ b/vpr/src/base/blk_loc_registry.h @@ -7,6 +7,7 @@ #include "grid_block.h" struct t_block_loc; +struct t_pl_blocks_to_be_moved; /** * @class BlkLocRegistry contains information about the placement of clustered blocks. @@ -80,6 +81,24 @@ class BlkLocRegistry { * It does not check for overuse of locations, therefore it can be used with placements that have resource overuse. */ void place_sync_external_block_connections(ClusterBlockId iblk); + + /** + * @brief Moves the blocks in blocks_affected to their new locations + * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. + */ + void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); + + /** + * @brief Commits the blocks in blocks_affected to their new locations (updates inverse lookups in grid_blocks) + * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. + */ + void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); + + /** + * @brief Moves the blocks in blocks_affected to their old locations + * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. + */ + void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); }; #endif //VTR_BLK_LOC_REGISTRY_H diff --git a/vpr/src/place/initial_noc_placement.cpp b/vpr/src/place/initial_noc_placement.cpp index cd6c9c957ba..4b8d9409994 100644 --- a/vpr/src/place/initial_noc_placement.cpp +++ b/vpr/src/place/initial_noc_placement.cpp @@ -242,7 +242,7 @@ static void noc_routers_anneal(const t_noc_opts& noc_opts, e_create_move create_move_outcome = propose_router_swap(blocks_affected, r_lim_decayed, blk_loc_registry); if (create_move_outcome != e_create_move::ABORT) { - apply_move_blocks(blocks_affected, blk_loc_registry); + blk_loc_registry.apply_move_blocks(blocks_affected); NocCostTerms noc_delta_c; find_affected_noc_routers_and_update_noc_costs(blocks_affected, noc_delta_c, block_locs); @@ -253,7 +253,7 @@ static void noc_routers_anneal(const t_noc_opts& noc_opts, if (move_accepted) { costs.cost += delta_cost; - commit_move_blocks(blocks_affected, blk_loc_registry.mutable_grid_blocks()); + blk_loc_registry.commit_move_blocks(blocks_affected); commit_noc_costs(); costs += noc_delta_c; // check if the current placement is better than the stored checkpoint @@ -261,7 +261,7 @@ static void noc_routers_anneal(const t_noc_opts& noc_opts, checkpoint.save_checkpoint(costs.cost, block_locs); } } else { // The proposed move is rejected - revert_move_blocks(blocks_affected, blk_loc_registry); + blk_loc_registry.revert_move_blocks(blocks_affected); revert_noc_traffic_flow_routes(blocks_affected, block_locs); } } diff --git a/vpr/src/place/move_transactions.cpp b/vpr/src/place/move_transactions.cpp index b12de81880b..a116be0d326 100644 --- a/vpr/src/place/move_transactions.cpp +++ b/vpr/src/place/move_transactions.cpp @@ -66,91 +66,6 @@ std::set t_pl_blocks_to_be_moved::determine_locations_emptied_by_move( return empty_locs; } -//Moves the blocks in blocks_affected to their new locations -void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - BlkLocRegistry& blk_loc_registry) { - auto& device_ctx = g_vpr_ctx.device(); - - //Swap the blocks, but don't swap the nets or update place_ctx.grid_blocks - //yet since we don't know whether the swap will be accepted - for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { - ClusterBlockId blk = moved_block.block_num; - - const t_pl_loc& old_loc = moved_block.old_loc; - const t_pl_loc& new_loc = moved_block.new_loc; - - // move the block to its new location - blk_loc_registry.mutable_block_locs()[blk].loc = new_loc; - - // get physical tile type of the old location - t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x,old_loc.y,old_loc.layer}); - // get physical tile type of the new location - t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x,new_loc.y, new_loc.layer}); - - //if physical tile type of old location does not equal physical tile type of new location, sync the new physical pins - if (old_type != new_type) { - blk_loc_registry.place_sync_external_block_connections(blk); - } - } -} - -//Commits the blocks in blocks_affected to their new locations (updates inverse lookups in grid_blocks) -void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - GridBlock& grid_blocks) { - - /* Swap physical location */ - for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { - ClusterBlockId blk = moved_block.block_num; - - const t_pl_loc& to = moved_block.new_loc; - const t_pl_loc& from = moved_block.old_loc; - - //Remove from old location only if it hasn't already been updated by a previous block update - if (grid_blocks.block_at_location(from) == blk) { - grid_blocks.set_block_at_location(from, ClusterBlockId::INVALID()); - grid_blocks.decrement_usage({from.x, from.y, from.layer}); - } - - //Add to new location - if (grid_blocks.block_at_location(to) == ClusterBlockId::INVALID()) { - //Only need to increase usage if previously unused - grid_blocks.increment_usage({to.x, to.y, to.layer}); - } - grid_blocks.set_block_at_location(to, blk); - - } // Finish updating clb for all blocks -} - -//Moves the blocks in blocks_affected to their old locations -void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - BlkLocRegistry& blk_loc_registry) { - auto& device_ctx = g_vpr_ctx.device(); - - // Swap the blocks back, nets not yet swapped they don't need to be changed - for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { - ClusterBlockId blk = moved_block.block_num; - - const t_pl_loc& old_loc = moved_block.old_loc; - const t_pl_loc& new_loc = moved_block.new_loc; - - // return the block to where it was before the swap - blk_loc_registry.mutable_block_locs()[blk].loc = old_loc; - - // get physical tile type of the old location - t_physical_tile_type_ptr old_type = device_ctx.grid.get_physical_type({old_loc.x, old_loc.y, old_loc.layer}); - // get physical tile type of the new location - t_physical_tile_type_ptr new_type = device_ctx.grid.get_physical_type({new_loc.x, new_loc.y, new_loc.layer}); - - //if physical tile type of old location does not equal physical tile type of new location, sync the new physical pins - if (old_type != new_type) { - blk_loc_registry.place_sync_external_block_connections(blk); - } - - VTR_ASSERT_SAFE_MSG(blk_loc_registry.grid_blocks().block_at_location(old_loc) == blk, - "Grid blocks should only have been updated if swap committed (not reverted)"); - } -} - //Clears the current move so a new move can be proposed void t_pl_blocks_to_be_moved::clear_move_blocks() { //Reset moved flags diff --git a/vpr/src/place/move_transactions.h b/vpr/src/place/move_transactions.h index a70d43d214a..68686be262e 100644 --- a/vpr/src/place/move_transactions.h +++ b/vpr/src/place/move_transactions.h @@ -82,14 +82,4 @@ struct t_pl_blocks_to_be_moved { std::vector affected_pins; }; - -void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - BlkLocRegistry& blk_loc_registry); - -void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - GridBlock& grid_blocks); - -void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected, - BlkLocRegistry& blk_loc_registry); - #endif diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index 4f20f89dc07..b1f860542ae 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -646,8 +646,11 @@ void NetCostHandler::update_bb_(ClusterNetId net_id, const int num_layers = device_ctx.grid.get_num_layers(); + // Number of blocks on the edges of the bounding box t_bb& bb_edge_new = ts_bb_edge_new_[net_id]; + // Coordinates of the bounding box t_bb& bb_coord_new = ts_bb_coord_new_[net_id]; + // Number of sinks of the given net on each layer vtr::NdMatrixProxy num_sink_pin_layer_new = ts_layer_sink_pin_count_[size_t(net_id)]; pin_new_loc.x = max(min(pin_new_loc.x, device_ctx.grid.width() - 2), 1); //-2 for no perim channels diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index c733cede4d6..fdec3319dbe 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -326,9 +326,7 @@ class NetCostHandler { * the CLBs forming the edges of the bounding box can be used. Essentially, I am assuming the pins always lie on the * outside of the bounding box. The x and y coordinates are the pin's x and y coordinates. IO blocks are considered to be one * cell in for simplicity. - * @param bb_edge_new Number of blocks on the edges of the bounding box - * @param bb_coord_new Coordinates of the bounding box - * @param num_sink_pin_layer_new Number of sinks of the given net on each layer + * @param net_id ID of the net which the moving pin belongs to * @param pin_old_loc The old location of the moving pin * @param pin_new_loc The new location of the moving pin * @param src_pin Is the moving pin driving the net @@ -369,7 +367,7 @@ class NetCostHandler { * @param bb_coord_new The new bb calculated by this function * @param bb_layer_pin_sink_count The updated number of net's sinks on each layer * @param old_num_block_on_edge The current known number of blocks of the net on bounding box edges - * @param old_edge_coord The current known boudning box of the net + * @param old_edge_coord The current known bounding box of the net * @param new_num_block_on_edge The new bb calculated by this function * @param new_edge_coord The new bb edge calculated by this function * @@ -390,7 +388,7 @@ class NetCostHandler { * @param pin_old_loc Old location of the moving pin * @param pin_new_loc New location of the moving pin * @param curr_bb_edge The current known number of blocks of the net on bounding box edges - * @param curr_bb_coord The current known boudning box of the net + * @param curr_bb_coord The current known bounding box of the net * @param bb_pin_sink_count_new The updated number of net's sinks on each layer * @param bb_edge_new The new bb edge calculated by this function * @param bb_coord_new The new bb calculated by this function @@ -411,7 +409,7 @@ class NetCostHandler { * @param pin_old_loc Old location of the moving pin * @param pin_new_loc New location of the moving pin * @param curr_bb_edge The current known number of blocks of the net on bounding box edges - * @param curr_bb_coord The current known boudning box of the net + * @param curr_bb_coord The current known bounding box of the net * @param bb_pin_sink_count_new The updated number of net's sinks on each layer * @param bb_edge_new The new bb edge calculated by this function * @param bb_coord_new The new bb calculated by this function diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 9df3966a4c9..80e1b53fd15 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -1261,6 +1261,7 @@ static e_move_result try_swap(const t_annealing_state* state, * Returns whether the swap is accepted, rejected or aborted. * * Passes back the new value of the cost functions. */ + auto& blk_loc_registry = placer_state.mutable_blk_loc_registry(); const auto& block_locs = placer_state.block_locs(); float rlim_escape_fraction = placer_opts.rlim_escape_fraction; @@ -1345,17 +1346,17 @@ static e_move_result try_swap(const t_annealing_state* state, /* * To make evaluating the move simpler (e.g. calculating changed bounding box), * we first move the blocks to their new locations (apply the move to - * place_ctx.block_locs) and then compute the change in cost. If the move + * blk_loc_registry.block_locs) and then compute the change in cost. If the move * is accepted, the inverse look-up in place_ctx.grid_blocks is updated * (committing the move). If the move is rejected, the blocks are returned to - * their original positions (reverting place_ctx.block_locs to its original state). + * their original positions (reverting blk_loc_registry.block_locs to its original state). * * Note that the inverse look-up place_ctx.grid_blocks is only updated after * move acceptance is determined, so it should not be used when evaluating a move. */ /* Update the block positions */ - apply_move_blocks(blocks_affected, placer_state.mutable_blk_loc_registry()); + blk_loc_registry.apply_move_blocks(blocks_affected); //Find all the nets affected by this swap and update the wiring costs. //This cost value doesn't depend on the timing info. @@ -1466,7 +1467,7 @@ static e_move_result try_swap(const t_annealing_state* state, net_cost_handler.update_move_nets(); /* Update clb data structures since we kept the move. */ - commit_move_blocks(blocks_affected, placer_state.mutable_grid_blocks()); + blk_loc_registry.commit_move_blocks(blocks_affected); if (proposed_action.logical_blk_type_index != -1) { //if the agent proposed the block type, then collect the block type stat ++move_type_stat.accepted_moves[proposed_action.logical_blk_type_index][(int)proposed_action.move_type]; @@ -1489,8 +1490,8 @@ static e_move_result try_swap(const t_annealing_state* state, /* Reset the net cost function flags first. */ net_cost_handler.reset_move_nets(); - /* Restore the place_ctx.block_locs data structures to their state before the move. */ - revert_move_blocks(blocks_affected, placer_state.mutable_blk_loc_registry()); + /* Restore the blk_loc_registry.block_locs data structures to their state before the move. */ + blk_loc_registry.revert_move_blocks(blocks_affected); if (place_algorithm == SLACK_TIMING_PLACE) { /* Revert the timing delays and costs to pre-update values. */ @@ -2078,7 +2079,7 @@ int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry) { // Compute the supposed member's x,y,z location t_pl_loc member_pos = block_locs[head_iblk].loc + pl_macros[imacro].members[imember].offset; - // Check the place_ctx.block_locs data structure first + // Check the blk_loc_registry.block_locs data structure first if (block_locs[member_iblk].loc != member_pos) { VTR_LOG_ERROR( "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n", @@ -2086,7 +2087,7 @@ int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry) { error++; } - // Then check the place_ctx.grid data structure + // Then check the blk_loc_registry.grid data structure if (grid_blocks.block_at_location(member_pos) != member_iblk) { VTR_LOG_ERROR( "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n", From 521c9e3f8ca13de9929e8fb66c56e17d33a67554 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 16:54:03 -0400 Subject: [PATCH 33/36] apply PR comments --- libs/libvtrutil/src/vtr_memory.h | 2 +- vpr/src/base/blk_loc_registry.cpp | 15 +++++++++++++++ vpr/src/base/blk_loc_registry.h | 22 +++++++++++++++++++--- vpr/src/place/move_generator.cpp | 11 +++++++++++ vpr/src/place/net_cost_handler.h | 26 +++++++++++++++++++++++--- 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/libs/libvtrutil/src/vtr_memory.h b/libs/libvtrutil/src/vtr_memory.h index 80ab73766f2..72e92ebe8f8 100644 --- a/libs/libvtrutil/src/vtr_memory.h +++ b/libs/libvtrutil/src/vtr_memory.h @@ -14,7 +14,7 @@ namespace vtr { /** * @brief This function will force the container to be cleared * - * It release its held memory. + * It releases its held memory. * For efficiency, STL containers usually don't * release their actual heap-allocated memory until * destruction (even if Container::clear() is called). diff --git a/vpr/src/base/blk_loc_registry.cpp b/vpr/src/base/blk_loc_registry.cpp index f3453ac794b..4c2f767b0f1 100644 --- a/vpr/src/base/blk_loc_registry.cpp +++ b/vpr/src/base/blk_loc_registry.cpp @@ -4,6 +4,9 @@ #include "move_transactions.h" #include "globals.h" +BlkLocRegistry::BlkLocRegistry() + : expected_transaction_(e_expected_transaction::APPLY) {} + const vtr::vector_map& BlkLocRegistry::block_locs() const { return block_locs_; } @@ -118,6 +121,8 @@ void BlkLocRegistry::place_sync_external_block_connections(ClusterBlockId iblk) void BlkLocRegistry::apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { auto& device_ctx = g_vpr_ctx.device(); + VTR_ASSERT_DEBUG(expected_transaction_ == e_expected_transaction::APPLY); + // Swap the blocks, but don't swap the nets or update place_ctx.grid_blocks // yet since we don't know whether the swap will be accepted for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { @@ -139,9 +144,13 @@ void BlkLocRegistry::apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_aff place_sync_external_block_connections(blk); } } + + expected_transaction_ = e_expected_transaction::COMMIT_REVERT; } void BlkLocRegistry::commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { + VTR_ASSERT_DEBUG(expected_transaction_ == e_expected_transaction::COMMIT_REVERT); + // Swap physical location for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { ClusterBlockId blk = moved_block.block_num; @@ -163,11 +172,15 @@ void BlkLocRegistry::commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_af grid_blocks_.set_block_at_location(to, blk); } // Finish updating clb for all blocks + + expected_transaction_ = e_expected_transaction::APPLY; } void BlkLocRegistry::revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { auto& device_ctx = g_vpr_ctx.device(); + VTR_ASSERT_DEBUG(expected_transaction_ == e_expected_transaction::COMMIT_REVERT); + // Swap the blocks back, nets not yet swapped they don't need to be changed for (const t_pl_moved_block& moved_block : blocks_affected.moved_blocks) { ClusterBlockId blk = moved_block.block_num; @@ -191,4 +204,6 @@ void BlkLocRegistry::revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_af VTR_ASSERT_SAFE_MSG(grid_blocks_.block_at_location(old_loc) == blk, "Grid blocks should only have been updated if swap committed (not reverted)"); } + + expected_transaction_ = e_expected_transaction::APPLY; } diff --git a/vpr/src/base/blk_loc_registry.h b/vpr/src/base/blk_loc_registry.h index 703066e74f6..542bad3651d 100644 --- a/vpr/src/base/blk_loc_registry.h +++ b/vpr/src/base/blk_loc_registry.h @@ -20,7 +20,7 @@ struct t_pl_blocks_to_be_moved; */ class BlkLocRegistry { public: - BlkLocRegistry() = default; + BlkLocRegistry(); ~BlkLocRegistry() = default; BlkLocRegistry(const BlkLocRegistry&) = delete; BlkLocRegistry& operator=(const BlkLocRegistry&) = default; @@ -83,22 +83,38 @@ class BlkLocRegistry { void place_sync_external_block_connections(ClusterBlockId iblk); /** - * @brief Moves the blocks in blocks_affected to their new locations + * @brief Moves the blocks in blocks_affected to their new locations. + * This method only updates `grid_blocks_` member variable and not `grid_blocks_`. + * After this method is called, either commit_move_blocks() or revert_move_blocks() + * must be called to either revert the new locations or commit them to `grid_block_` * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. */ void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); /** * @brief Commits the blocks in blocks_affected to their new locations (updates inverse lookups in grid_blocks) + * This method can only be called after a call to apply_move_blocks() to commit the block location changes + * to `grid_block_`. If this method is called after apply_move_blocks(), revert_move_blocks() must not be called + * until the next call to apply_move_blocks() is made. * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. */ void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); /** - * @brief Moves the blocks in blocks_affected to their old locations + * @brief Moves the blocks in blocks_affected to their old locations by updating `block_locs_` member variable. + * This method can only be called after a call to apply_move_blocks() to revert the block location changes + * applied to `block_locs_`. If this method is called after apply_move_blocks(), commit_move_blocks() must not be called + * until the next call to apply_move_blocks() is made. * @param blocks_affected Clustered blocks affected by a swap and their old and new locations. */ void revert_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected); + + enum class e_expected_transaction { + APPLY, + COMMIT_REVERT + }; + + e_expected_transaction expected_transaction_; }; #endif //VTR_BLK_LOC_REGISTRY_H diff --git a/vpr/src/place/move_generator.cpp b/vpr/src/place/move_generator.cpp index 7bc215f2388..7c7e252a050 100644 --- a/vpr/src/place/move_generator.cpp +++ b/vpr/src/place/move_generator.cpp @@ -6,6 +6,16 @@ void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& move_outcome_stats, double delta_c, float timing_bb_factor) { + /* + * To learn about different reward functions refer to the following paper: + * Elgammal MA, Murray KE, Betz V. RLPlace: Using reinforcement learning and + * smart perturbations to optimize FPGA placement. + * IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems. + * 2021 Sep 3;41(8):2532-45. + * + * For runtime-aware reward function, the reward value is divided by a normalized + * runtime in the implementation of process_outcome() + */ switch (reward_func_) { case e_reward_function::WL_BIASED_RUNTIME_AWARE: if (delta_c < 0) { @@ -25,6 +35,7 @@ void MoveGenerator::calculate_reward_and_process_outcome(const MoveOutcomeStats& process_outcome(-1 * delta_c, reward_func_); break; + case e_reward_function::NON_PENALIZING_BASIC: case e_reward_function::RUNTIME_AWARE: if (delta_c < 0) { diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index fdec3319dbe..b692e36b3bf 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -1,3 +1,9 @@ +/** + * @file net_cost_handler.h + * @brief This file contains the declaration of NetCostHandler class used to update placement cost when a new move is proposed/committed. + * For more details on the overall algorithm, refer to the comment at the top of the net_cost_handler.cpp + */ + #pragma once #include "place_delay_model.h" @@ -38,9 +44,10 @@ class NetCostHandler { NetCostHandler& operator=(NetCostHandler&&) = delete; /** - * @brief Resize temporary swap data structures needed to determine which nets are affected by a move and data needed per net - * about where their terminals are in order to quickly (incrementally) update their wirelength costs. These data structures are - * (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, and ts_nets_to_update. + * @brief Initializes a NetCostHandler object, which contains temporary swap data structures needed to determine which nets + * are affected by a move and data needed per net about where their terminals are in order to quickly (incrementally) update + * their wirelength costs. These data structures are (layer_)ts_bb_edge_new, (layer_)ts_bb_coord_new, ts_layer_sink_pin_count, + * and ts_nets_to_update. * @param num_nets Number of nets in the netlist used by the placement engine (currently clustered netlist) * @param cube_bb True if the 3D bounding box should be used, false otherwise. * @param place_cost_exp It is an exponent to which you take the average inverse channel @@ -423,7 +430,20 @@ class NetCostHandler { std::vector& bb_edge_new, std::vector& bb_coord_new); + /** + * @brief Computes the bounding box from scratch using 2D bounding boxes (per-layer mode) + * @param method The method used to calculate placement cost. Specifies whether the cost is + * computed from scratch or incrementally. + * @return Computed bounding box cost. + */ double comp_per_layer_bb_cost_(e_cost_methods method); + + /** + * @brief Computes the bounding box from scratch using 3D bounding boxes (cube mode) + * @param method The method used to calculate placement cost. Specifies whether the cost is + * computed from scratch or incrementally. + * @return Computed bounding box cost. + */ double comp_cube_bb_cost_(e_cost_methods method); /** From ef8007fe3a199041033a8c5d783291837cc6e842 Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 18:44:53 -0400 Subject: [PATCH 34/36] add get_net_bb_cost_functor_ and get_non_updatable_bb_functor_ --- vpr/src/place/net_cost_handler.cpp | 80 ++++++++++++------------------ vpr/src/place/net_cost_handler.h | 67 ++++++++++++------------- 2 files changed, 65 insertions(+), 82 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index b1f860542ae..da99a8dc981 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -129,12 +129,16 @@ NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts, 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); + get_net_bb_cost_functor_ = std::bind(&NetCostHandler::get_net_cube_bb_cost_, this, std::placeholders::_1, /*use_ts=*/true); + get_non_updatable_bb_functor_ = std::bind(&NetCostHandler::get_non_updatable_cube_bb_, this, std::placeholders::_1, /*use_ts=*/true); } 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())); 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); + get_net_bb_cost_functor_ = std::bind(&NetCostHandler::get_net_per_layer_bb_cost_, this, std::placeholders::_1, /*use_ts=*/true); + get_non_updatable_bb_functor_ = std::bind(&NetCostHandler::get_non_updatable_per_layer_bb_, this, std::placeholders::_1, /*use_ts=*/true); } /* This initializes the whole matrix to OPEN which is an invalid value*/ @@ -262,12 +266,10 @@ double NetCostHandler::comp_cube_bb_cost_(e_cost_methods method) { place_move_ctx.bb_num_on_edges[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } else { - get_non_updatable_cube_bb_(net_id, - place_move_ctx.bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + get_non_updatable_cube_bb_(net_id, /*use_ts=*/false); } - net_cost_[net_id] = get_net_cube_bb_cost_(net_id, place_move_ctx.bb_coords[net_id]); + net_cost_[net_id] = get_net_cube_bb_cost_(net_id, /*use_ts=*/false); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) { expected_wirelength += get_net_wirelength_estimate(net_id, place_move_ctx.bb_coords[net_id]); @@ -301,14 +303,10 @@ double NetCostHandler::comp_per_layer_bb_cost_(e_cost_methods method) { place_move_ctx.layer_bb_coords[net_id], place_move_ctx.num_sink_pin_layer[size_t(net_id)]); } else { - get_non_updatable_per_layer_bb_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + get_non_updatable_per_layer_bb_(net_id, /*use_ts=*/false); } - net_cost_[net_id] = get_net_per_layer_bb_cost_(net_id, - place_move_ctx.layer_bb_coords[net_id], - place_move_ctx.num_sink_pin_layer[size_t(net_id)]); + net_cost_[net_id] = get_net_per_layer_bb_cost_(net_id, /*use_ts=*/false); cost += net_cost_[net_id]; if (method == e_cost_methods::CHECK) { expected_wirelength += get_net_wirelength_from_layer_bb_(net_id); @@ -336,7 +334,7 @@ void NetCostHandler::update_net_bb_(const ClusterNetId net, //For small nets brute-force bounding box update is faster if (bb_update_status_[net] == NetUpdateState::NOT_UPDATED_YET) { //Only once per-net - get_non_updatable_bb_(net); + get_non_updatable_bb_functor_(net); } } else { //For large nets, update bounding box incrementally @@ -500,13 +498,15 @@ void NetCostHandler::update_net_info_on_pin_move_(const PlaceDelayModel* delay_m } } -void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer) { +void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, bool use_ts) { //TODO: account for multiple physical pin instances per logical pin - auto& cluster_ctx = g_vpr_ctx.clustering(); - auto& device_ctx = g_vpr_ctx.device(); - auto& block_locs = placer_state_.block_locs(); + const auto& cluster_ctx = g_vpr_ctx.clustering(); + const auto& device_ctx = g_vpr_ctx.device(); + const auto& block_locs = placer_state_.block_locs(); + auto& move_ctx = placer_state_.mutable_move(); + + t_bb& bb_coord_new = use_ts ? ts_bb_coord_new_[net_id] : move_ctx.bb_coords[net_id]; + 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)]; ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); int pnum = placer_state_.blk_loc_registry().net_pin_to_tile_pin_index(net_id, 0); @@ -572,13 +572,15 @@ void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, bb_coord_new.layer_max = max(min(layer_max, device_ctx.grid.get_num_layers() - 1), 0); } -void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer) { +void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool use_ts) { //TODO: account for multiple physical pin instances per logical pin auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); auto& block_locs = placer_state_.block_locs(); + 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)]; const int num_layers = device_ctx.grid.get_num_layers(); VTR_ASSERT_DEBUG(bb_coord_new.size() == num_layers); @@ -1456,10 +1458,12 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, } } -double NetCostHandler::get_net_cube_bb_cost_(ClusterNetId net_id, const t_bb& bb) { +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]; + double crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size()); /* Could insert a check for xmin == xmax. In that case, assume * @@ -1476,14 +1480,17 @@ double NetCostHandler::get_net_cube_bb_cost_(ClusterNetId net_id, const t_bb& bb return ncost; } -double NetCostHandler::get_net_per_layer_bb_cost_(ClusterNetId /* net_id */, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count) { - // Finds the cost due to one net by looking at its coordinate bounding box. +double NetCostHandler::get_net_per_layer_bb_cost_(ClusterNetId net_id , bool use_ts) { + const auto& move_ctx = placer_state_.move(); + 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)]; + // Finds the cost due to one net by looking at its coordinate bounding box double ncost = 0.; int num_layers = g_vpr_ctx.device().grid.get_num_layers(); + + for (int layer_num = 0; layer_num < num_layers; layer_num++) { VTR_ASSERT(layer_pin_sink_count[layer_num] != OPEN); if (layer_pin_sink_count[layer_num] == 0) { @@ -1592,7 +1599,7 @@ void NetCostHandler::set_bb_delta_cost_(double& bb_delta_c) { for (const ClusterNetId ts_net: ts_nets_to_update_) { ClusterNetId net_id = ts_net; - proposed_net_cost_[net_id] = get_net_bb_cost_(net_id); + proposed_net_cost_[net_id] = get_net_bb_cost_functor_(net_id); bb_delta_c += proposed_net_cost_[net_id] - net_cost_[net_id]; } @@ -1734,27 +1741,6 @@ void NetCostHandler::recompute_costs_from_scratch(const t_noc_opts& noc_opts, } } -void NetCostHandler::get_non_updatable_bb_(const ClusterNetId net) { - if (cube_bb_) { - get_non_updatable_cube_bb_(net, - ts_bb_coord_new_[net], - ts_layer_sink_pin_count_[size_t(net)]); - } - else { - get_non_updatable_per_layer_bb_(net, - layer_ts_bb_coord_new_[net], - ts_layer_sink_pin_count_[size_t(net)]); - } -} - -double NetCostHandler::get_net_bb_cost_(const ClusterNetId net_id) { - if (cube_bb_) { - return get_net_cube_bb_cost_(net_id, ts_bb_coord_new_[net_id]); - } else { - return get_net_per_layer_bb_cost_(net_id, layer_ts_bb_coord_new_[net_id], ts_layer_sink_pin_count_[size_t(net_id)]); - } -} - void NetCostHandler::set_ts_bb_coord_(const ClusterNetId net_id) { auto& place_move_ctx = placer_state_.mutable_move(); if (cube_bb_) { diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index b692e36b3bf..905a98ce99c 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -138,6 +138,10 @@ class NetCostHandler { ///@brief Points to the proper method for updating the bounding box of a net. std::function update_bb_functor_; + std::function get_net_bb_cost_functor_; + + std::function get_non_updatable_bb_functor_; + /** * @brief for the states of the bounding box. */ @@ -264,9 +268,7 @@ class NetCostHandler { double& delta_timing_cost, bool is_src_moving); - void get_non_updatable_bb_(const ClusterNetId net); - double get_net_bb_cost_(const ClusterNetId net_id); void set_ts_bb_coord_(const ClusterNetId net_id); @@ -279,9 +281,7 @@ class NetCostHandler { * @param bb_coord_new Computed by this function and returned by reference. * @param num_sink_pin_layer Store the number of sink pins of "net_id" on each layer */ - void get_non_updatable_cube_bb_(ClusterNetId net_id, - t_bb& bb_coord_new, - vtr::NdMatrixProxy num_sink_pin_layer); + void get_non_updatable_cube_bb_(ClusterNetId net_id, bool use_ts); /** * @brief Calculate the per-layer bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and @@ -290,9 +290,7 @@ class NetCostHandler { * @param bb_coord_new Computed by this function and returned by reference. * @param num_sink_layer Store the number of sink pins of "net_id" on each layer */ - void get_non_updatable_per_layer_bb_(ClusterNetId net_id, - std::vector& bb_coord_new, - vtr::NdMatrixProxy num_sink_layer); + void get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool use_sink); /** * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. @@ -447,43 +445,42 @@ class NetCostHandler { double comp_cube_bb_cost_(e_cost_methods method); /** - * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. - * @param net ID of a net affected by a move - */ + * @brief if "net" is not already stored as an affected net, add it in ts_nets_to_update. + * @param net ID of a net affected by a move + */ void record_affected_net_(const ClusterNetId net); /** - * @brief To mitigate round-off errors, every once in a while, the costs of nets are summed up from scratch. - * This functions is called to do that for bb cost. It doesn't calculate the BBs from scratch, it would only add the costs again. - * @return Total bb (wirelength) cost for the placement - */ + * @brief To mitigate round-off errors, every once in a while, the costs of nets are summed up from scratch. + * This functions is called to do that for bb cost. It doesn't calculate the BBs from scratch, it would only add the costs again. + * @return Total bb (wirelength) cost for the placement + */ double recompute_bb_cost_(); /** - * @brief Given the 3D BB, calculate the wire-length cost of the net - * @param net_id ID of the net which cost is requested - * @param bb Bounding box of the net - * @return Wirelength cost of the net - */ - double get_net_cube_bb_cost_(ClusterNetId net_id, const t_bb& bb); + * @brief Given the 3D BB, calculate the wire-length cost of the net + * @param net_id ID of the net which cost is requested. + * @param use_ts Specifies if the bounding box is retrieved from ts data structures + * or move context. + * @return Wirelength cost of the net + */ + double get_net_cube_bb_cost_(ClusterNetId net_id, bool use_ts); /** - * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer - * and return the sum of the costs - * @param net_id ID of the net which cost is requested. Currently unused - * @param bb Per-layer bounding box of the net - * @return Wirelength cost of the net - */ - double get_net_per_layer_bb_cost_(ClusterNetId net_id, - const std::vector& bb, - const vtr::NdMatrixProxy layer_pin_sink_count); + * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer + * and return the sum of the costs + * @param net_id ID of the net which cost is requested. Currently unused + * @param bb Per-layer bounding box of the net + * @return Wirelength cost of the net + */ + double get_net_per_layer_bb_cost_(ClusterNetId net_id, bool use_ts); /** - * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer - * and return the sum of the lengths - * @param net_id ID of the net which wirelength estimate is requested - * @return Wirelength estimate of the net - */ + * @brief Given the per-layer BB, calculate the wire-length estimate of the net on each layer + * and return the sum of the lengths + * @param net_id ID of the net which wirelength estimate is requested + * @return Wirelength estimate of the net + */ double get_net_wirelength_from_layer_bb_(ClusterNetId net_id); }; From 8bf5d2dacccfb2b48b0af07ed7a6caa352cfeedc Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 18:55:38 -0400 Subject: [PATCH 35/36] add comments and address compilation warnings --- vpr/src/place/net_cost_handler.cpp | 6 +++--- vpr/src/place/net_cost_handler.h | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index da99a8dc981..ad7504bfc5f 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -583,7 +583,7 @@ void NetCostHandler::get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool u 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)]; const int num_layers = device_ctx.grid.get_num_layers(); - VTR_ASSERT_DEBUG(bb_coord_new.size() == num_layers); + VTR_ASSERT_DEBUG(bb_coord_new.size() == (size_t)num_layers); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; @@ -1388,8 +1388,8 @@ void NetCostHandler::get_layer_bb_from_scratch_(ClusterNetId net_id, auto& block_locs = placer_state_.block_locs(); const int num_layers = device_ctx.grid.get_num_layers(); - VTR_ASSERT_DEBUG(coords.size() == num_layers); - VTR_ASSERT_DEBUG(num_on_edges.size() == num_layers); + VTR_ASSERT_DEBUG(coords.size() == (size_t)num_layers); + VTR_ASSERT_DEBUG(num_on_edges.size() == (size_t)num_layers); ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); t_pl_loc block_loc = block_locs[bnum].loc; diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 905a98ce99c..2319dbb0235 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -137,9 +137,9 @@ class NetCostHandler { std::function comp_bb_cost_functor_; ///@brief Points to the proper method for updating the bounding box of a net. std::function update_bb_functor_; - + ///@brief Points to the proper method for getting the bounding box cost of a net std::function get_net_bb_cost_functor_; - + ///@brief Points to the proper method for getting the non-updatable bounding box of a net std::function get_non_updatable_bb_functor_; /** @@ -268,10 +268,18 @@ class NetCostHandler { double& delta_timing_cost, bool is_src_moving); - - + /** + * @brief Updates the bounding box coordinates of a net in the placer state + * with coordinates stored in the `ts` bounding box coordinates container. + * @param net_id ID of the net whose bounding box coordinates it to be updated. + */ void set_ts_bb_coord_(const ClusterNetId net_id); + /** + * @brief Updates the number of pins on each boundary of the bounding box for a net + * in the placer state with the number of pins stores in the 'ts' num_on_edges containers. + * @param net_id ID of the net whose number of pins on each BB edge is to be updated. + */ void set_ts_edge_(const ClusterNetId net_id); /** From 68e489f769d1ddbefadadb6eef276cfd51fbe07b Mon Sep 17 00:00:00 2001 From: soheilshahrouz Date: Mon, 16 Sep 2024 19:08:47 -0400 Subject: [PATCH 36/36] add comments for use_ts arguments --- vpr/src/place/net_cost_handler.cpp | 4 ++++ vpr/src/place/net_cost_handler.h | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/vpr/src/place/net_cost_handler.cpp b/vpr/src/place/net_cost_handler.cpp index ad7504bfc5f..5abd9cb4f86 100644 --- a/vpr/src/place/net_cost_handler.cpp +++ b/vpr/src/place/net_cost_handler.cpp @@ -505,7 +505,9 @@ void NetCostHandler::get_non_updatable_cube_bb_(ClusterNetId net_id, bool use_ts const auto& block_locs = placer_state_.block_locs(); 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]; + // 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)]; ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id); @@ -1482,6 +1484,8 @@ 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)]; diff --git a/vpr/src/place/net_cost_handler.h b/vpr/src/place/net_cost_handler.h index 2319dbb0235..3b35bf68ea3 100644 --- a/vpr/src/place/net_cost_handler.h +++ b/vpr/src/place/net_cost_handler.h @@ -283,11 +283,11 @@ class NetCostHandler { void set_ts_edge_(const ClusterNetId net_id); /** - * @brief Calculate the 3D bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and - * store them in bb_coord_new + * @brief Calculate the 3D bounding box of "net_id" from scratch (based on the block locations + * stored in placer_state_.blk_loc_registry) and store them in bb_coord_new * @param net_id ID of the net for which the bounding box is requested - * @param bb_coord_new Computed by this function and returned by reference. - * @param num_sink_pin_layer Store the number of sink pins of "net_id" on each layer + * @param use_ts Specifies whether the `ts` bounding box is updated or + * the one stored in placer_state_ */ void get_non_updatable_cube_bb_(ClusterNetId net_id, bool use_ts); @@ -295,10 +295,10 @@ class NetCostHandler { * @brief Calculate the per-layer bounding box of "net_id" from scratch (based on the block locations stored in place_ctx) and * store them in bb_coord_new * @param net_id ID of the net for which the bounding box is requested - * @param bb_coord_new Computed by this function and returned by reference. - * @param num_sink_layer Store the number of sink pins of "net_id" on each layer + * @param use_ts Specifies whether the `ts` bounding box is updated or + * the one stored in placer_state_ */ - void get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool use_sink); + void get_non_updatable_per_layer_bb_(ClusterNetId net_id, bool use_ts); /** * @brief Calculate the 3D BB of a large net from scratch and update coord, edge, and num_sink_pin_layer data structures. @@ -478,7 +478,8 @@ class NetCostHandler { * @brief Given the per-layer BB, calculate the wire-length cost of the net on each layer * and return the sum of the costs * @param net_id ID of the net which cost is requested. Currently unused - * @param bb Per-layer bounding box of the net + * @param use_ts Specifies whether the 'ts` bounding box is used to compute the + * cost or the one stored in placer_state_ * @return Wirelength cost of the net */ double get_net_per_layer_bb_cost_(ClusterNetId net_id, bool use_ts);