From 11920a1e667101626de4ac709e1fea0b637eefb8 Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Mon, 3 Mar 2025 17:55:37 -0500 Subject: [PATCH 1/6] [AP][FullLegalizer] Basic Min. Disturbance FL Added read flat placement to AP flow and and command line option for Basic Min. Disturbance FL. --- .../analytical_placement_flow.cpp | 46 +++++++++++++++---- .../analytical_placement_flow.h | 13 ++++++ vpr/src/analytical_place/ap_flow_enums.h | 3 +- vpr/src/analytical_place/full_legalizer.cpp | 5 ++ vpr/src/base/ShowSetup.cpp | 3 ++ vpr/src/base/read_options.cpp | 9 +++- vpr/src/base/vpr_api.cpp | 17 +++++++ 7 files changed, 84 insertions(+), 12 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index d71b7bb8937..c75528a6c4a 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -58,6 +58,24 @@ static void print_ap_netlist_stats(const APNetlist& netlist) { VTR_LOG("\n"); } +void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, PartialPlacement& p_placement){ + for (APBlockId ap_blk_id : ap_netlist.blocks()) { + std::string ap_block_name = ap_netlist.block_name(ap_blk_id); + + // Find the AtomBlockId of a given AP block name + AtomBlockId atom_blk = g_vpr_ctx.atom().netlist().find_block(ap_block_name); + if (!atom_blk.is_valid()) { + continue; + } + + // Pass the placement information + p_placement.block_x_locs[ap_blk_id] = flat_placement_info.blk_x_pos[atom_blk]; + p_placement.block_y_locs[ap_blk_id] = flat_placement_info.blk_y_pos[atom_blk]; + p_placement.block_layer_nums[ap_blk_id] = flat_placement_info.blk_layer[atom_blk]; + p_placement.block_sub_tiles[ap_blk_id] = flat_placement_info.blk_sub_tile[atom_blk]; + } +} + void run_analytical_placement_flow(t_vpr_setup& vpr_setup) { // Start an overall timer for the Analytical Placement flow. vtr::ScopedStartFinishTimer timer("Analytical Placement"); @@ -77,15 +95,25 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) { constraints); print_ap_netlist_stats(ap_netlist); - // Run the Global Placer - std::unique_ptr global_placer = make_global_placer(e_global_placer::SimPL, - ap_netlist, - prepacker, - atom_nlist, - device_ctx.grid, - device_ctx.logical_block_types, - device_ctx.physical_tile_types); - PartialPlacement p_placement = global_placer->place(); + // If a flat placement is provided, skip the Global Placer and conver it + // to a partial placement. Otherwise, run the Global Placer. + PartialPlacement p_placement(ap_netlist); + if (g_vpr_ctx.atom().flat_placement_info().valid) { + VTR_LOG("Flat Placement is provided in the AP flow, skipping the Global Placement.\n"); + convert_flat_to_partial_placement(g_vpr_ctx.atom().flat_placement_info(), + ap_netlist, + p_placement); + } else { + // Run the Global Placer + std::unique_ptr global_placer = make_global_placer(e_global_placer::SimPL, + ap_netlist, + prepacker, + atom_nlist, + device_ctx.grid, + device_ctx.logical_block_types, + device_ctx.physical_tile_types); + p_placement = global_placer->place(); + } // Verify that the partial placement is valid before running the full // legalizer. diff --git a/vpr/src/analytical_place/analytical_placement_flow.h b/vpr/src/analytical_place/analytical_placement_flow.h index 638456177f1..15a9207ef8c 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.h +++ b/vpr/src/analytical_place/analytical_placement_flow.h @@ -9,6 +9,19 @@ // Forward declarations struct t_vpr_setup; +struct PartialPlacement; +class FlatPlacementInfo; +class APNetlist; + +/** + * @brief Passes the flat placement information to a provided partial placement. + * + * @param flat_placement_info The flat placement information to be read. + * @param ap_netlist The APNetlist that used to iterate over its blocks. + * @param p_placement The partial placement to be updated which is assumend + * to be generated on ap_netlist or have same blocks. + */ +void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, PartialPlacement& p_placement); /** * @brief Run the Analaytical Placement flow. diff --git a/vpr/src/analytical_place/ap_flow_enums.h b/vpr/src/analytical_place/ap_flow_enums.h index 5139d13c18d..afae47ef25f 100644 --- a/vpr/src/analytical_place/ap_flow_enums.h +++ b/vpr/src/analytical_place/ap_flow_enums.h @@ -15,6 +15,7 @@ */ enum class e_ap_full_legalizer { Naive, ///< The Naive Full Legalizer, which clusters atoms placed in the same tile and tries to place them in that tile according to the flat placement. - APPack ///< The APPack Full Legalizer, which uses the flat placement to improve the Packer and Placer. + APPack, ///< The APPack Full Legalizer, which uses the flat placement to improve the Packer and Placer. + Basic_Min_Disturbance ///< The Basic Min. Disturbance Full Legalizer, which uses flat placement and tries to reconstruct clusters identically. The method for handling orphan clusters has not yet been determined. }; diff --git a/vpr/src/analytical_place/full_legalizer.cpp b/vpr/src/analytical_place/full_legalizer.cpp index 0c7e4112638..d52bbfe3ee6 100644 --- a/vpr/src/analytical_place/full_legalizer.cpp +++ b/vpr/src/analytical_place/full_legalizer.cpp @@ -70,6 +70,11 @@ std::unique_ptr make_full_legalizer(e_ap_full_legalizer full_lega vpr_setup, arch, device_grid); + case e_ap_full_legalizer::Basic_Min_Disturbance: + VTR_LOG("Basic Minimum Disturbance Full Legalizer selected!\n"); + VPR_FATAL_ERROR(VPR_ERROR_AP, + "Basic Min. Disturbance Full Legalizer has not been implemented yet."); + default: VPR_FATAL_ERROR(VPR_ERROR_AP, "Unrecognized full legalizer type"); diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index 9b8af556c8d..c573af42a04 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -603,6 +603,9 @@ static void ShowAnalyticalPlacerOpts(const t_ap_opts& APOpts) { case e_ap_full_legalizer::APPack: VTR_LOG("appack\n"); break; + case e_ap_full_legalizer::Basic_Min_Disturbance: + VTR_LOG("basic_min_disturbance\n"); + break; default: VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown full_legalizer_type\n"); } diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 5803f05f896..240a925af1c 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -141,6 +141,8 @@ struct ParseAPFullLegalizer { conv_value.set_value(e_ap_full_legalizer::Naive); else if (str == "appack") conv_value.set_value(e_ap_full_legalizer::APPack); + else if (str == "basic_min_disturbance") + conv_value.set_value(e_ap_full_legalizer::Basic_Min_Disturbance); else { std::stringstream msg; msg << "Invalid conversion from '" << str << "' to e_ap_full_legalizer (expected one of: " << argparse::join(default_choices(), ", ") << ")"; @@ -158,6 +160,8 @@ struct ParseAPFullLegalizer { case e_ap_full_legalizer::APPack: conv_value.set_value("appack"); break; + case e_ap_full_legalizer::Basic_Min_Disturbance: + conv_value.set_value("basic_min_disturbance"); default: VTR_ASSERT(false); } @@ -165,7 +169,7 @@ struct ParseAPFullLegalizer { } std::vector default_choices() { - return {"naive", "appack"}; + return {"naive", "appack", "basic_min_disturbance"}; } }; @@ -1787,7 +1791,8 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .help( "Controls which Full Legalizer to use in the AP Flow.\n" " * naive: Use a Naive Full Legalizer which will try to create clusters exactly where their atoms are placed.\n" - " * appack: Use APPack, which takes the Packer in VPR and uses the flat atom placement to create better clusters.") + " * appack: Use APPack, which takes the Packer in VPR and uses the flat atom placement to create better clusters.\n" + " * basic_min_disturbance: Use The Basic Min. Disturbance Full Legalizer which uses flat placement to reconstruct clusters identically, but the orphan cluster handling method is yet to be determined.") .default_value("appack") .show_in(argparse::ShowIn::HELP_ONLY); diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index 2265f26b4ef..b39a8072f3a 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -404,8 +404,25 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) { { // Analytical Place if (vpr_setup.APOpts.doAP == STAGE_DO) { + // Passing flat placement input if provided and not loaded yet. + if (!vpr_setup.FileNameOpts.read_flat_place_file.empty() && + !g_vpr_ctx.atom().flat_placement_info().valid) { + g_vpr_ctx.mutable_atom().mutable_flat_placement_info() = read_flat_placement( + vpr_setup.FileNameOpts.read_flat_place_file, + g_vpr_ctx.atom().netlist()); + } + // TODO: Make this return a bool if the placement was successful or not. run_analytical_placement_flow(vpr_setup); + + // Write out a flat placement file at the end of Analytical Placement + // flow if the option is specified. + if (!vpr_setup.FileNameOpts.write_flat_place_file.empty()) { + write_flat_placement(vpr_setup.FileNameOpts.write_flat_place_file.c_str(), + g_vpr_ctx.clustering().clb_nlist, + g_vpr_ctx.placement().block_locs(), + g_vpr_ctx.clustering().atoms_lookup); + } } // Print the placement generated by AP to a .place file. auto& filename_opts = vpr_setup.FileNameOpts; From b4f34531ceb0ee02c3f92b4c623df23ed8820a75 Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Fri, 7 Mar 2025 09:25:59 -0500 Subject: [PATCH 2/6] [AP][FullLegalizer] Basic Min. Disturbance FL Changes based on review. --- .../analytical_placement_flow.cpp | 99 +++++++++++++------ .../analytical_placement_flow.h | 13 --- vpr/src/analytical_place/ap_flow_enums.h | 2 +- vpr/src/base/read_options.cpp | 2 +- 4 files changed, 70 insertions(+), 46 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index c75528a6c4a..57a98c65177 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -58,21 +58,72 @@ static void print_ap_netlist_stats(const APNetlist& netlist) { VTR_LOG("\n"); } -void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, PartialPlacement& p_placement){ +/** + * @brief Passes the flat placement information to a provided partial placement. + * + * @param flat_placement_info The flat placement information to be read. + * @param ap_netlist The APNetlist that used to iterate over its blocks. + * @param prepacker The Prepacker to get molecule of blocks in the ap_netlist. + * @param p_placement The partial placement to be updated which is assumend + * to be generated on ap_netlist or have same blocks. + */ +static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, const Prepacker& prepacker, PartialPlacement& p_placement){ for (APBlockId ap_blk_id : ap_netlist.blocks()) { - std::string ap_block_name = ap_netlist.block_name(ap_blk_id); - - // Find the AtomBlockId of a given AP block name - AtomBlockId atom_blk = g_vpr_ctx.atom().netlist().find_block(ap_block_name); - if (!atom_blk.is_valid()) { - continue; + // Get the molecule that AP block represents + PackMoleculeId mol_id = ap_netlist.block_molecule(ap_blk_id); + const t_pack_molecule& mol = prepacker.get_molecule(mol_id); + // Get location of a valid atom in the molecule and verify that + // all atoms of the molecule share same placement information. + t_pl_loc atom_loc; + bool found_valid_atom = false; + for (AtomBlockId atom_blk_id: mol.atom_block_ids) { + if (!atom_blk_id.is_valid()) + continue; + const t_pl_loc current_loc(flat_placement_info.blk_x_pos[atom_blk_id], + flat_placement_info.blk_y_pos[atom_blk_id], + flat_placement_info.blk_sub_tile[atom_blk_id], + flat_placement_info.blk_layer[atom_blk_id]); + if (found_valid_atom) { + VTR_ASSERT_MSG(current_loc == atom_loc, "Verify all atoms of a molecule provided in the flat placement share same location.\n"); + } else { + atom_loc = current_loc; + found_valid_atom = true; + } } - + // Skip if no valid atom found + if (!found_valid_atom) + continue; // Pass the placement information - p_placement.block_x_locs[ap_blk_id] = flat_placement_info.blk_x_pos[atom_blk]; - p_placement.block_y_locs[ap_blk_id] = flat_placement_info.blk_y_pos[atom_blk]; - p_placement.block_layer_nums[ap_blk_id] = flat_placement_info.blk_layer[atom_blk]; - p_placement.block_sub_tiles[ap_blk_id] = flat_placement_info.blk_sub_tile[atom_blk]; + p_placement.block_x_locs[ap_blk_id] = atom_loc.x; + p_placement.block_y_locs[ap_blk_id] = atom_loc.y; + p_placement.block_layer_nums[ap_blk_id] = atom_loc.layer; + p_placement.block_sub_tiles[ap_blk_id] = atom_loc.sub_tile; + } +} + +/** + * @brief If a flat placement is provided, skips the Global Placer and + * converts it to a partial placement. Otherwise, runs the Global Placer. + */ +static PartialPlacement run_global_placer(const AtomNetlist& atom_nlist, const APNetlist& ap_netlist, const Prepacker& prepacker, const DeviceContext& device_ctx) { + if (g_vpr_ctx.atom().flat_placement_info().valid) { + VTR_LOG("Flat Placement is provided in the AP flow, skipping the Global Placement.\n"); + PartialPlacement p_placement(ap_netlist); + convert_flat_to_partial_placement(g_vpr_ctx.atom().flat_placement_info(), + ap_netlist, + prepacker, + p_placement); + return p_placement; + } else { + // Run the Global Placer + std::unique_ptr global_placer = make_global_placer(e_global_placer::SimPL, + ap_netlist, + prepacker, + atom_nlist, + device_ctx.grid, + device_ctx.logical_block_types, + device_ctx.physical_tile_types); + return global_placer->place(); } } @@ -95,25 +146,11 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) { constraints); print_ap_netlist_stats(ap_netlist); - // If a flat placement is provided, skip the Global Placer and conver it - // to a partial placement. Otherwise, run the Global Placer. - PartialPlacement p_placement(ap_netlist); - if (g_vpr_ctx.atom().flat_placement_info().valid) { - VTR_LOG("Flat Placement is provided in the AP flow, skipping the Global Placement.\n"); - convert_flat_to_partial_placement(g_vpr_ctx.atom().flat_placement_info(), - ap_netlist, - p_placement); - } else { - // Run the Global Placer - std::unique_ptr global_placer = make_global_placer(e_global_placer::SimPL, - ap_netlist, - prepacker, - atom_nlist, - device_ctx.grid, - device_ctx.logical_block_types, - device_ctx.physical_tile_types); - p_placement = global_placer->place(); - } + // Run the Global Placer. + PartialPlacement p_placement = run_global_placer(atom_nlist, + ap_netlist, + prepacker, + device_ctx); // Verify that the partial placement is valid before running the full // legalizer. diff --git a/vpr/src/analytical_place/analytical_placement_flow.h b/vpr/src/analytical_place/analytical_placement_flow.h index 15a9207ef8c..638456177f1 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.h +++ b/vpr/src/analytical_place/analytical_placement_flow.h @@ -9,19 +9,6 @@ // Forward declarations struct t_vpr_setup; -struct PartialPlacement; -class FlatPlacementInfo; -class APNetlist; - -/** - * @brief Passes the flat placement information to a provided partial placement. - * - * @param flat_placement_info The flat placement information to be read. - * @param ap_netlist The APNetlist that used to iterate over its blocks. - * @param p_placement The partial placement to be updated which is assumend - * to be generated on ap_netlist or have same blocks. - */ -void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, PartialPlacement& p_placement); /** * @brief Run the Analaytical Placement flow. diff --git a/vpr/src/analytical_place/ap_flow_enums.h b/vpr/src/analytical_place/ap_flow_enums.h index afae47ef25f..c7c609b95fa 100644 --- a/vpr/src/analytical_place/ap_flow_enums.h +++ b/vpr/src/analytical_place/ap_flow_enums.h @@ -16,6 +16,6 @@ enum class e_ap_full_legalizer { Naive, ///< The Naive Full Legalizer, which clusters atoms placed in the same tile and tries to place them in that tile according to the flat placement. APPack, ///< The APPack Full Legalizer, which uses the flat placement to improve the Packer and Placer. - Basic_Min_Disturbance ///< The Basic Min. Disturbance Full Legalizer, which uses flat placement and tries to reconstruct clusters identically. The method for handling orphan clusters has not yet been determined. + Basic_Min_Disturbance ///< The Basic Min. Disturbance Full Legalizer, which tries to reconstruct a clustered placement as close to the incoming flat placement as it can. }; diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 240a925af1c..a4f79233f22 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1792,7 +1792,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio "Controls which Full Legalizer to use in the AP Flow.\n" " * naive: Use a Naive Full Legalizer which will try to create clusters exactly where their atoms are placed.\n" " * appack: Use APPack, which takes the Packer in VPR and uses the flat atom placement to create better clusters.\n" - " * basic_min_disturbance: Use The Basic Min. Disturbance Full Legalizer which uses flat placement to reconstruct clusters identically, but the orphan cluster handling method is yet to be determined.") + " * basic-min-disturbance: Use the Basic Min. Disturbance Full Legalizer which tries to reconstruct a clustered placement as close to the incoming flat placement as it can.\n") .default_value("appack") .show_in(argparse::ShowIn::HELP_ONLY); From 47818090f868ae2fba250d1a5ee9d4f7f4ceb1a8 Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Fri, 7 Mar 2025 09:30:37 -0500 Subject: [PATCH 3/6] [AP][FullLegalizer] Basic Min. Disturbance FL Style change. --- .../analytical_place/analytical_placement_flow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index 57a98c65177..ea90e6ea6ed 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -117,12 +117,12 @@ static PartialPlacement run_global_placer(const AtomNetlist& atom_nlist, const A } else { // Run the Global Placer std::unique_ptr global_placer = make_global_placer(e_global_placer::SimPL, - ap_netlist, - prepacker, - atom_nlist, - device_ctx.grid, - device_ctx.logical_block_types, - device_ctx.physical_tile_types); + ap_netlist, + prepacker, + atom_nlist, + device_ctx.grid, + device_ctx.logical_block_types, + device_ctx.physical_tile_types); return global_placer->place(); } } From 1171a70b4811e308ffeea5f297b1ad862954f3b2 Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Fri, 7 Mar 2025 18:09:33 -0500 Subject: [PATCH 4/6] [AP][FullLegalizer] Basic Min. Disturbance FL Changes based on review (VtrError and commenting) --- vpr/src/analytical_place/analytical_placement_flow.cpp | 10 ++++++++-- vpr/src/analytical_place/ap_flow_enums.h | 2 +- vpr/src/base/read_options.cpp | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index ea90e6ea6ed..33fd4c8473b 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -65,7 +65,7 @@ static void print_ap_netlist_stats(const APNetlist& netlist) { * @param ap_netlist The APNetlist that used to iterate over its blocks. * @param prepacker The Prepacker to get molecule of blocks in the ap_netlist. * @param p_placement The partial placement to be updated which is assumend - * to be generated on ap_netlist or have same blocks. + * to be generated on ap_netlist or have the same blocks. */ static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_placement_info, const APNetlist& ap_netlist, const Prepacker& prepacker, PartialPlacement& p_placement){ for (APBlockId ap_blk_id : ap_netlist.blocks()) { @@ -84,7 +84,13 @@ static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_plac flat_placement_info.blk_sub_tile[atom_blk_id], flat_placement_info.blk_layer[atom_blk_id]); if (found_valid_atom) { - VTR_ASSERT_MSG(current_loc == atom_loc, "Verify all atoms of a molecule provided in the flat placement share same location.\n"); + if (current_loc != atom_loc) + throw vtr::VtrError(vtr::string_fmt( + "Molecule of ID %d contains atom %s (ID: %d) with a location (%d, %d, layer: %d, subtile: %d) " + "that conflicts the location of other atoms in this molecule of (%d, %d, layer: %d, subtile: %d).", + (int)mol_id, g_vpr_ctx.atom().netlist().block_name(atom_blk_id).c_str(), (int)atom_blk_id, + current_loc.x, current_loc.y, current_loc.layer, current_loc.sub_tile, + atom_loc.x, atom_loc.y, atom_loc.layer, atom_loc.sub_tile), __FILE__, __LINE__); } else { atom_loc = current_loc; found_valid_atom = true; diff --git a/vpr/src/analytical_place/ap_flow_enums.h b/vpr/src/analytical_place/ap_flow_enums.h index c7c609b95fa..140e028678b 100644 --- a/vpr/src/analytical_place/ap_flow_enums.h +++ b/vpr/src/analytical_place/ap_flow_enums.h @@ -16,6 +16,6 @@ enum class e_ap_full_legalizer { Naive, ///< The Naive Full Legalizer, which clusters atoms placed in the same tile and tries to place them in that tile according to the flat placement. APPack, ///< The APPack Full Legalizer, which uses the flat placement to improve the Packer and Placer. - Basic_Min_Disturbance ///< The Basic Min. Disturbance Full Legalizer, which tries to reconstruct a clustered placement as close to the incoming flat placement as it can. + Basic_Min_Disturbance ///< The Basic Min. Disturbance Full Legalizer, which tries to reconstruct a clustered placement that is as close to the incoming flat placement as it can. }; diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index a4f79233f22..0a3270854f1 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1792,7 +1792,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio "Controls which Full Legalizer to use in the AP Flow.\n" " * naive: Use a Naive Full Legalizer which will try to create clusters exactly where their atoms are placed.\n" " * appack: Use APPack, which takes the Packer in VPR and uses the flat atom placement to create better clusters.\n" - " * basic-min-disturbance: Use the Basic Min. Disturbance Full Legalizer which tries to reconstruct a clustered placement as close to the incoming flat placement as it can.\n") + " * basic-min-disturbance: Use the Basic Min. Disturbance Full Legalizer which tries to reconstruct a clustered placement that is as close to the incoming flat placement as possible.\n") .default_value("appack") .show_in(argparse::ShowIn::HELP_ONLY); From 0fa47c65d4e6856ef91a05e5a4c44b43df940b88 Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Mon, 10 Mar 2025 00:42:31 -0400 Subject: [PATCH 5/6] [AP][FullLegalizer] Basic Min. Disturbance FL Using floats for location in flat and partial palcement. Also error handling. --- .../analytical_placement_flow.cpp | 42 ++++++++++--------- vpr/src/base/ShowSetup.cpp | 2 +- vpr/src/base/read_options.cpp | 6 +-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index 33fd4c8473b..24d5abe626e 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -74,36 +74,38 @@ static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_plac const t_pack_molecule& mol = prepacker.get_molecule(mol_id); // Get location of a valid atom in the molecule and verify that // all atoms of the molecule share same placement information. - t_pl_loc atom_loc; + float atom_loc_x, atom_loc_y, atom_loc_layer; + int atom_loc_sub_tile; bool found_valid_atom = false; for (AtomBlockId atom_blk_id: mol.atom_block_ids) { if (!atom_blk_id.is_valid()) continue; - const t_pl_loc current_loc(flat_placement_info.blk_x_pos[atom_blk_id], - flat_placement_info.blk_y_pos[atom_blk_id], - flat_placement_info.blk_sub_tile[atom_blk_id], - flat_placement_info.blk_layer[atom_blk_id]); + float current_loc_x = flat_placement_info.blk_x_pos[atom_blk_id]; + float current_loc_y = flat_placement_info.blk_y_pos[atom_blk_id]; + float current_loc_layer = flat_placement_info.blk_layer[atom_blk_id]; + int current_loc_sub_tile = flat_placement_info.blk_sub_tile[atom_blk_id]; if (found_valid_atom) { - if (current_loc != atom_loc) - throw vtr::VtrError(vtr::string_fmt( - "Molecule of ID %d contains atom %s (ID: %d) with a location (%d, %d, layer: %d, subtile: %d) " - "that conflicts the location of other atoms in this molecule of (%d, %d, layer: %d, subtile: %d).", - (int)mol_id, g_vpr_ctx.atom().netlist().block_name(atom_blk_id).c_str(), (int)atom_blk_id, - current_loc.x, current_loc.y, current_loc.layer, current_loc.sub_tile, - atom_loc.x, atom_loc.y, atom_loc.layer, atom_loc.sub_tile), __FILE__, __LINE__); + if (current_loc_x != atom_loc_x || current_loc_y != atom_loc_y || current_loc_layer != atom_loc_layer || current_loc_sub_tile != atom_loc_sub_tile) + VPR_FATAL_ERROR(VPR_ERROR_AP, "Molecule of ID %zu contains atom %s (ID: %zu) with a location (%d, %d, layer: %d, subtile: %d) " + "that conflicts the location of other atoms in this molecule of (%d, %d, layer: %d, subtile: %d).", + mol_id, g_vpr_ctx.atom().netlist().block_name(atom_blk_id), atom_blk_id, + current_loc_x, current_loc_y, current_loc_layer, current_loc_sub_tile, + atom_loc_x, atom_loc_y, atom_loc_layer, atom_loc_sub_tile); } else { - atom_loc = current_loc; + atom_loc_x = current_loc_x; + atom_loc_y = current_loc_y; + atom_loc_layer = current_loc_layer; + atom_loc_sub_tile = current_loc_sub_tile; found_valid_atom = true; } } - // Skip if no valid atom found - if (!found_valid_atom) - continue; + // Ensure that there is a valid atom in the molecule to pass its location. + VTR_ASSERT_MSG(found_valid_atom, "Each molecule must contain at least one valid atom"); // Pass the placement information - p_placement.block_x_locs[ap_blk_id] = atom_loc.x; - p_placement.block_y_locs[ap_blk_id] = atom_loc.y; - p_placement.block_layer_nums[ap_blk_id] = atom_loc.layer; - p_placement.block_sub_tiles[ap_blk_id] = atom_loc.sub_tile; + p_placement.block_x_locs[ap_blk_id] = atom_loc_x; + p_placement.block_y_locs[ap_blk_id] = atom_loc_y; + p_placement.block_layer_nums[ap_blk_id] = atom_loc_layer; + p_placement.block_sub_tiles[ap_blk_id] = atom_loc_sub_tile; } } diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index c573af42a04..e9e9d30d45e 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -604,7 +604,7 @@ static void ShowAnalyticalPlacerOpts(const t_ap_opts& APOpts) { VTR_LOG("appack\n"); break; case e_ap_full_legalizer::Basic_Min_Disturbance: - VTR_LOG("basic_min_disturbance\n"); + VTR_LOG("basic-min-disturbance\n"); break; default: VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown full_legalizer_type\n"); diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index 0a3270854f1..ea59faae156 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -141,7 +141,7 @@ struct ParseAPFullLegalizer { conv_value.set_value(e_ap_full_legalizer::Naive); else if (str == "appack") conv_value.set_value(e_ap_full_legalizer::APPack); - else if (str == "basic_min_disturbance") + else if (str == "basic-min-disturbance") conv_value.set_value(e_ap_full_legalizer::Basic_Min_Disturbance); else { std::stringstream msg; @@ -161,7 +161,7 @@ struct ParseAPFullLegalizer { conv_value.set_value("appack"); break; case e_ap_full_legalizer::Basic_Min_Disturbance: - conv_value.set_value("basic_min_disturbance"); + conv_value.set_value("basic-min-disturbance"); default: VTR_ASSERT(false); } @@ -169,7 +169,7 @@ struct ParseAPFullLegalizer { } std::vector default_choices() { - return {"naive", "appack", "basic_min_disturbance"}; + return {"naive", "appack", "basic-min-disturbance"}; } }; From 8bd962597c0619c00a6b0bafaba43f92323fe8cc Mon Sep 17 00:00:00 2001 From: hadyar-c Date: Mon, 10 Mar 2025 01:18:41 -0400 Subject: [PATCH 6/6] [AP][FullLegalizer] Basic Min. Disturbance FL Using floats for location in flat and partial placement. Changed error handling. --- vpr/src/analytical_place/analytical_placement_flow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vpr/src/analytical_place/analytical_placement_flow.cpp b/vpr/src/analytical_place/analytical_placement_flow.cpp index 24d5abe626e..10d9134cf91 100644 --- a/vpr/src/analytical_place/analytical_placement_flow.cpp +++ b/vpr/src/analytical_place/analytical_placement_flow.cpp @@ -86,9 +86,9 @@ static void convert_flat_to_partial_placement(const FlatPlacementInfo& flat_plac int current_loc_sub_tile = flat_placement_info.blk_sub_tile[atom_blk_id]; if (found_valid_atom) { if (current_loc_x != atom_loc_x || current_loc_y != atom_loc_y || current_loc_layer != atom_loc_layer || current_loc_sub_tile != atom_loc_sub_tile) - VPR_FATAL_ERROR(VPR_ERROR_AP, "Molecule of ID %zu contains atom %s (ID: %zu) with a location (%d, %d, layer: %d, subtile: %d) " - "that conflicts the location of other atoms in this molecule of (%d, %d, layer: %d, subtile: %d).", - mol_id, g_vpr_ctx.atom().netlist().block_name(atom_blk_id), atom_blk_id, + VPR_FATAL_ERROR(VPR_ERROR_AP, "Molecule of ID %zu contains atom %s (ID: %zu) with a location (%g, %g, layer: %g, subtile: %d) " + "that conflicts the location of other atoms in this molecule of (%g, %g, layer: %g, subtile: %d).", + mol_id, g_vpr_ctx.atom().netlist().block_name(atom_blk_id).c_str(), atom_blk_id, current_loc_x, current_loc_y, current_loc_layer, current_loc_sub_tile, atom_loc_x, atom_loc_y, atom_loc_layer, atom_loc_sub_tile); } else {