From 9667ed098214d6c6ec9e7391abf50787aa44a887 Mon Sep 17 00:00:00 2001 From: AlexandreSinger Date: Mon, 20 Jan 2025 16:14:27 -0500 Subject: [PATCH 1/2] [APPack] Added Flat Placement Reconstruction Added logic to the packer to reconstruct clusters from the flat placement, if one is provided. The packer will fall-back on the original packing algorithm if it runs out of options for candidates to cluster. Added logic to the initial placer to reconstruct the placement of each cluster from the flat placement, if one is provided. It will try to place the cluster at the centroid location of all atoms in a cluster, if it cannot place the cluster there it will fall-back on the original initial placement algorithm. Added a simple testcase to ensure the reading and writing of the flat placement file is working. --- vpr/src/base/load_flat_place.cpp | 114 +++ vpr/src/base/load_flat_place.h | 27 + vpr/src/base/place_and_route.cpp | 3 + vpr/src/base/vpr_api.cpp | 21 +- vpr/src/base/vpr_context.h | 5 + vpr/src/pack/greedy_candidate_selector.cpp | 136 ++- vpr/src/pack/greedy_candidate_selector.h | 46 + vpr/src/pack/greedy_clusterer.cpp | 6 +- vpr/src/pack/greedy_clusterer.h | 9 +- vpr/src/pack/pack.cpp | 3 +- vpr/src/pack/verify_flat_placement.cpp | 3 + vpr/src/place/initial_placement.cpp | 95 +- vpr/src/place/initial_placement.h | 7 + vpr/src/place/place.cpp | 4 +- vpr/src/place/place.h | 4 + vpr/src/place/placer.cpp | 17 +- vpr/src/place/placer.h | 2 + .../config/golden_results.txt | 4 +- .../read_write/config/config.txt | 35 + .../read_write/config/golden_results.txt | 2 + .../constraints/old_placement.fplace | 934 ++++++++++++++++++ .../vtr_reg_strong/task_list.txt | 1 + .../strong_sdc/config/golden_results.txt | 14 +- 23 files changed, 1456 insertions(+), 36 deletions(-) create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/config.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/golden_results.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace diff --git a/vpr/src/base/load_flat_place.cpp b/vpr/src/base/load_flat_place.cpp index 04a141e3b42..2a990facf0c 100644 --- a/vpr/src/base/load_flat_place.cpp +++ b/vpr/src/base/load_flat_place.cpp @@ -10,6 +10,7 @@ #include #include +#include "atom_lookup.h" #include "atom_netlist.h" #include "clustered_netlist.h" #include "FlatPlacementInfo.h" @@ -17,7 +18,9 @@ #include "vpr_context.h" #include "vpr_error.h" #include "vpr_types.h" +#include "vtr_assert.h" #include "vtr_log.h" +#include "vtr_vector_map.h" /** * @brief Prints flat placement file entries for the atoms in one placed @@ -174,3 +177,114 @@ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) { return false; } +void log_flat_placement_reconstruction_info( + const FlatPlacementInfo& flat_placement_info, + const vtr::vector_map& block_locs, + const vtr::vector>& atoms_lookup, + const AtomLookup& lookup, + const AtomNetlist& atom_netlist, + const ClusteredNetlist& clustered_netlist) { + // Go through each cluster and see how many clusters have atoms that + // do not belong (cluster is imperfect). + unsigned num_imperfect_clusters = 0; + for (ClusterBlockId clb_blk_id : clustered_netlist.blocks()) { + // Get the centroid of the cluster + const auto& clb_atoms = atoms_lookup[clb_blk_id]; + float centroid_x = 0.f; + float centroid_y = 0.f; + float centroid_layer = 0.f; + float centroid_sub_tile = 0.f; + for (AtomBlockId atom_blk_id : clb_atoms) { + // TODO: Currently only handle the case when all of the position + // data is provided. This can be extended, + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); + + centroid_x += flat_placement_info.blk_x_pos[atom_blk_id]; + centroid_y += flat_placement_info.blk_y_pos[atom_blk_id]; + centroid_layer += flat_placement_info.blk_layer[atom_blk_id]; + centroid_sub_tile += flat_placement_info.blk_sub_tile[atom_blk_id]; + } + centroid_x /= static_cast(clb_atoms.size()); + centroid_y /= static_cast(clb_atoms.size()); + centroid_layer /= static_cast(clb_atoms.size()); + centroid_sub_tile /= static_cast(clb_atoms.size()); + // Check if every atom in the cluster is within 0.5 units of the + // centroid. + for (AtomBlockId atom_blk_id : clb_atoms) { + // If the atom's flat placement more than half a block in any + // direction from the flat placement centroid, then it does not + // want to be in this cluster. + if (std::abs(centroid_x - flat_placement_info.blk_x_pos[atom_blk_id]) > 0.5f || + std::abs(centroid_y - flat_placement_info.blk_y_pos[atom_blk_id]) > 0.5f || + std::abs(centroid_layer - flat_placement_info.blk_layer[atom_blk_id]) > 0.5f || + std::abs(centroid_sub_tile - flat_placement_info.blk_sub_tile[atom_blk_id]) > 0.5f) { + num_imperfect_clusters++; + break; + } + } + } + // Go through each atom and compute how much it has displaced and count + // how many have been displaced beyond some threshold. + constexpr float disp_threashold = 0.5f; + float total_disp = 0; + unsigned num_atoms_missplaced = 0; + for (AtomBlockId atom_blk_id : atom_netlist.blocks()) { + // TODO: Currently only handle the case when all of the position + // data is provided. This can be extended, + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); + + // Get the (x, y, layer) position of the block. + int blk_x = flat_placement_info.blk_x_pos[atom_blk_id]; + int blk_y = flat_placement_info.blk_y_pos[atom_blk_id]; + int blk_layer = flat_placement_info.blk_layer[atom_blk_id]; + + // Get the (x, y, layer) position of the cluster that contains this block. + ClusterBlockId atom_clb_id = lookup.atom_clb(atom_blk_id); + const t_block_loc& clb_loc = block_locs[atom_clb_id]; + + // Compute the distance between these two positions. + float dx = blk_x - clb_loc.loc.x; + float dy = blk_y - clb_loc.loc.y; + float dlayer = blk_layer - clb_loc.loc.layer; + float dist = std::sqrt((dx * dx) + (dy * dy) + (dlayer * dlayer)); + + // Accumulate into the total displacement. + total_disp += dist; + + // Check if this block has been displaced beyond the threshold. + if (dist >= disp_threashold) { + num_atoms_missplaced++; + } + + // TODO: Make this debug option of higher verbosity. Helpful for + // debugging flat placement reconstruction. + /* + VTR_LOG("%s %d %d %d %d\n", + g_vpr_ctx.atom().nlist.block_name(atom_blk_id).c_str(), + clb_loc.loc.x, + clb_loc.loc.y, + clb_loc.loc.layer, + clb_loc.loc.sub_tile); + */ + } + + // Log the flat placement reconstruction info. + size_t num_atoms = atom_netlist.blocks().size(); + size_t num_clusters = clustered_netlist.blocks().size(); + VTR_LOG("Flat Placement Reconstruction Info:\n"); + VTR_LOG("\tPercent of clusters with reconstruction errors: %f\n", + static_cast(num_imperfect_clusters) / static_cast(num_clusters)); + VTR_LOG("\tTotal displacement of initial placement from flat placement: %f\n", + total_disp); + VTR_LOG("\tAverage atom displacement of initial placement from flat placement: %f\n", + total_disp / static_cast(num_atoms)); + VTR_LOG("\tPercent of atoms misplaced from the flat placement: %f\n", + static_cast(num_atoms_missplaced) / static_cast(num_atoms)); +} + diff --git a/vpr/src/base/load_flat_place.h b/vpr/src/base/load_flat_place.h index 683208bcf09..940c55cadbf 100644 --- a/vpr/src/base/load_flat_place.h +++ b/vpr/src/base/load_flat_place.h @@ -17,6 +17,7 @@ // Forward declarations class AtomBlockId; +class AtomLookup; class AtomNetlist; class ClusterBlockId; class ClusteredNetlist; @@ -61,3 +62,29 @@ FlatPlacementInfo read_flat_placement(const std::string& read_flat_place_file_pa */ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch); +/** + * @brief Logs information on the quality of the clustering and placement + * reconstruction of the given flat placement. + * + * @param flat_placement_info + * The flat placement to log, + * @param block_locs + * The location of each cluster in the netlist. + * @param atoms_lookup + * A lookup between each cluster and the atoms it contains. + * @param lookup + * A lookup between each atom and the cluster that contains it. + * @param atom_netlist + * The netlist of atoms the flat placement was over. + * @param clustered_netlist + * The clustered netlist that the flat placement was used to + * generate. + */ +void log_flat_placement_reconstruction_info( + const FlatPlacementInfo& flat_placement_info, + const vtr::vector_map& block_locs, + const vtr::vector>& atoms_lookup, + const AtomLookup& lookup, + const AtomNetlist& atom_netlist, + const ClusteredNetlist& clustered_netlist); + diff --git a/vpr/src/base/place_and_route.cpp b/vpr/src/base/place_and_route.cpp index 7074d34662a..106e33fed16 100644 --- a/vpr/src/base/place_and_route.cpp +++ b/vpr/src/base/place_and_route.cpp @@ -4,6 +4,7 @@ #include #include +#include "FlatPlacementInfo.h" #include "vtr_assert.h" #include "vtr_log.h" @@ -173,6 +174,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list, det_routing_arch, segment_inf, arch->directs, + FlatPlacementInfo(), // Pass empty flat placement info. /*is_flat=*/false); } success = route(router_net_list, @@ -311,6 +313,7 @@ int binary_search_place_and_route(const Netlist<>& placement_net_list, try_place(placement_net_list, placer_opts, router_opts, analysis_opts, noc_opts, arch->Chans, det_routing_arch, segment_inf, arch->directs, + FlatPlacementInfo(), // Pass empty flat placement info. /*is_flat=*/false); } diff --git a/vpr/src/base/vpr_api.cpp b/vpr/src/base/vpr_api.cpp index 1e3a4c390e9..50fd339b66b 100644 --- a/vpr/src/base/vpr_api.cpp +++ b/vpr/src/base/vpr_api.cpp @@ -688,10 +688,11 @@ bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) { + wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */ } - // Read in the flat placement if a flat placement file is provided. - FlatPlacementInfo flat_placement_info; - if (!vpr_setup.FileNameOpts.read_flat_place_file.empty()) { - flat_placement_info = read_flat_placement( + // Read in the flat placement if a flat placement file is provided and it + // has not been loaded already. + if (!vpr_setup.FileNameOpts.read_flat_place_file.empty() && + !g_vpr_ctx.atom().flat_placement_info.valid) { + g_vpr_ctx.mutable_atom().flat_placement_info = read_flat_placement( vpr_setup.FileNameOpts.read_flat_place_file, g_vpr_ctx.atom().nlist); } @@ -699,7 +700,7 @@ bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) { return try_pack(&vpr_setup.PackerOpts, &vpr_setup.AnalysisOpts, &arch, vpr_setup.user_models, vpr_setup.library_models, inter_cluster_delay, - vpr_setup.PackerRRGraph, flat_placement_info); + vpr_setup.PackerRRGraph, g_vpr_ctx.atom().flat_placement_info); } void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) { @@ -849,6 +850,15 @@ void vpr_place(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_arch& is_flat); } + // Read in the flat placement if a flat placement file is provided and it + // has not been loaded already. + if (!vpr_setup.FileNameOpts.read_flat_place_file.empty() && + !g_vpr_ctx.atom().flat_placement_info.valid) { + g_vpr_ctx.mutable_atom().flat_placement_info = read_flat_placement( + vpr_setup.FileNameOpts.read_flat_place_file, + g_vpr_ctx.atom().nlist); + } + try_place(net_list, vpr_setup.PlacerOpts, vpr_setup.RouterOpts, @@ -858,6 +868,7 @@ void vpr_place(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_arch& &vpr_setup.RoutingArch, vpr_setup.Segments, arch.directs, + g_vpr_ctx.atom().flat_placement_info, is_flat); auto& filename_opts = vpr_setup.FileNameOpts; diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 73a252a516a..ccfbf549bb4 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -5,6 +5,7 @@ #include #include +#include "FlatPlacementInfo.h" #include "prepack.h" #include "vpr_types.h" #include "vtr_ndmatrix.h" @@ -79,6 +80,10 @@ struct AtomContext : public Context { /// @brief Mappings to/from the Atom Netlist to physically described .blif models AtomLookup lookup; + + /// @brief Placement information on each atom known before packing and + /// placement. + FlatPlacementInfo flat_placement_info; }; /** diff --git a/vpr/src/pack/greedy_candidate_selector.cpp b/vpr/src/pack/greedy_candidate_selector.cpp index e028e061199..b93ed8b4a4d 100644 --- a/vpr/src/pack/greedy_candidate_selector.cpp +++ b/vpr/src/pack/greedy_candidate_selector.cpp @@ -7,6 +7,9 @@ #include "greedy_candidate_selector.h" #include +#include +#include +#include "FlatPlacementInfo.h" #include "atom_netlist.h" #include "attraction_groups.h" #include "cluster_legalizer.h" @@ -67,6 +70,7 @@ GreedyCandidateSelector::GreedyCandidateSelector( const std::unordered_set& is_global, const std::unordered_set& net_output_feeds_driving_block_input, const SetupTimingInfo& timing_info, + const FlatPlacementInfo& flat_placement_info, int log_verbosity) : atom_netlist_(atom_netlist), packer_opts_(packer_opts), @@ -78,6 +82,7 @@ GreedyCandidateSelector::GreedyCandidateSelector( is_global_(is_global), net_output_feeds_driving_block_input_(net_output_feeds_driving_block_input), timing_info_(timing_info), + flat_placement_info_(flat_placement_info), rng_(0) { // Initialize the list of molecules to pack, the clustering data, and the // net info. @@ -113,6 +118,51 @@ GreedyCandidateSelector::GreedyCandidateSelector( /* Store stats on nets used by packed block, useful for determining transitively connected blocks * (eg. [A1, A2, ..]->[B1, B2, ..]->C implies cluster [A1, A2, ...] and C have a weak link) */ clb_inter_blk_nets_.resize(atom_netlist.blocks().size()); + + // If a flat placement was provided, pre-load information used to + // reconstruct the packing from this information. + if (flat_placement_info.valid) { + // Need the maximum x, y, layer, and sub-tile information. + float max_x = -1.f; + float max_y = -1.f; + float max_layer = -1.f; + for (AtomBlockId blk_id : atom_netlist_.blocks()) { + max_x = std::max(max_x, flat_placement_info.blk_x_pos[blk_id]); + max_y = std::max(max_y, flat_placement_info.blk_y_pos[blk_id]); + max_layer = std::max(max_layer, flat_placement_info.blk_layer[blk_id]); + } + // Initialize the ND-Matrix for each tile in the flat placement. + VTR_ASSERT(max_x >= 0 && max_y >= 0 && max_layer >= 0); + size_t x_dim = std::floor(max_x) + 1; + size_t y_dim = std::floor(max_y) + 1; + size_t num_layers = std::floor(max_layer) + 1; + flat_tile_placement_.resize({x_dim, y_dim, num_layers}); + // Populate the ND-Matrix with each of the molecules. + std::unordered_set seen_molecules; + for (AtomBlockId blk_id : atom_netlist_.blocks()) { + VTR_ASSERT(flat_placement_info.blk_x_pos[blk_id] != -1.f && + flat_placement_info.blk_y_pos[blk_id] != -1.f && + flat_placement_info.blk_layer[blk_id] != -1.f); + // Get the molecule for this atom block. + t_pack_molecule* blk_mol = prepacker.get_atom_molecule(blk_id); + // Skip if we have already seen this molecule. + if (seen_molecules.count(blk_mol) != 0) + continue; + // Insert the molecule into the appropriate list + size_t tile_x = std::floor(flat_placement_info.blk_x_pos[blk_id]); + size_t tile_y = std::floor(flat_placement_info.blk_y_pos[blk_id]); + size_t tile_layer = std::floor(flat_placement_info.blk_layer[blk_id]); + FlatTileMoleculeList& tile_mol_list = flat_tile_placement_[tile_x][tile_y][tile_layer]; + if (flat_placement_info.blk_sub_tile[blk_id] == -1) { + tile_mol_list.undefined_sub_tile_mols.push_back(blk_mol); + } else { + size_t sub_tile = flat_placement_info.blk_sub_tile[blk_id]; + if (sub_tile >= tile_mol_list.sub_tile_mols.size()) + tile_mol_list.sub_tile_mols.resize(sub_tile + 1); + tile_mol_list.sub_tile_mols[sub_tile].push_back(blk_mol); + } + } + } } GreedyCandidateSelector::~GreedyCandidateSelector() { @@ -125,7 +175,9 @@ ClusterGainStats GreedyCandidateSelector::create_cluster_gain_stats( AttractionInfo& attraction_groups) { // Initialize the cluster gain stats. ClusterGainStats cluster_gain_stats; + cluster_gain_stats.seed_molecule = cluster_seed_mol; cluster_gain_stats.num_feasible_blocks = NOT_VALID; + cluster_gain_stats.has_done_connectivity_and_timing = false; // TODO: The reason this is being resized and not reserved is due to legacy // code which should be updated. cluster_gain_stats.feasible_blocks.resize(packer_opts_.feasible_block_array_size); @@ -175,6 +227,7 @@ void GreedyCandidateSelector::update_cluster_gain_stats_candidate_success( /* reset list of feasible blocks */ cluster_gain_stats.num_feasible_blocks = NOT_VALID; + cluster_gain_stats.has_done_connectivity_and_timing = false; /* TODO: Allow clusters to have more than one attraction group. */ if (atom_grp_id.is_valid()) cluster_gain_stats.attraction_grp_id = atom_grp_id; @@ -225,6 +278,9 @@ void GreedyCandidateSelector::update_cluster_gain_stats_candidate_success( e_net_relation_to_clustered_block::INPUT); } + // TODO: For flat placement reconstruction, should we mark the molecules + // in the same tile as the seed of this cluster? + update_total_gain(cluster_gain_stats, attraction_groups); } @@ -467,6 +523,9 @@ void GreedyCandidateSelector::update_total_gain(ClusterGainStats& cluster_gain_s if (cluster_gain_stats.sharing_gain.count(blk_id) == 0) { cluster_gain_stats.sharing_gain[blk_id] = 0; } + if (cluster_gain_stats.timing_gain.count(blk_id) == 0) { + cluster_gain_stats.timing_gain[blk_id] = 0; + } AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group(blk_id); if (atom_grp_id != AttractGroupId::INVALID() && atom_grp_id == cluster_att_grp_id) { @@ -545,13 +604,39 @@ t_pack_molecule* GreedyCandidateSelector::get_next_candidate_for_cluster( * (if the cluster has an attraction group). */ - // 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster - if (cluster_gain_stats.num_feasible_blocks == NOT_VALID) { - add_cluster_molecule_candidates_by_connectivity_and_timing(cluster_gain_stats, - cluster_id, - prepacker, - cluster_legalizer, - attraction_groups); + // 0. If flat placement is provided, first try to add molecule candidates + // that are placed in the same tile in the flat placement. + if (flat_placement_info_.valid) { + // If this is the first pass of candidate selection, use the flat placement info. + if (cluster_gain_stats.num_feasible_blocks == NOT_VALID) { + cluster_gain_stats.num_feasible_blocks = 0; + add_cluster_molecule_candidates_by_flat_placement(cluster_gain_stats, + cluster_id, + cluster_legalizer, + attraction_groups); + } + // If this is the second pass of candidate selection, use connectivity + // and timing. + if (cluster_gain_stats.num_feasible_blocks == 0 && + !cluster_gain_stats.has_done_connectivity_and_timing) { + add_cluster_molecule_candidates_by_connectivity_and_timing(cluster_gain_stats, + cluster_id, + prepacker, + cluster_legalizer, + attraction_groups); + cluster_gain_stats.has_done_connectivity_and_timing = true; + } + } else { + // 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster + if (cluster_gain_stats.num_feasible_blocks == NOT_VALID) { + cluster_gain_stats.num_feasible_blocks = 0; + add_cluster_molecule_candidates_by_connectivity_and_timing(cluster_gain_stats, + cluster_id, + prepacker, + cluster_legalizer, + attraction_groups); + cluster_gain_stats.has_done_connectivity_and_timing = true; + } } if (packer_opts_.prioritize_transitive_connectivity) { @@ -630,15 +715,46 @@ t_pack_molecule* GreedyCandidateSelector::get_next_candidate_for_cluster( return best_molecule; } +void GreedyCandidateSelector::add_cluster_molecule_candidates_by_flat_placement( + ClusterGainStats& cluster_gain_stats, + LegalizationClusterId legalization_cluster_id, + const ClusterLegalizer& cluster_legalizer, + AttractionInfo& attraction_groups) { + // Get the seed molecule root block. + AtomBlockId root_blk_id = cluster_gain_stats.seed_molecule->atom_block_ids[cluster_gain_stats.seed_molecule->root]; + // TODO: Instead of just using the seed, maybe we should get the candidates + // of all molecules in the cluster? However, this may have its own + // problems. + size_t tile_x = std::floor(flat_placement_info_.blk_x_pos[root_blk_id]); + size_t tile_y = std::floor(flat_placement_info_.blk_y_pos[root_blk_id]); + size_t tile_layer = std::floor(flat_placement_info_.blk_layer[root_blk_id]); + int sub_tile = flat_placement_info_.blk_sub_tile[root_blk_id]; + // TODO: We could handle unknown sub-tiles by trying all sub-tiles in the + // tile or having an "unkown sub-tile" bin. + VTR_ASSERT(sub_tile >= 0); + // Add all of the molecules in the current tile as candidates. + const std::vector& mols_in_tile = flat_tile_placement_[tile_x][tile_y][tile_layer].sub_tile_mols[sub_tile]; + + for (t_pack_molecule* molecule : mols_in_tile) { + // Add the molecule as a candidate if the molecule is not clustered and + // is compatible with this cluster (using simple checks). + if (!cluster_legalizer.is_mol_clustered(molecule) && + cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) { + add_molecule_to_pb_stats_candidates(molecule, + cluster_gain_stats, + packer_opts_.feasible_block_array_size, + attraction_groups, + atom_netlist_); + } + } +} + void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_and_timing( ClusterGainStats& cluster_gain_stats, LegalizationClusterId legalization_cluster_id, const Prepacker& prepacker, const ClusterLegalizer& cluster_legalizer, AttractionInfo& attraction_groups) { - VTR_ASSERT(cluster_gain_stats.num_feasible_blocks == NOT_VALID); - - cluster_gain_stats.num_feasible_blocks = 0; cluster_gain_stats.explore_transitive_fanout = true; /* If no legal molecules found, enable exploration of molecules two hops away */ for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks) { diff --git a/vpr/src/pack/greedy_candidate_selector.h b/vpr/src/pack/greedy_candidate_selector.h index 6aa140f7d66..edbd53806ea 100644 --- a/vpr/src/pack/greedy_candidate_selector.h +++ b/vpr/src/pack/greedy_candidate_selector.h @@ -15,12 +15,14 @@ #include "attraction_groups.h" #include "cluster_legalizer.h" #include "physical_types.h" +#include "vtr_ndmatrix.h" #include "vtr_vector.h" #include "vtr_random.h" // Forward declarations class AtomNetlist; class AttractionInfo; +class FlatPlacementInfo; class Prepacker; class SetupTimingInfo; class t_pack_high_fanout_thresholds; @@ -37,6 +39,14 @@ struct t_packer_opts; * into the given cluster. */ struct ClusterGainStats { + /// @brief The seed molecule used to create this cluster. + t_pack_molecule* seed_molecule = nullptr; + + /// @brief Has this cluster tried to get candidates by connectivity and + /// timing yet. This helps ensure that we only do that once per + /// cluster candidate proposal. + bool has_done_connectivity_and_timing = false; + /// @brief Attraction (inverse of cost) function. std::unordered_map gain; @@ -193,6 +203,10 @@ class GreedyCandidateSelector { * @param timing_info * Setup timing info for this Atom Netlist. Used to incorporate * timing / criticality into the gain calculation. + * @param flat_placement_info + * Placement information known about the atoms before they are + * clustered. If defined, helps inform the clusterer to build + * clusters. * @param log_verbosity * The verbosity of log messages in the candidate selector. */ @@ -207,6 +221,7 @@ class GreedyCandidateSelector { const std::unordered_set& is_global, const std::unordered_set& net_output_feeds_driving_block_input, const SetupTimingInfo& timing_info, + const FlatPlacementInfo& flat_placement_info, int log_verbosity); /** @@ -388,6 +403,15 @@ class GreedyCandidateSelector { // Cluster Candidate Selection // ===================================================================== // + /** + * @brief Add molecules that are "close" to the seed molecule in the flat + * placement tot he list of feasible blocks. + */ + void add_cluster_molecule_candidates_by_flat_placement( + ClusterGainStats& cluster_gain_stats, + LegalizationClusterId legalization_cluster_id, + const ClusterLegalizer& cluster_legalizer, + AttractionInfo& attraction_groups); /* * @brief Add molecules with strong connectedness to the current cluster to * the list of feasible blocks. @@ -514,6 +538,28 @@ class GreedyCandidateSelector { /// dimension is the number of external outputs of the molecule. std::vector> unrelated_clustering_data_; + /// @brief Placement information of the atoms in the netlist known before + /// packing. + const FlatPlacementInfo& flat_placement_info_; + + /** + * @brief Bins containing molecules in the same tile. Used for pre-computing + * flat placement information for clustering. + */ + struct FlatTileMoleculeList { + // A list of molecules in the undefined sub-tile at this tile. + std::vector undefined_sub_tile_mols; + // A list of molecule in each sub_tile at this tile. + std::vector> sub_tile_mols; + }; + + /// @brief Pre-computed information on the flat placement. Lists all of the + /// molecules at the given location according to the flat placement + /// information. For example: flat_tile_placement[x][y][layer] would + /// return lists of molecules at each of the sub-tiles at that + /// location. + vtr::NdMatrix flat_tile_placement_; + /// @brief A count on the number of unrelated clustering attempts which /// have been performed. int num_unrelated_clustering_attempts_ = 0; diff --git a/vpr/src/pack/greedy_clusterer.cpp b/vpr/src/pack/greedy_clusterer.cpp index dd2c9fb4551..5733965f302 100644 --- a/vpr/src/pack/greedy_clusterer.cpp +++ b/vpr/src/pack/greedy_clusterer.cpp @@ -41,6 +41,7 @@ #include #include #include +#include "FlatPlacementInfo.h" #include "SetupGrid.h" #include "atom_netlist.h" #include "attraction_groups.h" @@ -79,7 +80,8 @@ GreedyClusterer::GreedyClusterer(const t_packer_opts& packer_opts, const t_arch& arch, const t_pack_high_fanout_thresholds& high_fanout_thresholds, const std::unordered_set& is_clock, - const std::unordered_set& is_global) + const std::unordered_set& is_global, + const FlatPlacementInfo& flat_placement_info) : packer_opts_(packer_opts), analysis_opts_(analysis_opts), atom_netlist_(atom_netlist), @@ -87,6 +89,7 @@ GreedyClusterer::GreedyClusterer(const t_packer_opts& packer_opts, high_fanout_thresholds_(high_fanout_thresholds), is_clock_(is_clock), is_global_(is_global), + flat_placement_info_(flat_placement_info), primitive_candidate_block_types_(identify_primitive_candidate_block_types()), log_verbosity_(packer_opts.pack_verbosity), net_output_feeds_driving_block_input_(identify_net_output_feeds_driving_block_input(atom_netlist)) { @@ -141,6 +144,7 @@ GreedyClusterer::do_clustering(ClusterLegalizer& cluster_legalizer, is_global_, net_output_feeds_driving_block_input_, *timing_info, + flat_placement_info_, log_verbosity_); // Create the greedy seed selector. diff --git a/vpr/src/pack/greedy_clusterer.h b/vpr/src/pack/greedy_clusterer.h index eb1dff3afdf..93f23cbb775 100644 --- a/vpr/src/pack/greedy_clusterer.h +++ b/vpr/src/pack/greedy_clusterer.h @@ -19,6 +19,7 @@ class AtomNetId; class AtomNetlist; class AttractionInfo; class DeviceContext; +class FlatPlacementInfo; class GreedyCandidateSelector; class Prepacker; class SetupTimingInfo; @@ -76,6 +77,8 @@ class GreedyClusterer { * The set of global nets in the Atom Netlist. These will be * routed on special dedicated networks, and hence are less * relavent to locality / attraction. + * @param flat_placement_info + * Placement information of each atom known before packing. */ GreedyClusterer(const t_packer_opts& packer_opts, const t_analysis_opts& analysis_opts, @@ -83,7 +86,8 @@ class GreedyClusterer { const t_arch& arch, const t_pack_high_fanout_thresholds& high_fanout_thresholds, const std::unordered_set& is_clock, - const std::unordered_set& is_global); + const std::unordered_set& is_global, + const FlatPlacementInfo& flat_placement_info); /** * @brief Performs clustering on the pack molecules formed by the prepacker. @@ -227,6 +231,9 @@ class GreedyClusterer { /// @brief A set of atom nets which are considered as global nets. const std::unordered_set& is_global_; + /// @brief Flat placement information known about each atom before packing. + const FlatPlacementInfo& flat_placement_info_; + /// @brief Pre-computed logical block types for each model in the architecture. const std::map> primitive_candidate_block_types_; diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp index b71505246f8..8c342c39018 100644 --- a/vpr/src/pack/pack.cpp +++ b/vpr/src/pack/pack.cpp @@ -142,7 +142,8 @@ bool try_pack(t_packer_opts* packer_opts, *arch, high_fanout_thresholds, is_clock, - is_global); + is_global, + flat_placement_info); while (true) { //Cluster the netlist diff --git a/vpr/src/pack/verify_flat_placement.cpp b/vpr/src/pack/verify_flat_placement.cpp index 00e4b259876..5e657eabb98 100644 --- a/vpr/src/pack/verify_flat_placement.cpp +++ b/vpr/src/pack/verify_flat_placement.cpp @@ -96,6 +96,9 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme // TODO: May want to verify that the layer is all 0 in the case of 2D FPGAs. + // TODO: Should verify that the fixed block constraints are observed. + // It is ill-formed for a flat placement to disagree with the constraints. + return num_errors; } diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp index e6c8f8e09db..f999594be4b 100644 --- a/vpr/src/place/initial_placement.cpp +++ b/vpr/src/place/initial_placement.cpp @@ -1,3 +1,6 @@ +#include "FlatPlacementInfo.h" +#include "atom_netlist_fwd.h" +#include "place_macro.h" #include "vtr_memory.h" #include "vtr_random.h" #include "vtr_time.h" @@ -15,6 +18,7 @@ #include "noc_place_utils.h" #include +#include #include @@ -58,6 +62,7 @@ static bool place_macro(int macros_max_num_tries, std::vector* blk_types_empty_locs_in_grid, vtr::vector& block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng); /* @@ -194,6 +199,7 @@ static bool try_centroid_placement(const t_pl_macro& pl_macro, e_pad_loc_type pad_loc_type, vtr::vector& block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng); /** @@ -232,6 +238,7 @@ static void place_all_blocks(const t_placer_opts& placer_opts, e_pad_loc_type pad_loc_type, const char* constraints_file, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng); /** @@ -314,7 +321,7 @@ static bool is_loc_legal(const t_pl_loc& loc, continue; } - if (reg_rect.contains({loc.x, loc.y})) { + if (reg_rect.coincident({loc.x, loc.y})) { //check if the location is compatible with the block type const auto& type = grid.get_physical_type({loc.x, loc.y, loc.layer}); int height_offset = grid.get_height_offset({loc.x, loc.y, loc.layer}); @@ -483,19 +490,81 @@ static std::vector find_centroid_loc(const t_pl_macro& pl_macro, return connected_blocks_to_update; } +// TODO: Should this return the unplaced_blocks_to_update_their_score? +static void find_centroid_loc_from_flat_placement(const t_pl_macro& pl_macro, + t_pl_loc& centroid, + const FlatPlacementInfo& flat_placement_info) { + // Use the flat placement to compute the centroid of the given macro. + // TODO: Instead of averaging, maybe use MODE (most frequently placed location). + float acc_weight = 0.f; + float acc_x = 0.f; + float acc_y = 0.f; + float acc_layer = 0.f; + float acc_sub_tile = 0.f; + for (const t_pl_macro_member& member : pl_macro.members) { + const auto& cluster_atoms = g_vpr_ctx.clustering().atoms_lookup[member.blk_index]; + for (AtomBlockId atom_blk_id : cluster_atoms) { + // TODO: We can get away with using less information. + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS && + flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS && + flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS && + flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); + // TODO: Make this a debug print. + // VTR_LOG("%s ", g_vpr_ctx.atom().nlist.block_name(atom_blk_id).c_str()); + + // Accumulate the x, y, layer, and sub_tile for each atom in each + // member of the macro. Remove the offset so the centroid would be + // where the head macro should be placed to put the members in the + // correct place. + acc_x += flat_placement_info.blk_x_pos[atom_blk_id] - member.offset.x; + acc_y += flat_placement_info.blk_y_pos[atom_blk_id] - member.offset.y; + acc_layer += flat_placement_info.blk_layer[atom_blk_id] - member.offset.layer; + acc_sub_tile += flat_placement_info.blk_sub_tile[atom_blk_id] - member.offset.sub_tile; + acc_weight++; + } + } + if (acc_weight > 0.f) { + // NOTE: We add an offset of 0.5 to prevent us from moving to the tile + // below / to the left due to tiny numerical changes (this + // pretends that each atom is in the center of the tile). + centroid.x = std::floor((acc_x / acc_weight) + 0.5f); + centroid.y = std::floor((acc_y / acc_weight) + 0.5f); + centroid.layer = std::floor((acc_layer / acc_weight) + 0.5f); + centroid.sub_tile = std::floor((acc_sub_tile / acc_weight) + 0.5f); + + // TODO: Make this a debug print. + // VTR_LOG("\n\t(%d, %d, %d, %d)\n", centroid.x, centroid.y, centroid.layer, centroid.sub_tile); + } +} + static bool try_centroid_placement(const t_pl_macro& pl_macro, const PartitionRegion& pr, t_logical_block_type_ptr block_type, e_pad_loc_type pad_loc_type, vtr::vector& block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng) { auto& block_locs = blk_loc_registry.mutable_block_locs(); t_pl_loc centroid_loc(OPEN, OPEN, OPEN, OPEN); std::vector unplaced_blocks_to_update_their_score; - unplaced_blocks_to_update_their_score = find_centroid_loc(pl_macro, centroid_loc, blk_loc_registry); + if (!flat_placement_info.valid) { + // If a flat placement is not provided, use the centroid of connected + // blocks which have already been placed. + unplaced_blocks_to_update_their_score = find_centroid_loc(pl_macro, centroid_loc, blk_loc_registry); + } else { + // If a flat placement is provided, use the flat placement to get the + // centroid. + find_centroid_loc_from_flat_placement(pl_macro, centroid_loc, flat_placement_info); + // If a centroid could not be found, or if the tile is not legal + // fall-back on the centroid of the neighbor blocks of this block. + if (!is_loc_on_chip({centroid_loc.x, centroid_loc.y, centroid_loc.layer}) || + !is_loc_legal(centroid_loc, pr, block_type)) { + unplaced_blocks_to_update_their_score = find_centroid_loc(pl_macro, centroid_loc, blk_loc_registry); + } + } //no suggestion was available for this block type if (!is_loc_on_chip({centroid_loc.x, centroid_loc.y, centroid_loc.layer})) { @@ -894,6 +963,7 @@ static bool place_macro(int macros_max_num_tries, std::vector* blk_types_empty_locs_in_grid, vtr::vector& block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng) { const auto& block_locs = blk_loc_registry.block_locs(); ClusterBlockId blk_id = pl_macro.members[0].blk_index; @@ -928,7 +998,7 @@ static bool place_macro(int macros_max_num_tries, if (!macro_placed) { VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\t\t\tTry centroid placement\n"); - macro_placed = try_centroid_placement(pl_macro, pr, block_type, pad_loc_type, block_scores, blk_loc_registry, rng); + macro_placed = try_centroid_placement(pl_macro, pr, block_type, pad_loc_type, block_scores, blk_loc_registry, flat_placement_info, rng); } VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\t\t\tMacro is placed: %d\n", macro_placed); // If macro is not placed yet, try to place the macro randomly for the max number of random tries @@ -999,6 +1069,7 @@ static void place_all_blocks(const t_placer_opts& placer_opts, enum e_pad_loc_type pad_loc_type, const char* constraints_file, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng) { const auto& cluster_ctx = g_vpr_ctx.clustering(); const auto& device_ctx = g_vpr_ctx.device(); @@ -1059,7 +1130,13 @@ static void place_all_blocks(const t_placer_opts& placer_opts, blocks_placed_since_heap_update++; - bool block_placed = place_one_block(blk_id, pad_loc_type, &blk_types_empty_locs_in_grid[blk_id_type->index], &block_scores, blk_loc_registry, rng); + bool block_placed = place_one_block(blk_id, + pad_loc_type, + &blk_types_empty_locs_in_grid[blk_id_type->index], + &block_scores, + blk_loc_registry, + flat_placement_info, + rng); //update heap based on update_heap_freq calculated above if (blocks_placed_since_heap_update % (update_heap_freq) == 0) { @@ -1100,6 +1177,7 @@ bool place_one_block(const ClusterBlockId blk_id, std::vector* blk_types_empty_locs_in_grid, vtr::vector* block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng) { const auto& block_locs = blk_loc_registry.block_locs(); const auto& place_macros = blk_loc_registry.place_macros(); @@ -1117,7 +1195,7 @@ bool place_one_block(const ClusterBlockId blk_id, if (imacro != -1) { //If the block belongs to a macro, pass that macro to the placement routines VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\tBelongs to a macro %d\n", imacro); const t_pl_macro& pl_macro = place_macros[imacro]; - placed_macro = place_macro(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, pl_macro, pad_loc_type, blk_types_empty_locs_in_grid, *block_scores, blk_loc_registry, rng); + placed_macro = place_macro(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, pl_macro, pad_loc_type, blk_types_empty_locs_in_grid, *block_scores, blk_loc_registry, flat_placement_info, rng); } else { //If it does not belong to a macro, create a macro with the one block and then pass to the placement routines //This is done so that the initial placement flow can be the same whether the block belongs to a macro or not @@ -1126,7 +1204,7 @@ bool place_one_block(const ClusterBlockId blk_id, macro_member.offset = t_pl_offset(0, 0, 0, 0); t_pl_macro pl_macro; pl_macro.members.push_back(macro_member); - placed_macro = place_macro(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, pl_macro, pad_loc_type, blk_types_empty_locs_in_grid, *block_scores, blk_loc_registry, rng); + placed_macro = place_macro(MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY, pl_macro, pad_loc_type, blk_types_empty_locs_in_grid, *block_scores, blk_loc_registry, flat_placement_info, rng); } return placed_macro; @@ -1160,6 +1238,7 @@ void initial_placement(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, BlkLocRegistry& blk_loc_registry, std::optional& noc_cost_handler, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng) { vtr::ScopedStartFinishTimer timer("Initial Placement"); auto& block_locs = blk_loc_registry.mutable_block_locs(); @@ -1201,7 +1280,9 @@ void initial_placement(const t_placer_opts& placer_opts, vtr::vector block_scores = assign_block_scores(place_macros); //Place all blocks - place_all_blocks(placer_opts, block_scores, placer_opts.pad_loc_type, constraints_file, blk_loc_registry, rng); + place_all_blocks(placer_opts, block_scores, placer_opts.pad_loc_type, + constraints_file, blk_loc_registry, + flat_placement_info, rng); } alloc_and_load_movable_blocks(block_locs); diff --git a/vpr/src/place/initial_placement.h b/vpr/src/place/initial_placement.h index f2078a3e720..2f0181f44da 100644 --- a/vpr/src/place/initial_placement.h +++ b/vpr/src/place/initial_placement.h @@ -11,7 +11,12 @@ class NocCostHandler; #include "vpr_types.h" #include "vtr_vector_map.h" +// Forward declarations class BlkLocRegistry; +class FlatPlacementInfo; +namespace vtr { + class RngContainer; +} // namespace vtr /* The maximum number of tries when trying to place a macro at a * random location before trying exhaustive placement - find the first @@ -144,6 +149,7 @@ void initial_placement(const t_placer_opts& placer_opts, const t_noc_opts& noc_opts, BlkLocRegistry& blk_loc_registry, std::optional& noc_cost_handler, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng); /** @@ -164,6 +170,7 @@ bool place_one_block(const ClusterBlockId blk_id, std::vector* blk_types_empty_locs_in_grid, vtr::vector* block_scores, BlkLocRegistry& blk_loc_registry, + const FlatPlacementInfo& flat_placement_info, vtr::RngContainer& rng); diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp index 69e4e1895a0..b6ba05ecb41 100644 --- a/vpr/src/place/place.cpp +++ b/vpr/src/place/place.cpp @@ -1,6 +1,7 @@ #include +#include "FlatPlacementInfo.h" #include "vtr_assert.h" #include "vtr_log.h" #include "vtr_time.h" @@ -47,6 +48,7 @@ void try_place(const Netlist<>& net_list, t_det_routing_arch* det_routing_arch, std::vector& segment_inf, const std::vector& directs, + const FlatPlacementInfo& flat_placement_info, bool is_flat) { /* Currently, the functions that require is_flat as their parameter and are called during placement should @@ -106,7 +108,7 @@ void try_place(const Netlist<>& net_list, ClusteredPinAtomPinsLookup netlist_pin_lookup(cluster_ctx.clb_nlist, atom_ctx.nlist, pb_gpin_lookup); Placer placer(net_list, placer_opts, analysis_opts, noc_opts, pb_gpin_lookup, netlist_pin_lookup, - directs, place_delay_model, cube_bb, is_flat, /*quiet=*/false); + directs, flat_placement_info, place_delay_model, cube_bb, is_flat, /*quiet=*/false); placer.place(); diff --git a/vpr/src/place/place.h b/vpr/src/place/place.h index e4a0172ba4e..73995af2a0a 100644 --- a/vpr/src/place/place.h +++ b/vpr/src/place/place.h @@ -3,6 +3,8 @@ #include "vpr_types.h" +class FlatPlacementInfo; + void try_place(const Netlist<>& net_list, const t_placer_opts& placer_opts, const t_router_opts& router_opts, @@ -12,4 +14,6 @@ void try_place(const Netlist<>& net_list, t_det_routing_arch* det_routing_arch, std::vector& segment_inf, const std::vector& directs, + const FlatPlacementInfo& flat_placement_info, bool is_flat); + diff --git a/vpr/src/place/placer.cpp b/vpr/src/place/placer.cpp index 37b48f11d0d..27ae3e89165 100644 --- a/vpr/src/place/placer.cpp +++ b/vpr/src/place/placer.cpp @@ -3,11 +3,13 @@ #include +#include "FlatPlacementInfo.h" #include "vtr_time.h" #include "draw.h" #include "read_place.h" #include "analytic_placer.h" #include "initial_placement.h" +#include "load_flat_place.h" #include "concrete_timing_info.h" #include "verify_placement.h" #include "place_timing_update.h" @@ -23,6 +25,7 @@ Placer::Placer(const Netlist<>& net_list, const IntraLbPbPinLookup& pb_gpin_lookup, const ClusteredPinAtomPinsLookup& netlist_pin_lookup, const std::vector& directs, + const FlatPlacementInfo& flat_placement_info, std::shared_ptr place_delay_model, bool cube_bb, bool is_flat, @@ -64,7 +67,19 @@ Placer::Placer(const Netlist<>& net_list, BlkLocRegistry& blk_loc_registry = placer_state_.mutable_blk_loc_registry(); initial_placement(placer_opts, placer_opts.constraints_file.c_str(), - noc_opts, blk_loc_registry, noc_cost_handler_, rng_); + noc_opts, blk_loc_registry, noc_cost_handler_, + flat_placement_info, rng_); + + // After initial placement, if a flat placement is being reconstructed, + // print flat placement reconstruction info. + if (flat_placement_info.valid) { + log_flat_placement_reconstruction_info(flat_placement_info, + blk_loc_registry.block_locs(), + g_vpr_ctx.clustering().atoms_lookup, + g_vpr_ctx.atom().lookup, + g_vpr_ctx.atom().nlist, + g_vpr_ctx.clustering().clb_nlist); + } const int move_lim = (int)(placer_opts.anneal_sched.inner_num * pow(net_list.blocks().size(), 1.3333)); //create the move generator based on the chosen placement strategy diff --git a/vpr/src/place/placer.h b/vpr/src/place/placer.h index 3fb89fb20f3..4da3c5fbb27 100644 --- a/vpr/src/place/placer.h +++ b/vpr/src/place/placer.h @@ -30,6 +30,7 @@ #include "PlacerCriticalities.h" #include "NetPinTimingInvalidator.h" +class FlatPlacementInfo; class PlacementAnnealer; namespace vtr{ class ScopedStartFinishTimer; @@ -44,6 +45,7 @@ class Placer { const IntraLbPbPinLookup& pb_gpin_lookup, const ClusteredPinAtomPinsLookup& netlist_pin_lookup, const std::vector& directs, + const FlatPlacementInfo& flat_placement_info, std::shared_ptr place_delay_model, bool cube_bb, bool is_flat, diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_analytic_placer/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_analytic_placer/config/golden_results.txt index 9faf05e95f9..7c275ef04da 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_analytic_placer/config/golden_results.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_analytic_placer/config/golden_results.txt @@ -1,2 +1,2 @@ - arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time - k6_frac_N10_mem32K_40nm.xml ch_intrinsics.v common 2.70 vpr 65.57 MiB -1 -1 0.46 18464 3 0.09 -1 -1 33268 -1 -1 68 99 1 0 success v8.0.0-11920-g63becbef4-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-12-04T15:29:41 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/release/vtr-verilog-to-routing 67140 99 130 344 474 1 227 298 12 12 144 clb auto 25.8 MiB 0.19 783 1293 269 877 147 65.6 MiB 0.07 0.00 1.86362 -117.589 -1.86362 1.86362 0.14 0.00131894 0.00124933 0.00585475 0.00563344 -1 -1 -1 -1 34 1729 21 5.66058e+06 4.21279e+06 293002. 2034.74 0.69 0.279636 0.254512 12094 55633 -1 1447 11 494 759 44038 15434 1.98889 1.98889 -143.496 -1.98889 -0.113193 -0.0844279 360780. 2505.42 0.01 0.05 0.05 -1 -1 0.01 0.0345628 0.0319717 +arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time +k6_frac_N10_mem32K_40nm.xml ch_intrinsics.v common 2.41 vpr 67.97 MiB -1 -1 0.27 22396 3 0.07 -1 -1 37184 -1 -1 68 99 1 0 success v8.0.0-12022-gc86d71bf5 release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:10:05 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 69600 99 130 344 474 1 227 298 12 12 144 clb auto 28.4 MiB 0.14 825 1293 236 881 176 68.0 MiB 0.08 0.00 1.90582 -118.892 -1.90582 1.90582 0.23 0.000836339 0.000716894 0.00586054 0.00547296 -1 -1 -1 -1 46 1402 9 5.66058e+06 4.21279e+06 378970. 2631.74 0.86 0.179641 0.159412 13238 73581 -1 1332 7 351 556 25815 8128 1.92739 1.92739 -132.029 -1.92739 -0.277709 -0.264614 486261. 3376.82 0.02 0.02 0.07 -1 -1 0.02 0.016991 0.0157011 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/config.txt new file mode 100644 index 00000000000..68fc81625c3 --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/config.txt @@ -0,0 +1,35 @@ +############################################## +# Configuration file for running experiments +############################################## + +# Path to directory of circuits to use +circuits_dir=benchmarks/blif/wiremap6 + +# Path to directory of architectures to use +archs_dir=arch/timing + +# Add circuits to list to sweep +circuit_list_add=alu4.pre-vpr.blif + +# Constrain the circuits to their devices +circuit_constraint_list_add=(alu4.pre-vpr.blif, device=mcnc_small) + +# Constrain the circuits to their channel widths +# 1.3 * minW +circuit_constraint_list_add=(alu4.pre-vpr.blif, route_chan_width=70) + +# Add architectures to list to sweep +arch_list_add=k6_frac_N10_40nm.xml + +# Parse info and how to parse +parse_file=vpr_standard.txt + +# How to parse QoR info +qor_parse_file=qor_standard.txt + +# Pass requirements +pass_requirements_file=pass_requirements.txt + +# Pass the script params while writing the vpr constraints. +script_params=-starting_stage vpr -track_memory_usage --read_flat_place ../../../../constraints/old_placement.fplace --write_flat_place placement.fplace + diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/golden_results.txt new file mode 100644 index 00000000000..d0610f693ca --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/config/golden_results.txt @@ -0,0 +1,2 @@ +arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time +k6_frac_N10_40nm.xml alu4.pre-vpr.blif common 1.83 vpr 67.48 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 79 14 -1 -1 success v8.0.0-12022-gc86d71bf5 release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:10:05 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing 69096 14 8 926 934 0 494 101 11 11 121 -1 mcnc_small 27.7 MiB 1.08 4647 3861 347 3260 254 67.5 MiB 0.13 0.01 4.63277 -33.0878 -4.63277 nan 0.00 0.00209215 0.00173488 0.0519805 0.0449116 -1 -1 -1 -1 -1 6413 16 4.36541e+06 4.25763e+06 511363. 4226.14 0.18 0.170897 0.151055 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace new file mode 100644 index 00000000000..357cb8fe79e --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace @@ -0,0 +1,934 @@ +n523 6 8 0 0 3 #0 lut +n522 6 8 0 0 5 #0 lut +n520 6 8 0 0 2 #0 lut +n518 6 8 0 0 16 #0 lut +n454 6 8 0 0 4 #0 lut +n298 6 8 0 0 14 #0 lut +n214 6 8 0 0 2 #0 lut +n517 6 8 0 0 0 #0 lut +n49 6 8 0 0 9 #0 lut +n516 6 8 0 0 6 #0 lut +n48 6 8 0 0 15 #0 lut +o_4_ 6 8 0 0 1 #0 lut +n47 6 8 0 0 17 #0 lut +o_3_ 3 2 0 0 17 #1 lut +n168 3 2 0 0 2 #1 lut +n158 3 2 0 0 3 #1 lut +n157 3 2 0 0 2 #1 lut +n156 3 2 0 0 4 #1 lut +n154 3 2 0 0 5 #1 lut +n165 3 2 0 0 0 #1 lut +n113 3 2 0 0 13 #1 lut +n112 3 2 0 0 16 #1 lut +n108 3 2 0 0 15 #1 lut +n159 3 2 0 0 12 #1 lut +n107 3 2 0 0 9 #1 lut +n292 6 9 0 0 12 #2 lut +n291 6 9 0 0 5 #2 lut +n288 6 9 0 0 3 #2 lut +n287 6 9 0 0 4 #2 lut +n286 6 9 0 0 0 #2 lut +n285 6 9 0 0 7 #2 lut +n293 6 9 0 0 13 #2 lut +n215 6 9 0 0 4 #2 lut +n295 6 9 0 0 8 #2 lut +n178 6 9 0 0 3 #2 lut +n290 6 9 0 0 2 #2 lut +n121 6 9 0 0 9 #2 lut +n739 3 6 0 0 5 #3 lut +n726 3 6 0 0 4 #3 lut +n725 3 6 0 0 8 #3 lut +n735 3 6 0 0 4 #3 lut +n722 3 6 0 0 2 #3 lut +n721 3 6 0 0 0 #3 lut +n737 3 6 0 0 13 #3 lut +n334 3 6 0 0 3 #3 lut +n720 3 6 0 0 7 #3 lut +n122 3 6 0 0 9 #3 lut +n727 3 6 0 0 6 #3 lut +n77 3 6 0 0 7 #3 lut +n719 2 8 0 0 0 #4 lut +n717 2 8 0 0 4 #4 lut +n716 2 8 0 0 1 #4 lut +n714 2 8 0 0 6 #4 lut +n711 2 8 0 0 4 #4 lut +n710 2 8 0 0 2 #4 lut +n707 2 8 0 0 5 #4 lut +n713 2 8 0 0 8 #4 lut +n700 2 8 0 0 7 #4 lut +n718 2 8 0 0 3 #4 lut +n133 2 8 0 0 9 #4 lut +n114 2 8 0 0 3 #4 lut +n926 6 6 0 0 6 #5 lut +n915 6 6 0 0 5 #5 lut +n41 6 6 0 0 0 #5 lut +n119 6 6 0 0 13 #5 lut +n118 6 6 0 0 7 #5 lut +n123 6 6 0 0 5 #5 lut +n124 6 6 0 0 4 #5 lut +n126 6 6 0 0 1 #5 lut +n129 6 6 0 0 17 #5 lut +n134 6 6 0 0 9 #5 lut +n238 6 6 0 0 3 #5 lut +n131 6 6 0 0 12 #5 lut +n914 6 6 0 0 4 #5 lut +n120 6 6 0 0 2 #5 lut +n439 6 6 0 0 7 #5 lut +n844 5 7 0 0 5 #6 lut +n29 5 7 0 0 2 #6 lut +n96 5 7 0 0 3 #6 lut +n135 5 7 0 0 6 #6 lut +n137 5 7 0 0 1 #6 lut +n839 5 7 0 0 4 #6 lut +n136 5 7 0 0 0 #6 lut +n138 5 7 0 0 8 #6 lut +n139 5 7 0 0 9 #6 lut +n111 5 7 0 0 4 #6 lut +n140 5 7 0 0 15 #6 lut +n842 5 7 0 0 5 #6 lut +n142 5 7 0 0 7 #6 lut +n843 5 7 0 0 6 #6 lut +n797 3 5 0 0 4 #7 lut +n793 3 5 0 0 0 #7 lut +n799 3 5 0 0 6 #7 lut +n786 3 5 0 0 5 #7 lut +n800 3 5 0 0 8 #7 lut +n696 3 5 0 0 1 #7 lut +n153 3 5 0 0 7 #7 lut +n789 3 5 0 0 13 #7 lut +n152 3 5 0 0 15 #7 lut +n796 3 5 0 0 2 #7 lut +n146 3 5 0 0 9 #7 lut +n144 3 5 0 0 8 #7 lut +n898 7 6 0 0 2 #8 lut +n896 7 6 0 0 5 #8 lut +n893 7 6 0 0 7 #8 lut +n899 7 6 0 0 17 #8 lut +n886 7 6 0 0 6 #8 lut +n884 7 6 0 0 4 #8 lut +n895 7 6 0 0 13 #8 lut +n882 7 6 0 0 1 #8 lut +n881 7 6 0 0 4 #8 lut +n406 7 6 0 0 0 #8 lut +n239 7 6 0 0 7 #8 lut +n150 7 6 0 0 9 #8 lut +n275 8 9 0 0 3 #9 lut +n272 8 9 0 0 6 #9 lut +n266 8 9 0 0 2 #9 lut +n264 8 9 0 0 0 #9 lut +n274 8 9 0 0 5 #9 lut +n261 8 9 0 0 16 #9 lut +n260 8 9 0 0 4 #9 lut +n164 8 9 0 0 7 #9 lut +n163 8 9 0 0 9 #9 lut +n276 8 9 0 0 2 #9 lut +n55 8 9 0 0 17 #9 lut +n44 8 9 0 0 1 #9 lut +n604 5 1 0 0 8 #10 lut +n582 5 1 0 0 0 #10 lut +n595 5 1 0 0 17 #10 lut +n346 5 1 0 0 14 #10 lut +n541 5 1 0 0 7 #10 lut +n526 5 1 0 0 3 #10 lut +n583 5 1 0 0 2 #10 lut +n596 5 1 0 0 13 #10 lut +n192 5 1 0 0 12 #10 lut +n598 5 1 0 0 15 #10 lut +n600 5 1 0 0 4 #10 lut +n166 5 1 0 0 9 #10 lut +n601 5 1 0 0 5 #10 lut +n602 5 1 0 0 6 #10 lut +n423 4 9 0 0 6 #11 lut +n421 4 9 0 0 4 #11 lut +n419 4 9 0 0 0 #11 lut +n415 4 9 0 0 4 #11 lut +n413 4 9 0 0 2 #11 lut +n412 4 9 0 0 13 #11 lut +n411 4 9 0 0 5 #11 lut +n171 4 9 0 0 9 #11 lut +n417 4 9 0 0 14 #11 lut +n235 4 9 0 0 5 #11 lut +n170 4 9 0 0 8 #11 lut +n130 4 9 0 0 15 #11 lut +n244 7 9 0 0 3 #12 lut +n243 7 9 0 0 17 #12 lut +n242 7 9 0 0 5 #12 lut +n241 7 9 0 0 7 #12 lut +n240 7 9 0 0 0 #12 lut +n458 7 9 0 0 4 #12 lut +n237 7 9 0 0 4 #12 lut +n236 7 9 0 0 1 #12 lut +n233 7 9 0 0 2 #12 lut +n232 7 9 0 0 9 #12 lut +n209 7 9 0 0 3 #12 lut +n234 7 9 0 0 6 #12 lut +n182 7 9 0 0 5 #12 lut +n557 2 1 0 0 4 #13 lut +n556 2 1 0 0 0 #13 lut +n554 2 1 0 0 6 #13 lut +n550 2 1 0 0 10 #13 lut +n549 2 1 0 0 8 #13 lut +n548 2 1 0 0 2 #13 lut +n547 2 1 0 0 13 #13 lut +n546 2 1 0 0 8 #13 lut +n545 2 1 0 0 7 #13 lut +n540 2 1 0 0 5 #13 lut +n500 2 1 0 0 3 #13 lut +n555 2 1 0 0 12 #13 lut +n308 2 1 0 0 9 #13 lut +n574 6 5 0 0 14 #14 lut +n31 6 5 0 0 7 #14 lut +n395 6 5 0 0 1 #14 lut +n393 6 5 0 0 9 #14 lut +n394 6 5 0 0 4 #14 lut +n407 6 5 0 0 3 #14 lut +n397 6 5 0 0 6 #14 lut +n410 6 5 0 0 2 #14 lut +n398 6 5 0 0 17 #14 lut +n399 6 5 0 0 5 #14 lut +n401 6 5 0 0 4 #14 lut +n404 6 5 0 0 15 #14 lut +n405 6 5 0 0 13 #14 lut +n409 6 5 0 0 0 #14 lut +n913 2 9 0 0 5 #15 lut +n912 2 9 0 0 13 #15 lut +n911 2 9 0 0 8 #15 lut +n909 2 9 0 0 6 #15 lut +n908 2 9 0 0 2 #15 lut +n906 2 9 0 0 15 #15 lut +n529 2 9 0 0 9 #15 lut +n422 2 9 0 0 9 #15 lut +n420 2 9 0 0 8 #15 lut +n907 2 9 0 0 0 #15 lut +n283 2 9 0 0 3 #15 lut +n910 2 9 0 0 4 #15 lut +n91 2 9 0 0 7 #15 lut +n466 7 7 0 0 4 #16 lut +n465 7 7 0 0 2 #16 lut +n467 7 7 0 0 6 #16 lut +n32 7 7 0 0 14 #16 lut +n461 7 7 0 0 4 #16 lut +n69 7 7 0 0 1 #16 lut +n459 7 7 0 0 13 #16 lut +n99 7 7 0 0 7 #16 lut +n297 7 7 0 0 16 #16 lut +n336 7 7 0 0 3 #16 lut +n371 7 7 0 0 5 #16 lut +n455 7 7 0 0 9 #16 lut +n456 7 7 0 0 15 #16 lut +n457 7 7 0 0 17 #16 lut +n460 7 7 0 0 0 #16 lut +n464 7 7 0 0 5 #16 lut +n463 8 7 0 0 7 #17 lut +n462 8 7 0 0 9 #17 lut +n375 8 7 0 0 2 #17 lut +n370 8 7 0 0 13 #17 lut +n366 8 7 0 0 4 #17 lut +n468 8 7 0 0 8 #17 lut +n364 8 7 0 0 6 #17 lut +n363 8 7 0 0 5 #17 lut +n367 8 7 0 0 8 #17 lut +n328 8 7 0 0 0 #17 lut +n304 8 7 0 0 9 #17 lut +n199 8 7 0 0 7 #17 lut +n565 3 1 0 0 10 #18 lut +n543 3 1 0 0 8 #18 lut +n564 3 1 0 0 4 #18 lut +n538 3 1 0 0 16 #18 lut +n533 3 1 0 0 0 #18 lut +n558 3 1 0 0 2 #18 lut +n532 3 1 0 0 13 #18 lut +n531 3 1 0 0 7 #18 lut +n524 3 1 0 0 9 #18 lut +o_5_ 3 1 0 0 17 #18 lut +n542 3 1 0 0 6 #18 lut +n373 3 1 0 0 12 #18 lut +n54 3 1 0 0 9 #18 lut +n757 6 3 0 0 6 #19 lut +n756 6 3 0 0 4 #19 lut +n552 6 3 0 0 7 #19 lut +n551 6 3 0 0 9 #19 lut +n764 6 3 0 0 2 #19 lut +n504 6 3 0 0 12 #19 lut +n763 6 3 0 0 4 #19 lut +n503 6 3 0 0 5 #19 lut +n416 6 3 0 0 5 #19 lut +n761 6 3 0 0 0 #19 lut +n553 6 3 0 0 17 #19 lut +n280 6 3 0 0 16 #19 lut +n25 6 3 0 0 13 #19 lut +o_7_ 5 4 0 0 17 #20 lut +n838 5 4 0 0 16 #20 lut +n38 5 4 0 0 6 #20 lut +n785 5 4 0 0 4 #20 lut +n327 5 4 0 0 12 #20 lut +n365 5 4 0 0 9 #20 lut +n628 5 4 0 0 8 #20 lut +n57 5 4 0 0 7 #20 lut +n782 5 4 0 0 2 #20 lut +n666 5 4 0 0 1 #20 lut +n674 5 4 0 0 9 #20 lut +n752 5 4 0 0 7 #20 lut +n778 5 4 0 0 5 #20 lut +n783 5 4 0 0 0 #20 lut +n754 5 4 0 0 13 #20 lut +n742 2 5 0 0 5 #21 lut +n686 2 5 0 0 4 #21 lut +n684 2 5 0 0 1 #21 lut +n683 2 5 0 0 7 #21 lut +n682 2 5 0 0 2 #21 lut +n680 2 5 0 0 4 #21 lut +n744 2 5 0 0 0 #21 lut +n679 2 5 0 0 3 #21 lut +n676 2 5 0 0 17 #21 lut +n675 2 5 0 0 9 #21 lut +n687 2 5 0 0 13 #21 lut +n414 2 5 0 0 3 #21 lut +n807 4 8 0 0 6 #22 lut +n804 4 8 0 0 2 #22 lut +n803 4 8 0 0 0 #22 lut +n801 4 8 0 0 5 #22 lut +n805 4 8 0 0 8 #22 lut +n688 4 8 0 0 9 #22 lut +n472 4 8 0 0 8 #22 lut +n808 4 8 0 0 6 #22 lut +n379 4 8 0 0 7 #22 lut +n806 4 8 0 0 15 #22 lut +n338 4 8 0 0 1 #22 lut +n802 4 8 0 0 4 #22 lut +n230 4 8 0 0 3 #22 lut +n347 4 5 0 0 4 #23 lut +n689 4 5 0 0 0 #23 lut +n919 4 5 0 0 8 #23 lut +n832 4 5 0 0 6 #23 lut +n489 4 5 0 0 12 #23 lut +n690 4 5 0 0 9 #23 lut +n920 4 5 0 0 15 #23 lut +n369 4 5 0 0 3 #23 lut +n833 4 5 0 0 5 #23 lut +n442 4 5 0 0 1 #23 lut +n790 4 5 0 0 5 #23 lut +n894 4 5 0 0 4 #23 lut +n792 4 5 0 0 2 #23 lut +n791 4 5 0 0 14 #23 lut +n849 4 5 0 0 13 #23 lut +n829 1 4 0 0 6 #24 lut +n828 1 4 0 0 2 #24 lut +n827 1 4 0 0 4 #24 lut +n826 1 4 0 0 0 #24 lut +n825 1 4 0 0 4 #24 lut +n743 1 4 0 0 12 #24 lut +n706 1 4 0 0 5 #24 lut +n705 1 4 0 0 8 #24 lut +n702 1 4 0 0 13 #24 lut +n701 1 4 0 0 9 #24 lut +n703 1 4 0 0 15 #24 lut +n196 1 4 0 0 14 #24 lut +n862 3 4 0 0 4 #25 lut +n859 3 4 0 0 5 #25 lut +n857 3 4 0 0 3 #25 lut +n856 3 4 0 0 4 #25 lut +n854 3 4 0 0 0 #25 lut +n853 3 4 0 0 17 #25 lut +n852 3 4 0 0 16 #25 lut +n851 3 4 0 0 7 #25 lut +n860 3 4 0 0 2 #25 lut +n704 3 4 0 0 9 #25 lut +n858 3 4 0 0 13 #25 lut +n195 3 4 0 0 5 #25 lut +n869 1 8 0 0 6 #26 lut +n868 1 8 0 0 17 #26 lut +n867 1 8 0 0 0 #26 lut +n866 1 8 0 0 5 #26 lut +n865 1 8 0 0 4 #26 lut +n863 1 8 0 0 7 #26 lut +n746 1 8 0 0 2 #26 lut +n355 1 8 0 0 3 #26 lut +n864 1 8 0 0 13 #26 lut +n708 1 8 0 0 9 #26 lut +n305 1 8 0 0 5 #26 lut +n835 1 8 0 0 4 #26 lut +n302 1 8 0 0 7 #26 lut +n712 5 5 0 0 8 #27 lut +n148 5 5 0 0 3 #27 lut +n330 5 5 0 0 4 #27 lut +n343 5 5 0 0 13 #27 lut +n329 5 5 0 0 5 #27 lut +n342 5 5 0 0 7 #27 lut +n331 5 5 0 0 6 #27 lut +n332 5 5 0 0 0 #27 lut +n709 5 5 0 0 9 #27 lut +n333 5 5 0 0 7 #27 lut +n174 5 5 0 0 12 #27 lut +n580 5 5 0 0 1 #27 lut +n337 5 5 0 0 2 #27 lut +n339 5 5 0 0 4 #27 lut +n870 9 6 0 0 4 #28 lut +n877 9 6 0 0 2 #28 lut +n734 9 6 0 0 15 #28 lut +n876 9 6 0 0 6 #28 lut +n733 9 6 0 0 16 #28 lut +n732 9 6 0 0 13 #28 lut +n730 9 6 0 0 5 #28 lut +n729 9 6 0 0 0 #28 lut +n871 9 6 0 0 4 #28 lut +n728 9 6 0 0 9 #28 lut +n731 9 6 0 0 17 #28 lut +n68 9 6 0 0 1 #28 lut +n818 4 7 0 0 8 #29 lut +n815 4 7 0 0 4 #29 lut +n812 4 7 0 0 5 #29 lut +n846 4 7 0 0 15 #29 lut +n508 4 7 0 0 12 #29 lut +n736 4 7 0 0 9 #29 lut +n294 4 7 0 0 0 #29 lut +n738 4 7 0 0 13 #29 lut +n270 4 7 0 0 3 #29 lut +n845 4 7 0 0 17 #29 lut +n819 4 7 0 0 6 #29 lut +n247 4 7 0 0 2 #29 lut +n831 2 6 0 0 4 #30 lut +n820 2 6 0 0 0 #30 lut +n509 2 6 0 0 12 #30 lut +n821 2 6 0 0 4 #30 lut +n724 2 6 0 0 14 #30 lut +n750 2 6 0 0 13 #30 lut +n745 2 6 0 0 9 #30 lut +n747 2 6 0 0 16 #30 lut +n748 2 6 0 0 17 #30 lut +n53 2 6 0 0 1 #30 lut +n749 2 6 0 0 15 #30 lut +n751 2 6 0 0 5 #30 lut +n809 2 6 0 0 3 #30 lut +n822 2 6 0 0 2 #30 lut +n699 4 2 0 0 14 #31 lut +n698 4 2 0 0 5 #31 lut +n697 4 2 0 0 4 #31 lut +n695 4 2 0 0 15 #31 lut +n758 4 2 0 0 9 #31 lut +n693 4 2 0 0 0 #31 lut +n692 4 2 0 0 6 #31 lut +n612 4 2 0 0 6 #31 lut +n759 4 2 0 0 8 #31 lut +n694 4 2 0 0 4 #31 lut +n382 4 2 0 0 3 #31 lut +n180 4 2 0 0 2 #31 lut +n46 4 2 0 0 5 #31 lut +n128 6 4 0 0 15 #32 lut +n491 6 4 0 0 4 #32 lut +n779 6 4 0 0 9 #32 lut +n431 6 4 0 0 1 #32 lut +n483 6 4 0 0 3 #32 lut +n482 6 4 0 0 5 #32 lut +n492 6 4 0 0 13 #32 lut +n521 6 4 0 0 7 #32 lut +n426 6 4 0 0 14 #32 lut +n484 6 4 0 0 6 #32 lut +n485 6 4 0 0 2 #32 lut +n486 6 4 0 0 0 #32 lut +n488 6 4 0 0 4 #32 lut +n780 6 4 0 0 17 #32 lut +n490 6 4 0 0 16 #32 lut +n905 7 2 0 0 0 #33 lut +n904 7 2 0 0 5 #33 lut +n59 7 2 0 0 1 #33 lut +n537 7 2 0 0 7 #33 lut +n589 7 2 0 0 2 #33 lut +n901 7 2 0 0 8 #33 lut +n587 7 2 0 0 4 #33 lut +n588 7 2 0 0 4 #33 lut +n590 7 2 0 0 14 #33 lut +n61 7 2 0 0 5 #33 lut +n902 7 2 0 0 13 #33 lut +n475 7 2 0 0 12 #33 lut +n591 7 2 0 0 6 #33 lut +n903 7 2 0 0 15 #33 lut +n897 7 2 0 0 9 #33 lut +n85 8 6 0 0 16 #34 lut +n81 8 6 0 0 2 #34 lut +n79 8 6 0 0 0 #34 lut +n73 8 6 0 0 5 #34 lut +o_2_ 8 6 0 0 17 #34 lut +n84 8 6 0 0 3 #34 lut +n71 8 6 0 0 13 #34 lut +n83 8 6 0 0 4 #34 lut +n70 8 6 0 0 7 #34 lut +n64 8 6 0 0 4 #34 lut +n51 8 6 0 0 9 #34 lut +n39 8 6 0 0 5 #34 lut +n228 3 8 0 0 2 #35 lut +n225 3 8 0 0 13 #35 lut +n224 3 8 0 0 4 #35 lut +n219 3 8 0 0 5 #35 lut +n231 3 8 0 0 4 #35 lut +n218 3 8 0 0 0 #35 lut +n217 3 8 0 0 3 #35 lut +n229 3 8 0 0 8 #35 lut +n216 3 8 0 0 15 #35 lut +n145 3 8 0 0 9 #35 lut +n221 3 8 0 0 6 #35 lut +n78 3 8 0 0 5 #35 lut +n663 1 2 0 0 5 #36 lut +n35 1 2 0 0 1 #36 lut +n161 1 2 0 0 4 #36 lut +n578 1 2 0 0 8 #36 lut +n162 1 2 0 0 9 #36 lut +n220 1 2 0 0 14 #36 lut +n662 1 2 0 0 7 #36 lut +n310 1 2 0 0 5 #36 lut +n309 1 2 0 0 4 #36 lut +n570 1 2 0 0 6 #36 lut +n311 1 2 0 0 6 #36 lut +n572 1 2 0 0 0 #36 lut +n573 1 2 0 0 2 #36 lut +n579 1 2 0 0 15 #36 lut +n210 5 2 0 0 17 #37 lut +n207 5 2 0 0 0 #37 lut +n194 5 2 0 0 9 #37 lut +n206 5 2 0 0 15 #37 lut +n193 5 2 0 0 6 #37 lut +n191 5 2 0 0 5 #37 lut +n189 5 2 0 0 4 #37 lut +n188 5 2 0 0 2 #37 lut +n213 5 2 0 0 5 #37 lut +n187 5 2 0 0 9 #37 lut +n208 5 2 0 0 13 #37 lut +n117 5 2 0 0 8 #37 lut +n248 6 2 0 0 1 #38 lut +n246 6 2 0 0 4 #38 lut +n374 6 2 0 0 3 #38 lut +n205 6 2 0 0 0 #38 lut +n204 6 2 0 0 15 #38 lut +n372 6 2 0 0 4 #38 lut +n203 6 2 0 0 2 #38 lut +n202 6 2 0 0 16 #38 lut +n201 6 2 0 0 13 #38 lut +n200 6 2 0 0 5 #38 lut +n198 6 2 0 0 17 #38 lut +n249 6 2 0 0 3 #38 lut +n197 6 2 0 0 9 #38 lut +n627 5 3 0 0 0 #39 lut +n626 5 3 0 0 17 #39 lut +n625 5 3 0 0 2 #39 lut +n623 5 3 0 0 15 #39 lut +n620 5 3 0 0 6 #39 lut +n619 5 3 0 0 4 #39 lut +n606 5 3 0 0 8 #39 lut +n605 5 3 0 0 5 #39 lut +n212 5 3 0 0 9 #39 lut +n624 5 3 0 0 13 #39 lut +n325 5 3 0 0 12 #39 lut +n26 5 3 0 0 1 #39 lut +n501 2 3 0 0 2 #40 lut +n837 2 3 0 0 13 #40 lut +n577 2 3 0 0 8 #40 lut +n499 2 3 0 0 0 #40 lut +n498 2 3 0 0 4 #40 lut +n497 2 3 0 0 4 #40 lut +n494 2 3 0 0 5 #40 lut +n227 2 3 0 0 7 #40 lut +n495 2 3 0 0 3 #40 lut +n222 2 3 0 0 9 #40 lut +n24 2 3 0 0 3 #40 lut +n634 3 7 0 0 0 #41 lut +n633 3 7 0 0 6 #41 lut +n631 3 7 0 0 4 #41 lut +n630 3 7 0 0 2 #41 lut +n226 3 7 0 0 8 #41 lut +n223 3 7 0 0 9 #41 lut +n151 3 7 0 0 7 #41 lut +n507 3 7 0 0 12 #41 lut +n143 3 7 0 0 13 #41 lut +n635 3 7 0 0 4 #41 lut +n141 3 7 0 0 5 #41 lut +n259 7 4 0 0 0 #42 lut +n28 7 4 0 0 3 #42 lut +n250 7 4 0 0 9 #42 lut +n75 7 4 0 0 1 #42 lut +n257 7 4 0 0 14 #42 lut +n251 7 4 0 0 4 #42 lut +n42 7 4 0 0 5 #42 lut +n245 7 4 0 0 17 #42 lut +n258 7 4 0 0 2 #42 lut +n252 7 4 0 0 5 #42 lut +n253 7 4 0 0 4 #42 lut +n255 7 4 0 0 15 #42 lut +n82 7 4 0 0 6 #42 lut +n256 7 4 0 0 13 #42 lut +n480 5 9 0 0 0 #43 lut +n479 5 9 0 0 4 #43 lut +n478 5 9 0 0 6 #43 lut +n476 5 9 0 0 17 #43 lut +n474 5 9 0 0 13 #43 lut +n471 5 9 0 0 7 #43 lut +n469 5 9 0 0 7 #43 lut +n477 5 9 0 0 2 #43 lut +n360 5 9 0 0 16 #43 lut +n481 5 9 0 0 10 #43 lut +n273 5 9 0 0 5 #43 lut +n470 5 9 0 0 8 #43 lut +n262 5 9 0 0 9 #43 lut +n449 9 7 0 0 6 #44 lut +n444 9 7 0 0 10 #44 lut +n435 9 7 0 0 0 #44 lut +n434 9 7 0 0 6 #44 lut +n437 9 7 0 0 2 #44 lut +n424 9 7 0 0 4 #44 lut +n440 9 7 0 0 8 #44 lut +n388 9 7 0 0 16 #44 lut +n271 9 7 0 0 17 #44 lut +n438 9 7 0 0 7 #44 lut +n269 9 7 0 0 9 #44 lut +n87 9 7 0 0 11 #44 lut +n387 8 8 0 0 4 #45 lut +n377 8 8 0 0 4 #45 lut +n284 8 8 0 0 0 #45 lut +n281 8 8 0 0 6 #45 lut +n279 8 8 0 0 5 #45 lut +n381 8 8 0 0 6 #45 lut +n277 8 8 0 0 17 #45 lut +n278 8 8 0 0 15 #45 lut +n265 8 8 0 0 2 #45 lut +n289 8 8 0 0 9 #45 lut +n263 8 8 0 0 1 #45 lut +n105 8 8 0 0 3 #45 lut +o_6_ 9 3 0 0 16 #46 lut +n636 9 3 0 0 2 #46 lut +n320 9 3 0 0 17 #46 lut +n657 9 3 0 0 5 #46 lut +n644 9 3 0 0 2 #46 lut +n319 9 3 0 0 0 #46 lut +n318 9 3 0 0 7 #46 lut +n655 9 3 0 0 4 #46 lut +n317 9 3 0 0 6 #46 lut +n654 9 3 0 0 3 #46 lut +n316 9 3 0 0 9 #46 lut +n380 1 6 0 0 3 #47 lut +n326 1 6 0 0 6 #47 lut +n922 1 6 0 0 1 #47 lut +n324 1 6 0 0 7 #47 lut +n921 1 6 0 0 6 #47 lut +n323 1 6 0 0 2 #47 lut +n312 1 6 0 0 5 #47 lut +n569 1 6 0 0 4 #47 lut +n322 1 6 0 0 4 #47 lut +n296 1 6 0 0 17 #47 lut +n568 1 6 0 0 5 #47 lut +n321 1 6 0 0 9 #47 lut +n282 1 6 0 0 0 #47 lut +n850 6 7 0 0 7 #48 lut +n847 6 7 0 0 17 #48 lut +n514 6 7 0 0 4 #48 lut +n848 6 7 0 0 6 #48 lut +n510 6 7 0 0 4 #48 lut +n506 6 7 0 0 0 #48 lut +n505 6 7 0 0 2 #48 lut +n515 6 7 0 0 6 #48 lut +n502 6 7 0 0 5 #48 lut +n446 6 7 0 0 1 #48 lut +n400 6 7 0 0 9 #48 lut +n104 7 8 0 0 13 #49 lut +n103 7 8 0 0 3 #49 lut +n101 7 8 0 0 7 #49 lut +n100 7 8 0 0 6 #49 lut +n98 7 8 0 0 4 #49 lut +n95 7 8 0 0 2 #49 lut +n94 7 8 0 0 8 #49 lut +n418 7 8 0 0 9 #49 lut +n106 7 8 0 0 9 #49 lut +n93 7 8 0 0 0 #49 lut +n102 7 8 0 0 17 #49 lut +n89 7 8 0 0 5 #49 lut +n433 8 5 0 0 7 #50 lut +n430 8 5 0 0 4 #50 lut +n427 8 5 0 0 4 #50 lut +n425 8 5 0 0 9 #50 lut +n429 8 5 0 0 6 #50 lut +n351 8 5 0 0 5 #50 lut +n428 8 5 0 0 5 #50 lut +n376 8 5 0 0 2 #50 lut +n350 8 5 0 0 3 #50 lut +n432 8 5 0 0 8 #50 lut +n341 8 5 0 0 0 #50 lut +n917 5 6 0 0 3 #51 lut +n918 5 6 0 0 4 #51 lut +n840 5 6 0 0 2 #51 lut +n621 5 6 0 0 13 #51 lut +n677 5 6 0 0 2 #51 lut +n586 5 6 0 0 3 #51 lut +n916 5 6 0 0 0 #51 lut +n513 5 6 0 0 17 #51 lut +n512 5 6 0 0 15 #51 lut +n511 5 6 0 0 9 #51 lut +n622 5 6 0 0 5 #51 lut +n63 5 6 0 0 14 #51 lut +o_1_ 7 1 0 0 14 #52 lut +n519 7 1 0 0 9 #52 lut +n149 7 1 0 0 15 #52 lut +n45 7 1 0 0 5 #52 lut +n147 7 1 0 0 13 #52 lut +n43 7 1 0 0 4 #52 lut +n40 7 1 0 0 0 #52 lut +n50 7 1 0 0 5 #52 lut +n37 7 1 0 0 4 #52 lut +n36 7 1 0 0 3 #52 lut +n592 7 1 0 0 17 #52 lut +n33 7 1 0 0 2 #52 lut +n661 1 3 0 0 2 #53 lut +n658 1 3 0 0 4 #53 lut +n571 1 3 0 0 0 #53 lut +n563 1 3 0 0 8 #53 lut +n562 1 3 0 0 7 #53 lut +n665 1 3 0 0 3 #53 lut +n561 1 3 0 0 5 #53 lut +n664 1 3 0 0 4 #53 lut +n560 1 3 0 0 6 #53 lut +n559 1 3 0 0 9 #53 lut +n776 4 4 0 0 2 #54 lut +n775 4 4 0 0 12 #54 lut +n773 4 4 0 0 6 #54 lut +n772 4 4 0 0 13 #54 lut +n771 4 4 0 0 15 #54 lut +n770 4 4 0 0 0 #54 lut +n769 4 4 0 0 4 #54 lut +n767 4 4 0 0 4 #54 lut +n609 4 4 0 0 9 #54 lut +n766 4 4 0 0 5 #54 lut +n610 4 4 0 0 8 #54 lut +n441 4 4 0 0 1 #54 lut +n651 4 3 0 0 0 #55 lut +n650 4 3 0 0 3 #55 lut +n617 4 3 0 0 17 #55 lut +n616 4 3 0 0 15 #55 lut +n823 4 3 0 0 5 #55 lut +n615 4 3 0 0 9 #55 lut +n613 4 3 0 0 4 #55 lut +n608 4 3 0 0 3 #55 lut +n567 4 3 0 0 2 #55 lut +n618 4 3 0 0 6 #55 lut +n566 4 3 0 0 4 #55 lut +n669 2 4 0 0 9 #56 lut +n668 2 4 0 0 17 #56 lut +n184 2 4 0 0 13 #56 lut +n183 2 4 0 0 14 #56 lut +n181 2 4 0 0 2 #56 lut +n836 2 4 0 0 5 #56 lut +n186 2 4 0 0 6 #56 lut +n173 2 4 0 0 8 #56 lut +n185 2 4 0 0 0 #56 lut +n172 2 4 0 0 4 #56 lut +n127 2 4 0 0 15 #56 lut +n880 2 7 0 0 6 #57 lut +n810 2 7 0 0 15 #57 lut +n448 2 7 0 0 10 #57 lut +n811 2 7 0 0 8 #57 lut +n681 2 7 0 0 9 #57 lut +n447 2 7 0 0 8 #57 lut +n392 2 7 0 0 4 #57 lut +n534 2 7 0 0 6 #57 lut +n391 2 7 0 0 0 #57 lut +n390 2 7 0 0 2 #57 lut +n784 5 8 0 0 13 #58 lut +n753 5 8 0 0 7 #58 lut +n645 5 8 0 0 2 #58 lut +n685 5 8 0 0 9 #58 lut +n74 5 8 0 0 8 #58 lut +n80 5 8 0 0 17 #58 lut +n67 5 8 0 0 5 #58 lut +n378 5 8 0 0 0 #58 lut +n66 5 8 0 0 4 #58 lut +n65 5 8 0 0 6 #58 lut +n740 3 9 0 0 7 #59 lut +n723 3 9 0 0 9 #59 lut +n741 3 9 0 0 8 #59 lut +n715 3 9 0 0 12 #59 lut +n453 3 9 0 0 4 #59 lut +n452 3 9 0 0 5 #59 lut +n357 3 9 0 0 0 #59 lut +n356 3 9 0 0 6 #59 lut +n354 3 9 0 0 2 #59 lut +n358 3 9 0 0 4 #59 lut +n267 3 9 0 0 13 #59 lut +n649 8 4 0 0 13 #60 lut +n765 8 4 0 0 3 #60 lut +n648 8 4 0 0 0 #60 lut +n359 8 4 0 0 6 #60 lut +n353 8 4 0 0 2 #60 lut +n755 8 4 0 0 8 #60 lut +n352 8 4 0 0 4 #60 lut +n647 8 4 0 0 7 #60 lut +n348 8 4 0 0 8 #60 lut +n760 8 4 0 0 9 #60 lut +n344 8 4 0 0 5 #60 lut +n889 7 3 0 0 2 #61 lut +n892 7 3 0 0 2 #61 lut +n762 7 3 0 0 9 #61 lut +n175 7 3 0 0 17 #61 lut +n891 7 3 0 0 3 #61 lut +n72 7 3 0 0 15 #61 lut +o_0_ 7 3 0 0 14 #61 lut +n888 7 3 0 0 4 #61 lut +n30 7 3 0 0 5 #61 lut +n27 7 3 0 0 0 #61 lut +n23 7 3 0 0 6 #61 lut +n861 3 3 0 0 0 #62 lut +n774 3 3 0 0 9 #62 lut +n768 3 3 0 0 15 #62 lut +n691 3 3 0 0 13 #62 lut +n678 3 3 0 0 4 #62 lut +n659 3 3 0 0 2 #62 lut +n607 3 3 0 0 4 #62 lut +n855 3 3 0 0 5 #62 lut +n777 3 3 0 0 17 #62 lut +n62 3 3 0 0 6 #62 lut +n788 9 5 0 0 8 #63 lut +n787 9 5 0 0 9 #63 lut +n643 9 5 0 0 2 #63 lut +n642 9 5 0 0 4 #63 lut +n638 9 5 0 0 6 #63 lut +n90 9 5 0 0 0 #63 lut +n641 9 5 0 0 4 #63 lut +n56 9 5 0 0 6 #63 lut +n637 9 5 0 0 5 #63 lut +n52 9 5 0 0 7 #63 lut +n925 1 5 0 0 3 #64 lut +n795 1 5 0 0 8 #64 lut +n924 1 5 0 0 2 #64 lut +n794 1 5 0 0 9 #64 lut +n386 1 5 0 0 2 #64 lut +n385 1 5 0 0 5 #64 lut +n307 1 5 0 0 0 #64 lut +n306 1 5 0 0 6 #64 lut +n576 1 5 0 0 4 #64 lut +n303 1 5 0 0 7 #64 lut +n824 4 6 0 0 2 #65 lut +n813 4 6 0 0 9 #65 lut +n670 4 6 0 0 3 #65 lut +n384 4 6 0 0 5 #65 lut +n132 4 6 0 0 4 #65 lut +n443 4 6 0 0 4 #65 lut +n92 4 6 0 0 6 #65 lut +n814 4 6 0 0 17 #65 lut +n177 4 6 0 0 0 #65 lut +n60 4 6 0 0 15 #65 lut +n817 1 7 0 0 8 #66 lut +n672 1 7 0 0 3 #66 lut +n671 1 7 0 0 2 #66 lut +n816 1 7 0 0 9 #66 lut +n673 1 7 0 0 4 #66 lut +n530 1 7 0 0 2 #66 lut +n834 1 7 0 0 5 #66 lut +n301 1 7 0 0 13 #66 lut +n300 1 7 0 0 0 #66 lut +n299 1 7 0 0 15 #66 lut +n830 4 1 0 0 9 #67 lut +n653 4 1 0 0 0 #67 lut +n614 4 1 0 0 4 #67 lut +n611 4 1 0 0 4 #67 lut +n585 4 1 0 0 3 #67 lut +n652 4 1 0 0 5 #67 lut +n496 4 1 0 0 13 #67 lut +n539 4 1 0 0 7 #67 lut +n396 4 1 0 0 2 #67 lut +n155 4 1 0 0 17 #67 lut +n781 8 3 0 0 0 #68 lut +n841 8 3 0 0 9 #68 lut +n646 8 3 0 0 8 #68 lut +n640 8 3 0 0 15 #68 lut +n493 8 3 0 0 2 #68 lut +n362 8 3 0 0 3 #68 lut +n345 8 3 0 0 2 #68 lut +n160 8 3 0 0 13 #68 lut +n656 8 3 0 0 4 #68 lut +n58 8 3 0 0 5 #68 lut +n900 7 5 0 0 8 #69 lut +n887 7 5 0 0 7 #69 lut +n885 7 5 0 0 9 #69 lut +n883 7 5 0 0 6 #69 lut +n890 7 5 0 0 0 #69 lut +n487 7 5 0 0 2 #69 lut +n368 7 5 0 0 5 #69 lut +n335 7 5 0 0 4 #69 lut +n179 7 5 0 0 3 #69 lut +n34 7 5 0 0 2 #69 lut +n599 6 1 0 0 3 #70 lut +n603 6 1 0 0 4 #70 lut +n408 6 1 0 0 7 #70 lut +n403 6 1 0 0 13 #70 lut +n597 6 1 0 0 2 #70 lut +n402 6 1 0 0 5 #70 lut +n873 6 1 0 0 12 #70 lut +n340 6 1 0 0 2 #70 lut +n575 6 1 0 0 8 #70 lut +n211 6 1 0 0 9 #70 lut +n190 6 1 0 0 0 #70 lut +n667 1 1 0 0 0 #71 lut +n660 1 1 0 0 2 #71 lut +n593 1 1 0 0 5 #71 lut +n584 1 1 0 0 3 #71 lut +n594 1 1 0 0 4 #71 lut +n581 1 1 0 0 8 #71 lut +n525 1 1 0 0 4 #71 lut +n315 1 1 0 0 7 #71 lut +n314 1 1 0 0 6 #71 lut +n313 1 1 0 0 9 #71 lut +n878 9 8 0 0 6 #72 lut +n875 9 8 0 0 2 #72 lut +n874 9 8 0 0 0 #72 lut +n872 9 8 0 0 4 #72 lut +n389 9 8 0 0 8 #72 lut +n383 9 8 0 0 9 #72 lut +n97 9 8 0 0 5 #72 lut +n88 9 8 0 0 8 #72 lut +n879 9 8 0 0 7 #72 lut +n86 9 8 0 0 6 #72 lut +n451 9 9 0 0 8 #73 lut +n632 9 9 0 0 5 #73 lut +n450 9 9 0 0 7 #73 lut +n445 9 9 0 0 6 #73 lut +n436 9 9 0 0 9 #73 lut +n536 2 2 0 0 17 #74 lut +n535 2 2 0 0 9 #74 lut +n169 2 2 0 0 4 #74 lut +n528 2 2 0 0 13 #74 lut +n125 2 2 0 0 0 #74 lut +n116 2 2 0 0 5 #74 lut +n544 2 2 0 0 7 #74 lut +n167 2 2 0 0 2 #74 lut +n115 2 2 0 0 5 #74 lut +n110 2 2 0 0 6 #74 lut +n473 2 2 0 0 1 #74 lut +n109 2 2 0 0 4 #74 lut +n639 9 4 0 0 5 #75 lut +n798 9 4 0 0 6 #75 lut +n629 9 4 0 0 9 #75 lut +n361 9 4 0 0 15 #75 lut +n349 9 4 0 0 17 #75 lut +n527 8 2 0 0 6 #76 lut +n254 8 2 0 0 17 #76 lut +n176 8 2 0 0 15 #76 lut +n76 8 2 0 0 9 #76 lut +n923 1 9 0 0 17 #77 lut +n268 1 9 0 0 19 #77 lut +out:o_3_ 3 0 0 4 0 #78 outpad +out:o_4_ 10 8 0 7 0 #79 outpad +out:o_5_ 3 0 0 3 0 #80 outpad +out:o_7_ 5 0 0 5 0 #81 outpad +out:o_2_ 8 0 0 3 0 #82 outpad +out:o_6_ 10 3 0 6 0 #83 outpad +out:o_1_ 7 0 0 5 0 #84 outpad +out:o_0_ 7 0 0 2 0 #85 outpad +i_0_ 5 0 0 0 0 #86 inpad +i_10_ 5 0 0 1 0 #87 inpad +i_11_ 6 0 0 0 0 #88 inpad +i_12_ 5 0 0 3 0 #89 inpad +i_13_ 4 0 0 1 0 #90 inpad +i_1_ 3 0 0 0 0 #91 inpad +i_2_ 5 0 0 2 0 #92 inpad +i_3_ 4 0 0 3 0 #93 inpad +i_4_ 5 0 0 6 0 #94 inpad +i_5_ 5 10 0 0 0 #95 inpad +i_6_ 5 0 0 4 0 #96 inpad +i_7_ 4 0 0 6 0 #97 inpad +i_8_ 5 0 0 7 0 #98 inpad +i_9_ 6 0 0 4 0 #99 inpad diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt index 24c0c75e502..20a184ec627 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/task_list.txt @@ -33,6 +33,7 @@ regression_tests/vtr_reg_strong/strong_equivalent_sites regression_tests/vtr_reg_strong/strong_fc_abs regression_tests/vtr_reg_strong/strong_fix_clusters regression_tests/vtr_reg_strong/strong_fix_pins_random +regression_tests/vtr_reg_strong/strong_flat_placement/read_write regression_tests/vtr_reg_strong/strong_flyover_wires regression_tests/vtr_reg_strong/strong_fpu_hard_block_arch regression_tests/vtr_reg_strong/strong_fracturable_luts diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong_odin/strong_sdc/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong_odin/strong_sdc/config/golden_results.txt index 93ad79df1cb..691c0cd8075 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong_odin/strong_sdc/config/golden_results.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong_odin/strong_sdc/config/golden_results.txt @@ -1,7 +1,7 @@ - arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/A.sdc 0.46 vpr 63.03 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64540 5 3 11 14 2 9 10 4 4 16 clb auto 24.3 MiB 0.01 22 30 9 14 7 63.0 MiB 0.00 0.00 0.814339 -2.77068 -0.814339 0.571 0.01 4.6237e-05 3.9054e-05 0.0002174 0.000180615 -1 -1 -1 -1 8 18 2 107788 107788 4794.78 299.674 0.02 0.00197825 0.00183539 564 862 -1 18 4 10 10 199 87 0.757297 0.571 -2.63894 -0.757297 0 0 5401.54 337.596 0.00 0.01 0.00 -1 -1 0.00 0.00215654 0.00203426 - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/B.sdc 0.51 vpr 62.91 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64424 5 3 11 14 2 9 10 4 4 16 clb auto 24.2 MiB 0.01 23 30 6 15 9 62.9 MiB 0.01 0.00 0.571 0 0 0.571 0.02 3.7988e-05 2.9784e-05 0.000252809 0.000212792 -1 -1 -1 -1 8 26 3 107788 107788 4794.78 299.674 0.03 0.00214308 0.00198029 564 862 -1 25 5 13 13 435 272 0.571 0.571 0 0 0 0 5401.54 337.596 0.00 0.01 0.00 -1 -1 0.00 0.00179325 0.00170005 - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/C.sdc 0.53 vpr 63.05 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64568 5 3 11 14 2 9 10 4 4 16 clb auto 24.3 MiB 0.01 20 30 10 18 2 63.1 MiB 0.00 0.00 0.645658 -2.18842 -0.645658 0.571 0.01 4.2928e-05 3.0736e-05 0.000257589 0.000202685 -1 -1 -1 -1 8 17 3 107788 107788 4794.78 299.674 0.01 0.00208504 0.00188215 564 862 -1 14 5 15 15 285 110 0.571526 0.571 -1.89284 -0.571526 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00184632 0.00172634 - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/D.sdc 0.57 vpr 62.89 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64396 5 3 11 14 2 9 10 4 4 16 clb auto 24.2 MiB 0.01 20 30 12 17 1 62.9 MiB 0.01 0.00 1.64534 -5.31677 -1.64534 0.571 0.01 5.3727e-05 3.88e-05 0.000288614 0.00022112 -1 -1 -1 -1 8 19 8 107788 107788 4794.78 299.674 0.05 0.00254374 0.00221143 564 862 -1 15 2 8 8 156 74 1.57153 0.571 -4.92067 -1.57153 0 0 5401.54 337.596 0.00 0.01 0.00 -1 -1 0.00 0.00180866 0.00171184 - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/E.sdc 0.51 vpr 62.98 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64496 5 3 11 14 2 9 10 4 4 16 clb auto 24.2 MiB 0.01 20 30 8 18 4 63.0 MiB 0.00 0.00 1.44871 -2.90839 -1.44871 0.571 0.01 3.8739e-05 2.8831e-05 0.000233335 0.000188434 -1 -1 -1 -1 8 33 10 107788 107788 4794.78 299.674 0.02 0.0025966 0.00229332 564 862 -1 19 2 11 11 275 141 1.39454 0.571 -2.72425 -1.39454 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00164291 0.00155522 - k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/F.sdc 0.51 vpr 62.82 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-11852-g026644d7f-dirty release IPO VTR_ASSERT_LEVEL=2 GNU 9.4.0 on Linux-4.15.0-213-generic x86_64 2024-11-21T16:04:00 betzgrp-wintermute.eecg.utoronto.ca /home/elgamma8/research/temp/temp2/vtr-verilog-to-routing 64328 5 3 11 14 2 9 10 4 4 16 clb auto 24.0 MiB 0.01 20 110 34 46 30 62.8 MiB 0.00 0.00 0.145339 0 0 0.571 0.01 3.5398e-05 2.9142e-05 0.000512135 0.000417096 -1 -1 -1 -1 8 25 4 107788 107788 4794.78 299.674 0.02 0.00232795 0.00209925 564 862 -1 36 5 15 15 690 511 0.0724097 0.571 0 0 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00186912 0.00175661 +arch circuit script_params vtr_flow_elapsed_time vtr_max_mem_stage vtr_max_mem error odin_synth_time max_odin_mem parmys_synth_time max_parmys_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_status vpr_revision vpr_build_info vpr_compiler vpr_compiled hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_mem pack_time placed_wirelength_est total_swap accepted_swap rejected_swap aborted_swap place_mem place_time place_quench_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est placed_geomean_nonvirtual_intradomain_critical_path_delay_est place_delay_matrix_lookup_time place_quench_timing_analysis_time place_quench_sta_time place_total_timing_analysis_time place_total_sta_time ap_mem ap_time ap_full_legalizer_mem ap_full_legalizer_time min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time min_chan_width_total_timing_analysis_time min_chan_width_total_sta_time crit_path_num_rr_graph_nodes crit_path_num_rr_graph_edges crit_path_collapsed_nodes crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay geomean_nonvirtual_intradomain_critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile router_lookahead_computation_time crit_path_route_time crit_path_create_rr_graph_time crit_path_create_intra_cluster_rr_graph_time crit_path_tile_lookahead_computation_time crit_path_router_lookahead_computation_time crit_path_total_timing_analysis_time crit_path_total_sta_time +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/A.sdc 0.27 vpr 65.23 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66800 5 3 11 14 2 9 10 4 4 16 clb auto 26.8 MiB 0.00 22 30 9 11 10 65.2 MiB 0.00 0.00 0.814658 -2.77132 -0.814658 0.571 0.01 2.74e-05 2.1395e-05 0.000172845 0.000138846 -1 -1 -1 -1 8 18 2 107788 107788 4794.78 299.674 0.01 0.00118453 0.00106116 564 862 -1 18 4 13 13 259 109 0.739641 0.571 -2.62128 -0.739641 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00100541 0.000920616 +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/B.sdc 0.28 vpr 65.03 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66592 5 3 11 14 2 9 10 4 4 16 clb auto 26.6 MiB 0.00 24 30 5 16 9 65.0 MiB 0.00 0.00 0.571 0 0 0.571 0.01 2.4711e-05 1.9521e-05 0.000161855 0.000132213 -1 -1 -1 -1 8 21 3 107788 107788 4794.78 299.674 0.01 0.00116147 0.00104598 564 862 -1 23 3 16 16 451 224 0.571 0.571 0 0 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.000962828 0.000887085 +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/C.sdc 0.28 vpr 65.03 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66592 5 3 11 14 2 9 10 4 4 16 clb auto 26.5 MiB 0.00 21 30 12 15 3 65.0 MiB 0.00 0.00 0.646297 -2.19065 -0.646297 0.571 0.01 4.7051e-05 3.5839e-05 0.000229917 0.000178741 -1 -1 -1 -1 8 19 3 107788 107788 4794.78 299.674 0.01 0.00133474 0.00116551 564 862 -1 18 8 28 28 448 186 0.685959 0.571 -2.00816 -0.685959 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00118731 0.00104896 +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/D.sdc 0.28 vpr 65.16 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66720 5 3 11 14 2 9 10 4 4 16 clb auto 26.6 MiB 0.00 20 30 13 13 4 65.2 MiB 0.00 0.00 1.6463 -5.31997 -1.6463 0.571 0.01 3.249e-05 2.3621e-05 0.00021121 0.000155903 -1 -1 -1 -1 8 17 8 107788 107788 4794.78 299.674 0.01 0.0014969 0.00126163 564 862 -1 15 8 24 24 354 155 1.57153 0.571 -4.9011 -1.57153 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00121937 0.00106888 +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/E.sdc 0.27 vpr 65.28 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66848 5 3 11 14 2 9 10 4 4 16 clb auto 26.8 MiB 0.00 20 30 8 18 4 65.3 MiB 0.00 0.00 1.44871 -2.90966 -1.44871 0.571 0.01 3.4821e-05 2.5953e-05 0.000217795 0.00017136 -1 -1 -1 -1 8 33 8 107788 107788 4794.78 299.674 0.01 0.00152357 0.00129813 564 862 -1 17 3 11 11 260 128 1.39454 0.571 -2.70659 -1.39454 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00104042 0.000952271 +k6_N10_mem32K_40nm.xml multiclock.blif common_-sdc_file_sdc/samples/F.sdc 0.27 vpr 65.28 MiB -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 5 0 0 success v8.0.0-12031-g8839b394a release VTR_ASSERT_LEVEL=3 GNU 13.2.0 on Linux-6.8.0-49-generic x86_64 2025-01-23T11:44:53 srivatsan-Precision-Tower-5810 /home/alex/vtr-verilog-to-routing/vtr_flow/tasks 66848 5 3 11 14 2 9 10 4 4 16 clb auto 26.8 MiB 0.00 21 90 29 40 21 65.3 MiB 0.00 0.00 0.146042 0 0 0.571 0.01 2.4899e-05 1.9685e-05 0.000349955 0.000277335 -1 -1 -1 -1 8 20 2 107788 107788 4794.78 299.674 0.01 0.00137572 0.00121296 564 862 -1 19 4 12 12 252 111 0.0892558 0.571 0 0 0 0 5401.54 337.596 0.00 0.00 0.00 -1 -1 0.00 0.00105707 0.000965343 From 42756cd4124fa8b237c7dd2652447b0626eadcce Mon Sep 17 00:00:00 2001 From: AlexandreSinger Date: Tue, 28 Jan 2025 10:07:54 -0500 Subject: [PATCH 2/2] [APPack] Updated Comments Updated comments and some variables names as per VB review. --- vpr/src/base/load_flat_place.cpp | 31 +++++++++++++++++-- vpr/src/base/load_flat_place.h | 4 +-- vpr/src/base/vpr_context.h | 4 +-- vpr/src/pack/greedy_candidate_selector.h | 13 +++++--- vpr/src/place/initial_placement.cpp | 3 ++ .../constraints/old_placement.fplace | 7 +++++ 6 files changed, 52 insertions(+), 10 deletions(-) diff --git a/vpr/src/base/load_flat_place.cpp b/vpr/src/base/load_flat_place.cpp index 2a990facf0c..02eafccdda0 100644 --- a/vpr/src/base/load_flat_place.cpp +++ b/vpr/src/base/load_flat_place.cpp @@ -21,6 +21,26 @@ #include "vtr_assert.h" #include "vtr_log.h" #include "vtr_vector_map.h" +#include "vtr_version.h" + +/** + * @brief Prints the header for the flat placement file. This includes helpful + * information on how to read the file and when it was generated. + * + * @param fp + * File pointer to the file the cluster is printed to. + */ +static void print_flat_placement_file_header(FILE* fp) { + fprintf(fp, "# Flat Placement File\n"); + fprintf(fp, "# Auto-generated by VPR %s\n", + vtr::VERSION); + fprintf(fp, "# Created: %s\n", + vtr::BUILD_TIMESTAMP); + fprintf(fp, "#\n"); + fprintf(fp, "# This file prints the following information for each atom in the netlist:\n"); + fprintf(fp, "# # \n"); + fprintf(fp, "\n"); +} /** * @brief Prints flat placement file entries for the atoms in one placed @@ -76,6 +96,9 @@ void write_flat_placement(const char* flat_place_file_path, // Create a file in write mode for the flat placement. FILE* fp = fopen(flat_place_file_path, "w"); + // Add a header to the flat placement file. + print_flat_placement_file_header(fp); + // For each cluster, write out the atoms in the cluster at this cluster's // location. for (ClusterBlockId iblk : cluster_netlist.blocks()) { @@ -181,7 +204,7 @@ void log_flat_placement_reconstruction_info( const FlatPlacementInfo& flat_placement_info, const vtr::vector_map& block_locs, const vtr::vector>& atoms_lookup, - const AtomLookup& lookup, + const AtomLookup& cluster_of_atom_lookup, const AtomNetlist& atom_netlist, const ClusteredNetlist& clustered_netlist) { // Go through each cluster and see how many clusters have atoms that @@ -217,6 +240,8 @@ void log_flat_placement_reconstruction_info( // If the atom's flat placement more than half a block in any // direction from the flat placement centroid, then it does not // want to be in this cluster. + // FIXME: This should take into account large blocks somehow, just + // being 0.5 tiles away may not be sufficient. if (std::abs(centroid_x - flat_placement_info.blk_x_pos[atom_blk_id]) > 0.5f || std::abs(centroid_y - flat_placement_info.blk_y_pos[atom_blk_id]) > 0.5f || std::abs(centroid_layer - flat_placement_info.blk_layer[atom_blk_id]) > 0.5f || @@ -245,10 +270,12 @@ void log_flat_placement_reconstruction_info( int blk_layer = flat_placement_info.blk_layer[atom_blk_id]; // Get the (x, y, layer) position of the cluster that contains this block. - ClusterBlockId atom_clb_id = lookup.atom_clb(atom_blk_id); + ClusterBlockId atom_clb_id = cluster_of_atom_lookup.atom_clb(atom_blk_id); const t_block_loc& clb_loc = block_locs[atom_clb_id]; // Compute the distance between these two positions. + // FIXME: This will overreport large blocks. This should really be + // the distance outside of the tile you want to be placed in. float dx = blk_x - clb_loc.loc.x; float dy = blk_y - clb_loc.loc.y; float dlayer = blk_layer - clb_loc.loc.layer; diff --git a/vpr/src/base/load_flat_place.h b/vpr/src/base/load_flat_place.h index 940c55cadbf..73252034c00 100644 --- a/vpr/src/base/load_flat_place.h +++ b/vpr/src/base/load_flat_place.h @@ -72,7 +72,7 @@ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch); * The location of each cluster in the netlist. * @param atoms_lookup * A lookup between each cluster and the atoms it contains. - * @param lookup + * @param cluster_of_atom_lookup * A lookup between each atom and the cluster that contains it. * @param atom_netlist * The netlist of atoms the flat placement was over. @@ -84,7 +84,7 @@ void log_flat_placement_reconstruction_info( const FlatPlacementInfo& flat_placement_info, const vtr::vector_map& block_locs, const vtr::vector>& atoms_lookup, - const AtomLookup& lookup, + const AtomLookup& cluster_of_atom_lookup, const AtomNetlist& atom_netlist, const ClusteredNetlist& clustered_netlist); diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index ccfbf549bb4..d8d7c99b958 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -81,8 +81,8 @@ struct AtomContext : public Context { /// @brief Mappings to/from the Atom Netlist to physically described .blif models AtomLookup lookup; - /// @brief Placement information on each atom known before packing and - /// placement. + /// @brief Placement information on each atom known (from a file or another + /// algorithm) before packing and the cluster-level placement. FlatPlacementInfo flat_placement_info; }; diff --git a/vpr/src/pack/greedy_candidate_selector.h b/vpr/src/pack/greedy_candidate_selector.h index edbd53806ea..2ef43fbf940 100644 --- a/vpr/src/pack/greedy_candidate_selector.h +++ b/vpr/src/pack/greedy_candidate_selector.h @@ -405,7 +405,7 @@ class GreedyCandidateSelector { /** * @brief Add molecules that are "close" to the seed molecule in the flat - * placement tot he list of feasible blocks. + * placement to the list of feasible blocks. */ void add_cluster_molecule_candidates_by_flat_placement( ClusterGainStats& cluster_gain_stats, @@ -547,10 +547,15 @@ class GreedyCandidateSelector { * flat placement information for clustering. */ struct FlatTileMoleculeList { - // A list of molecules in the undefined sub-tile at this tile. - std::vector undefined_sub_tile_mols; - // A list of molecule in each sub_tile at this tile. + // A list of molecule in each sub_tile at this tile. Where each index + // in the first dimension is the subtile [0, num_sub_tiles - 1]. std::vector> sub_tile_mols; + + // A list of molecules in the undefined sub-tile at this tile. An + // undefined sub-tile is the location molecules go when the sub-tile + // in the flat placement is unspecified for this atom. + // Currently unused, but can be used to support that feature. + std::vector undefined_sub_tile_mols; }; /// @brief Pre-computed information on the flat placement. Lists all of the diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp index f999594be4b..c3a1579b775 100644 --- a/vpr/src/place/initial_placement.cpp +++ b/vpr/src/place/initial_placement.cpp @@ -560,6 +560,9 @@ static bool try_centroid_placement(const t_pl_macro& pl_macro, find_centroid_loc_from_flat_placement(pl_macro, centroid_loc, flat_placement_info); // If a centroid could not be found, or if the tile is not legal // fall-back on the centroid of the neighbor blocks of this block. + // TODO: This may be more disruptive than needed for flat placement + // reconstruction. Ideally, we would search for a new tile + // location near the flat placement centroid. if (!is_loc_on_chip({centroid_loc.x, centroid_loc.y, centroid_loc.layer}) || !is_loc_legal(centroid_loc, pr, block_type)) { unplaced_blocks_to_update_their_score = find_centroid_loc(pl_macro, centroid_loc, blk_loc_registry); diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace index 357cb8fe79e..6104318972c 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_flat_placement/read_write/constraints/old_placement.fplace @@ -1,3 +1,10 @@ +# Flat Placement File +# Auto-generated by VPR 9.0.0-dev+v8.0.0-12075-g53e90e62b-dirty +# Created: 2025-01-28T09:59:25 +# +# This file prints the following information for each atom in the netlist: +# # + n523 6 8 0 0 3 #0 lut n522 6 8 0 0 5 #0 lut n520 6 8 0 0 2 #0 lut