diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 18306db87a7..2ee9cb4b5d2 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -565,6 +565,9 @@ void SetupPackerOpts(const t_options& Options, PackerOpts->alpha = Options.alpha_clustering; PackerOpts->beta = Options.beta_clustering; PackerOpts->pack_verbosity = Options.pack_verbosity; + PackerOpts->external_attraction_file = Options.external_attraction_file; + PackerOpts->external_attraction_default_weight = 0.5; /* DEFAULT: Experiment now */ + PackerOpts->external_attraction_default_value = -1; PackerOpts->enable_pin_feasibility_filter = Options.enable_clustering_pin_feasibility_filter; PackerOpts->balance_block_type_utilization = Options.balance_block_type_utilization; PackerOpts->target_external_pin_util = Options.target_external_pin_util; diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp index 61f1bf772c3..3a08b855d18 100644 --- a/vpr/src/base/ShowSetup.cpp +++ b/vpr/src/base/ShowSetup.cpp @@ -737,6 +737,12 @@ static void ShowAnalysisOpts(const t_analysis_opts& AnalysisOpts) { } static void ShowPackerOpts(const t_packer_opts& PackerOpts) { + if (PackerOpts.external_attraction_file.empty()) { + VTR_LOG("external_attraction_file: None used\n"); + } else { + VTR_LOG("external_attraction_file: %s\n", PackerOpts.external_attraction_file.c_str()); + } + VTR_LOG("PackerOpts.allow_unrelated_clustering: "); if (PackerOpts.allow_unrelated_clustering == e_unrelated_clustering::ON) { VTR_LOG("true\n"); diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp index e72115af766..b339ae96a88 100644 --- a/vpr/src/base/read_options.cpp +++ b/vpr/src/base/read_options.cpp @@ -1807,6 +1807,11 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg .default_value("2") .show_in(argparse::ShowIn::HELP_ONLY); + pack_grp.add_argument(args.external_attraction_file, "--external_attraction_file") + .help("Whether to use external attraction data from a file") + .default_value("") + .show_in(argparse::ShowIn::HELP_ONLY); + pack_grp.add_argument(args.use_attraction_groups, "--use_attraction_groups") .help("Whether attraction groups are used to make it easier to pack primitives in the same floorplan region together.") .default_value("on") diff --git a/vpr/src/base/read_options.h b/vpr/src/base/read_options.h index 90f82ac07fb..335b97acbf7 100644 --- a/vpr/src/base/read_options.h +++ b/vpr/src/base/read_options.h @@ -98,6 +98,7 @@ struct t_options { argparse::ArgValue pack_feasible_block_array_size; argparse::ArgValue> pack_high_fanout_threshold; argparse::ArgValue pack_verbosity; + argparse::ArgValue external_attraction_file; argparse::ArgValue use_attraction_groups; argparse::ArgValue pack_num_moves; argparse::ArgValue pack_move_type; diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index c7b2fc97e06..1c7863e2386 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -347,6 +347,18 @@ struct ClusteringHelperContext : public Context { // A vector of unordered_sets of AtomBlockIds that are inside each clustered block [0 .. num_clustered_blocks-1] // unordered_set for faster insertion/deletion during the iterative improvement process of packing vtr::vector> atoms_lookup; + + // 2D vector to store the external attraction data from one atom to another, default set to slight repulsion in SetupPackerOpts() + // external_atom_attraction_data[src][dst]: + // The attraction of putting dst atom to src atom + std::unordered_map> external_atom_attraction_data; + + // A vector of ordered_sets of AtomBlockIds that are inside each clustered block during the time of clustering + // This is used when we are clustering, hence the lookup map is not complete during the clustering algorithm. + // Each cluster contains all the atoms that are determined to be packed into the same cluster (there might be other atoms to be packed later) + // The data structure will be cleaned after the clustering stage to keep memory impact minimal + vtr::vector> incomplete_cluster_to_atoms_lookup; + ~ClusteringHelperContext() { delete[] primitives_list; } diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 5b6e4c52b2f..04ec80ee885 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -903,6 +903,9 @@ struct t_packer_opts { e_unrelated_clustering allow_unrelated_clustering; bool connection_driven; int pack_verbosity; + std::string external_attraction_file; + float external_attraction_default_weight; + float external_attraction_default_value; bool enable_pin_feasibility_filter; e_balance_block_type_util balance_block_type_utilization; std::vector target_external_pin_util; diff --git a/vpr/src/pack/cluster.cpp b/vpr/src/pack/cluster.cpp index 4f1382a990d..7fd660c97a8 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -148,6 +148,7 @@ std::map do_clustering(const t_packer_opts& pa auto& device_ctx = g_vpr_ctx.mutable_device(); auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); + const auto& cl_helper_ctx = g_vpr_ctx.cl_helper(); helper_ctx.enable_pin_feasibility_filter = packer_opts.enable_pin_feasibility_filter; helper_ctx.feasible_block_array_size = packer_opts.feasible_block_array_size; @@ -174,6 +175,12 @@ std::map do_clustering(const t_packer_opts& pa istart = nullptr; + // load external attraction data + load_external_attraction_data(packer_opts.external_attraction_file, verbosity); + + // clear up to data clustering decision (This should be a clean start for clustering) + helper_ctx.incomplete_cluster_to_atoms_lookup.clear(); + /* determine bound on cluster size and primitive input size */ helper_ctx.max_cluster_size = 0; max_pb_depth = 0; @@ -292,7 +299,8 @@ std::map do_clustering(const t_packer_opts& pa high_fanout_threshold, *timing_info, attraction_groups, - net_output_feeds_driving_block_input); + net_output_feeds_driving_block_input, + verbosity); helper_ctx.total_clb_num++; if (packer_opts.timing_driven) { @@ -304,6 +312,9 @@ std::map do_clustering(const t_packer_opts& pa cluster_stats.num_unrelated_clustering_attempts = 0; next_molecule = get_molecule_for_cluster(cluster_ctx.clb_nlist.block_pb(clb_index), attraction_groups, + cl_helper_ctx.external_atom_attraction_data, + packer_opts.external_attraction_default_weight, + packer_opts.external_attraction_default_value, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -350,6 +361,9 @@ std::map do_clustering(const t_packer_opts& pa clb_index, detailed_routing_stage, attraction_groups, + cl_helper_ctx.external_atom_attraction_data, + packer_opts.external_attraction_default_weight, + packer_opts.external_attraction_default_value, clb_inter_blk_nets, allow_unrelated_clustering, high_fanout_threshold, @@ -369,7 +383,7 @@ std::map do_clustering(const t_packer_opts& pa if (is_cluster_legal) { istart = save_cluster_routing_and_pick_new_seed(packer_opts, helper_ctx.total_clb_num, seed_atoms, num_blocks_hill_added, clustering_data.intra_lb_routing, seedindex, cluster_stats, router_data); - store_cluster_info_and_free(packer_opts, clb_index, logic_block_type, le_pb_type, le_count, clb_inter_blk_nets); + store_cluster_info_and_free(packer_opts, clb_index, logic_block_type, le_pb_type, le_count, clb_inter_blk_nets, verbosity); } else { free_data_and_requeue_used_mols_if_illegal(clb_index, savedseedindex, num_used_type_instances, helper_ctx.total_clb_num, seedindex); } @@ -386,6 +400,9 @@ std::map do_clustering(const t_packer_opts& pa //check_floorplan_regions(floorplan_regions_overfull); floorplan_regions_overfull = floorplan_constraints_regions_overfull(); + // clear up to data clustering decision (No one should use incomplete_cluster_to_atoms_lookup after this point) + helper_ctx.incomplete_cluster_to_atoms_lookup.clear(); + return num_used_type_instances; } diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 0e12305dc70..3fa3fa49be9 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -7,6 +7,10 @@ #include "vtr_math.h" #include "SetupGrid.h" +#include "pugixml.hpp" +#include "pugixml_util.hpp" +#include "read_xml_util.h" + /**********************************/ /* Global variables in clustering */ /**********************************/ @@ -427,10 +431,14 @@ void remove_molecule_from_pb_stats_candidates(t_pack_molecule* molecule, /* Add blk to list of feasible blocks sorted according to gain */ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, - std::map& gain, + const std::map& gain, t_pb* pb, + const ClusterBlockId cluster_index, int max_queue_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value) { int i, j; int num_molecule_failures = 0; @@ -460,12 +468,18 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, } } + float new_molecule_gain = get_molecule_gain(molecule, cluster_index, gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value, num_molecule_failures); + if (pb->pb_stats->num_feasible_blocks >= max_queue_size - 1) { /* maximum size for array, remove smallest gain element and sort */ - if (get_molecule_gain(molecule, gain, cluster_att_grp, attraction_groups, num_molecule_failures) > get_molecule_gain(pb->pb_stats->feasible_blocks[0], gain, cluster_att_grp, attraction_groups, num_molecule_failures)) { + if (new_molecule_gain > get_molecule_gain(pb->pb_stats->feasible_blocks[0], cluster_index, gain, cluster_att_grp, attraction_groups, + external_atom_attraction_data, external_attraction_default_weight, external_attraction_default_value, + num_molecule_failures)) { /* single loop insertion sort */ for (j = 0; j < pb->pb_stats->num_feasible_blocks - 1; j++) { - if (get_molecule_gain(molecule, gain, cluster_att_grp, attraction_groups, num_molecule_failures) <= get_molecule_gain(pb->pb_stats->feasible_blocks[j + 1], gain, cluster_att_grp, attraction_groups, num_molecule_failures)) { + if (new_molecule_gain <= get_molecule_gain(pb->pb_stats->feasible_blocks[j + 1], cluster_index, gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value, num_molecule_failures)) { pb->pb_stats->feasible_blocks[j] = molecule; break; } else { @@ -479,7 +493,9 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, } else { /* Expand array and single loop insertion sort */ for (j = pb->pb_stats->num_feasible_blocks - 1; j >= 0; j--) { - if (get_molecule_gain(pb->pb_stats->feasible_blocks[j], gain, cluster_att_grp, attraction_groups, num_molecule_failures) > get_molecule_gain(molecule, gain, cluster_att_grp, attraction_groups, num_molecule_failures)) { + if (get_molecule_gain(pb->pb_stats->feasible_blocks[j], cluster_index, gain, cluster_att_grp, attraction_groups, + external_atom_attraction_data, external_attraction_default_weight, external_attraction_default_value, num_molecule_failures) + > new_molecule_gain) { pb->pb_stats->feasible_blocks[j + 1] = pb->pb_stats->feasible_blocks[j]; } else { pb->pb_stats->feasible_blocks[j + 1] = molecule; @@ -1493,6 +1509,9 @@ void try_fill_cluster(const t_packer_opts& packer_opts, const ClusterBlockId clb_index, const int detailed_routing_stage, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, vtr::vector>& clb_inter_blk_nets, bool allow_unrelated_clustering, const int& high_fanout_threshold, @@ -1553,6 +1572,9 @@ void try_fill_cluster(const t_packer_opts& packer_opts, next_molecule = get_molecule_for_cluster(cluster_ctx.clb_nlist.block_pb(clb_index), attraction_groups, + external_atom_attraction_data, + external_attraction_default_weight, + external_attraction_default_value, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -1598,7 +1620,8 @@ void try_fill_cluster(const t_packer_opts& packer_opts, high_fanout_threshold, *timing_info, attraction_groups, - net_output_feeds_driving_block_input); + net_output_feeds_driving_block_input, + packer_opts.pack_verbosity); cluster_stats.num_unrelated_clustering_attempts = 0; if (packer_opts.timing_driven) { @@ -1606,6 +1629,9 @@ void try_fill_cluster(const t_packer_opts& packer_opts, } next_molecule = get_molecule_for_cluster(cluster_ctx.clb_nlist.block_pb(clb_index), attraction_groups, + external_atom_attraction_data, + external_attraction_default_weight, + external_attraction_default_value, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -1654,7 +1680,8 @@ void store_cluster_info_and_free(const t_packer_opts& packer_opts, const t_logical_block_type_ptr logic_block_type, const t_pb_type* le_pb_type, std::vector& le_count, - vtr::vector>& clb_inter_blk_nets) { + vtr::vector>& clb_inter_blk_nets, + const int verbosity) { auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); auto& atom_ctx = g_vpr_ctx.atom(); @@ -1667,6 +1694,16 @@ void store_cluster_info_and_free(const t_packer_opts& packer_opts, clb_inter_blk_nets[clb_index].push_back(mnet_id); } } + + if (verbosity > 2) { + VTR_LOG("Final Cluster Result for clb #%ld: ", static_cast(clb_index)); + auto& blks_in_the_cluster = g_vpr_ctx.cl_helper().incomplete_cluster_to_atoms_lookup.at(clb_index); + for (const auto& blk_id : blks_in_the_cluster) { + VTR_LOG("%s ", atom_ctx.nlist.block_name(blk_id).c_str()); + } + VTR_LOG("\n"); + } + auto cur_pb = cluster_ctx.clb_nlist.block_pb(clb_index); // update the data structure holding the LE counts @@ -1684,6 +1721,9 @@ void free_data_and_requeue_used_mols_if_illegal(const ClusterBlockId& clb_index, int& num_clb, int& seedindex) { auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); + auto& cl_helper_ctx = g_vpr_ctx.mutable_cl_helper(); + cl_helper_ctx.incomplete_cluster_to_atoms_lookup.erase( + cl_helper_ctx.incomplete_cluster_to_atoms_lookup.cbegin() + static_cast(clb_index)); num_used_type_instances[cluster_ctx.clb_nlist.block_type(clb_index)]--; revalid_molecules(cluster_ctx.clb_nlist.block_pb(clb_index)); @@ -1912,7 +1952,8 @@ void update_cluster_stats(const t_pack_molecule* molecule, const int high_fanout_net_threshold, const SetupTimingInfo& timing_info, AttractionInfo& attraction_groups, - std::unordered_map& net_output_feeds_driving_block_input) { + std::unordered_map& net_output_feeds_driving_block_input, + const int verbosity) { /* Routine that is called each time a new molecule is added to the cluster. * Makes calls to update cluster stats such as the gain map for atoms, used pins, and clock structures, * in order to reflect the new content of the cluster. @@ -1923,6 +1964,7 @@ void update_cluster_stats(const t_pack_molecule* molecule, t_pb *cur_pb, *cb; auto& atom_ctx = g_vpr_ctx.mutable_atom(); + auto& cl_helper_ctx = g_vpr_ctx.mutable_cl_helper(); molecule_size = get_array_size_of_molecule(molecule); cb = nullptr; @@ -1935,6 +1977,17 @@ void update_cluster_stats(const t_pack_molecule* molecule, //Update atom netlist mapping atom_ctx.lookup.set_atom_clb(blk_id, clb_index); + //Update clustring clb to atoms mapping + if (static_cast(clb_index) >= cl_helper_ctx.incomplete_cluster_to_atoms_lookup.size()) { + cl_helper_ctx.incomplete_cluster_to_atoms_lookup.push_back(std::set()); + } + auto& blks_in_the_cluster = cl_helper_ctx.incomplete_cluster_to_atoms_lookup.at(clb_index); + blks_in_the_cluster.insert(blk_id); + + if (verbosity > 2) { + VTR_LOG("Adding block %s to cluster %d\n", atom_ctx.nlist.block_name(blk_id).c_str(), clb_index); + } + const t_pb* atom_pb = atom_ctx.lookup.atom_pb(blk_id); VTR_ASSERT(atom_pb); @@ -2197,6 +2250,9 @@ void start_new_cluster(t_cluster_placement_stats* cluster_placement_stats, */ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const enum e_gain_type gain_mode, t_cluster_placement_stats* cluster_placement_stats_ptr, vtr::vector>& clb_inter_blk_nets, @@ -2217,38 +2273,58 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, // 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster if (cur_pb->pb_stats->num_feasible_blocks == NOT_VALID) { - add_cluster_molecule_candidates_by_connectivity_and_timing(cur_pb, cluster_placement_stats_ptr, feasible_block_array_size, attraction_groups); + add_cluster_molecule_candidates_by_connectivity_and_timing(cur_pb, cluster_index, cluster_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } if (prioritize_transitive_connectivity) { // 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster if (cur_pb->pb_stats->num_feasible_blocks == 0 && cur_pb->pb_stats->explore_transitive_fanout) { add_cluster_molecule_candidates_by_transitive_connectivity(cur_pb, cluster_placement_stats_ptr, clb_inter_blk_nets, - cluster_index, transitive_fanout_threshold, feasible_block_array_size, attraction_groups); + cluster_index, transitive_fanout_threshold, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } // 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster if (cur_pb->pb_stats->num_feasible_blocks == 0 && cur_pb->pb_stats->tie_break_high_fanout_net) { - add_cluster_molecule_candidates_by_highfanout_connectivity(cur_pb, cluster_placement_stats_ptr, feasible_block_array_size, attraction_groups); + add_cluster_molecule_candidates_by_highfanout_connectivity(cur_pb, cluster_index, cluster_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } } else { //Reverse order // 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster if (cur_pb->pb_stats->num_feasible_blocks == 0 && cur_pb->pb_stats->tie_break_high_fanout_net) { - add_cluster_molecule_candidates_by_highfanout_connectivity(cur_pb, cluster_placement_stats_ptr, feasible_block_array_size, attraction_groups); + add_cluster_molecule_candidates_by_highfanout_connectivity(cur_pb, cluster_index, cluster_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } // 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster if (cur_pb->pb_stats->num_feasible_blocks == 0 && cur_pb->pb_stats->explore_transitive_fanout) { add_cluster_molecule_candidates_by_transitive_connectivity(cur_pb, cluster_placement_stats_ptr, clb_inter_blk_nets, - cluster_index, transitive_fanout_threshold, feasible_block_array_size, attraction_groups); + cluster_index, transitive_fanout_threshold, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } } // 4. Find unpacked molecules based on attraction group of the current cluster (if the cluster has an attraction group) if (cur_pb->pb_stats->num_feasible_blocks == 0) { - add_cluster_molecule_candidates_by_attraction_group(cur_pb, cluster_placement_stats_ptr, attraction_groups, + add_cluster_molecule_candidates_by_attraction_group(cur_pb, cluster_placement_stats_ptr, attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value, feasible_block_array_size, cluster_index, primitive_candidate_block_types); } + + // 5. Find unpacked molecules based on external attraction data + // No condition here since we may always want to check this. External data is used to overwrite internal clustering intention + if (!external_atom_attraction_data.empty()) { + add_cluster_molecule_candidates_by_external_attraction_data(cur_pb, cluster_index, cluster_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); + } + /* Grab highest gain molecule */ t_pack_molecule* molecule = nullptr; if (cur_pb->pb_stats->num_feasible_blocks > 0) { @@ -2264,9 +2340,13 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, /* Add molecules with strong connectedness to the current cluster to the list of feasible blocks. */ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, + const ClusterBlockId cluster_index, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value) { VTR_ASSERT(cur_pb->pb_stats->num_feasible_blocks == NOT_VALID); cur_pb->pb_stats->num_feasible_blocks = 0; @@ -2283,7 +2363,9 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); if (success) { add_molecule_to_pb_stats_candidates(molecule, - cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups); + cur_pb->pb_stats->gain, cur_pb, cluster_index, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); } } } @@ -2293,9 +2375,13 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, /* Add molecules based on weak connectedness (connected by high fanout nets) with current cluster */ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, + const ClusterBlockId cluster_index, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value) { /* Because the packer ignores high fanout nets when marking what blocks * to consider, use one of the ignored high fanout net to fill up lightly * related blocks */ @@ -2321,7 +2407,10 @@ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); if (success) { add_molecule_to_pb_stats_candidates(molecule, - cur_pb->pb_stats->gain, cur_pb, std::min(feasible_block_array_size, AAPACK_MAX_HIGH_FANOUT_EXPLORE), attraction_groups); + cur_pb->pb_stats->gain, cur_pb, cluster_index, + std::min(feasible_block_array_size, AAPACK_MAX_HIGH_FANOUT_EXPLORE), + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); count++; } } @@ -2342,6 +2431,9 @@ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const int feasible_block_array_size, ClusterBlockId clb_index, std::map>& primitive_candidate_block_types) { @@ -2410,7 +2502,9 @@ void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb, bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); if (success) { add_molecule_to_pb_stats_candidates(molecule, - cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups); + cur_pb->pb_stats->gain, cur_pb, clb_index, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); } } } @@ -2445,7 +2539,9 @@ void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb, bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); if (success) { add_molecule_to_pb_stats_candidates(molecule, - cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups); + cur_pb->pb_stats->gain, cur_pb, clb_index, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); } } } @@ -2460,7 +2556,10 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, const ClusterBlockId cluster_index, int transitive_fanout_threshold, const int feasible_block_array_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value) { //TODO: For now, only done by fan-out; should also consider fan-in cur_pb->pb_stats->explore_transitive_fanout = false; @@ -2475,8 +2574,53 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, if (molecule->valid) { bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); if (success) { - add_molecule_to_pb_stats_candidates(molecule, - cur_pb->pb_stats->gain, cur_pb, std::min(feasible_block_array_size, AAPACK_MAX_TRANSITIVE_EXPLORE), attraction_groups); + add_molecule_to_pb_stats_candidates(molecule, cur_pb->pb_stats->gain, cur_pb, cluster_index, + std::min(feasible_block_array_size, AAPACK_MAX_TRANSITIVE_EXPLORE), + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); + } + } + } +} + +void add_cluster_molecule_candidates_by_external_attraction_data(t_pb* cur_pb, + const ClusterBlockId cluster_index, + t_cluster_placement_stats* cluster_placement_stats_ptr, + const int feasible_block_array_size, + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value) { + if (external_atom_attraction_data.empty()) return; + + // Copied from other code, need to change + auto& atom_ctx = g_vpr_ctx.atom(); + const auto& cl_helper_ctx = g_vpr_ctx.cl_helper(); + + auto& atom_blocks_in_cluster = cl_helper_ctx.incomplete_cluster_to_atoms_lookup.at(cluster_index); + // Given all the blocks already in the cluster, explore all the other atom blocks that can be cluster into this cluster + for (const auto& blk_id : atom_blocks_in_cluster) { + const auto& src_itr = external_atom_attraction_data.find(blk_id); + if (src_itr == external_atom_attraction_data.end()) { + continue; + } + + for (const auto& dst_itr : src_itr->second) { + AtomBlockId dst_blk_id = dst_itr.first; + if (atom_ctx.lookup.atom_clb(dst_blk_id) == ClusterBlockId::INVALID()) { + auto rng = atom_ctx.atom_molecules.equal_range(dst_blk_id); + for (const auto& kv : vtr::make_range(rng.first, rng.second)) { + t_pack_molecule* molecule = kv.second; + if (molecule->valid) { + bool success = check_free_primitives_for_molecule_atoms(molecule, cluster_placement_stats_ptr); + if (success) { + add_molecule_to_pb_stats_candidates(molecule, + cur_pb->pb_stats->gain, cur_pb, cluster_index, feasible_block_array_size, + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); + } + } + } } } } @@ -2506,6 +2650,9 @@ bool check_free_primitives_for_molecule_atoms(t_pack_molecule* molecule, t_clust /*****************************************/ t_pack_molecule* get_molecule_for_cluster(t_pb* cur_pb, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const bool allow_unrelated_clustering, const bool prioritize_transitive_connectivity, const int transitive_fanout_threshold, @@ -2527,7 +2674,8 @@ t_pack_molecule* get_molecule_for_cluster(t_pb* cur_pb, /* If cannot pack into primitive, try packing into cluster */ - auto best_molecule = get_highest_gain_molecule(cur_pb, attraction_groups, + auto best_molecule = get_highest_gain_molecule(cur_pb, attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value, NOT_HILL_CLIMBING, cluster_placement_stats_ptr, clb_inter_blk_nets, cluster_index, prioritize_transitive_connectivity, transitive_fanout_threshold, feasible_block_array_size, primitive_candidate_block_types); @@ -2853,58 +3001,88 @@ t_pack_molecule* get_highest_gain_seed_molecule(int* seedindex, const std::vecto /* get gain of packing molecule into current cluster * gain is equal to: * total_block_gain + * attraction_group_score * + molecule_base_gain*some_factor * - introduced_input_nets_of_unrelated_blocks_pulled_in_by_molecule*some_other_factor + * + external_atom_attraction*some_factor */ -float get_molecule_gain(t_pack_molecule* molecule, std::map& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, int num_molecule_failures) { - float gain; +float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_index, const std::map& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, const std::unordered_map>& external_atom_attraction_data, float external_attraction_default_weight, float external_attraction_default_value, int num_molecule_failures) { + float gain = 0.0; + + float att_grp_gain = 0.0; + float attraction_group_penalty = 0.1; + + float external_attraction_score = 0.0; + int i; int num_introduced_inputs_of_indirectly_related_block; auto& atom_ctx = g_vpr_ctx.atom(); - - gain = 0; - float attraction_group_penalty = 0.1; + const auto& cl_helper_ctx = g_vpr_ctx.cl_helper(); num_introduced_inputs_of_indirectly_related_block = 0; for (i = 0; i < get_array_size_of_molecule(molecule); i++) { auto blk_id = molecule->atom_block_ids[i]; - if (blk_id) { - if (blk_gain.count(blk_id) > 0) { - gain += blk_gain[blk_id]; - } else { - /* This block has no connection with current cluster, penalize molecule for having this block - */ - for (auto pin_id : atom_ctx.nlist.block_input_pins(blk_id)) { - auto net_id = atom_ctx.nlist.pin_net(pin_id); - VTR_ASSERT(net_id); + if (!blk_id) continue; - auto driver_pin_id = atom_ctx.nlist.net_driver(net_id); - VTR_ASSERT(driver_pin_id); + // Calculate the score affected by attraction_groups + AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group(blk_id); + if (atom_grp_id == cluster_attraction_group_id && cluster_attraction_group_id != AttractGroupId::INVALID()) { + att_grp_gain = attraction_groups.get_attraction_group_gain(atom_grp_id); + } else if (cluster_attraction_group_id != AttractGroupId::INVALID() && atom_grp_id != cluster_attraction_group_id) { + att_grp_gain = -attraction_group_penalty; + } - auto driver_blk_id = atom_ctx.nlist.pin_block(driver_pin_id); + // Calculate the score affected by unrelated molecules + if (blk_gain.count(blk_id) > 0) { + gain += blk_gain.at(blk_id); + } else { + /* This block has no connection with current cluster, penalize molecule for having this block + */ + for (auto pin_id : atom_ctx.nlist.block_input_pins(blk_id)) { + auto net_id = atom_ctx.nlist.pin_net(pin_id); + VTR_ASSERT(net_id); - num_introduced_inputs_of_indirectly_related_block++; - for (int iblk = 0; iblk < get_array_size_of_molecule(molecule); iblk++) { - if (molecule->atom_block_ids[iblk] && driver_blk_id == molecule->atom_block_ids[iblk]) { - //valid block which is driver (and hence not an input) - num_introduced_inputs_of_indirectly_related_block--; - break; - } + auto driver_pin_id = atom_ctx.nlist.net_driver(net_id); + VTR_ASSERT(driver_pin_id); + + auto driver_blk_id = atom_ctx.nlist.pin_block(driver_pin_id); + + num_introduced_inputs_of_indirectly_related_block++; + for (int iblk = 0; iblk < get_array_size_of_molecule(molecule); iblk++) { + if (molecule->atom_block_ids[iblk] && driver_blk_id == molecule->atom_block_ids[iblk]) { + //valid block which is driver (and hence not an input) + num_introduced_inputs_of_indirectly_related_block--; + break; } } } - AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group(blk_id); - if (atom_grp_id == cluster_attraction_group_id && cluster_attraction_group_id != AttractGroupId::INVALID()) { - float att_grp_gain = attraction_groups.get_attraction_group_gain(atom_grp_id); - gain += att_grp_gain; - } else if (cluster_attraction_group_id != AttractGroupId::INVALID() && atom_grp_id != cluster_attraction_group_id) { - gain -= attraction_group_penalty; + } + + // Calculate the score affected by external atom attraction data + if (!external_atom_attraction_data.empty()) { + const auto& atom_blocks_ids = cl_helper_ctx.incomplete_cluster_to_atoms_lookup.at(cluster_index); + for (const auto& blk : atom_blocks_ids) { + auto itr = external_atom_attraction_data.find(blk); + if (itr == external_atom_attraction_data.end()) { + external_attraction_score += external_attraction_default_value; + continue; + } + + auto dst_itr = itr->second.find(blk_id); + if (dst_itr == itr->second.end()) { + external_attraction_score += external_attraction_default_value; + continue; + } + + external_attraction_score += external_atom_attraction_data.at(blk).at(blk_id); } } } + gain += att_grp_gain; gain += molecule->base_gain * 0.0001; /* Use base gain as tie breaker TODO: need to sweep this value and perhaps normalize */ gain -= num_introduced_inputs_of_indirectly_related_block * (0.001); + gain += external_attraction_default_weight * external_attraction_score; if (num_molecule_failures > 0 && attraction_groups.num_attraction_groups() > 0) { gain -= 0.1 * num_molecule_failures; @@ -3688,4 +3866,68 @@ void init_clb_atoms_lookup(vtr::vector 1, "\nLoadign external attracion data\n"); + // go through the file + try { + // load the file + loc_data = pugiutil::load_xml(doc, attraction_file_char); + + // Root tag should be attraction_data + auto attraction_data_tag = pugiutil::get_single_child(doc, "attraction_data", loc_data); + + for (pugi::xml_node single_attraction : attraction_data_tag.children()) { + auto src_node_tag = pugiutil::get_single_child(single_attraction, "src", loc_data); + std::string src_node_name = pugiutil::get_attribute(src_node_tag, "name", loc_data, pugiutil::REQUIRED).as_string(); + AtomBlockId src_block_id = atom_ctx.nlist.find_block(src_node_name); + + auto dst_nodes_tags = pugiutil::get_single_child(single_attraction, "dst_list", loc_data); + for (pugi::xml_node dst_node_tag : dst_nodes_tags.children()) { + std::string dst_node_name = pugiutil::get_attribute(dst_node_tag, "name", loc_data, pugiutil::REQUIRED).as_string(); + AtomBlockId dst_block_id = atom_ctx.nlist.find_block(dst_node_name); + + double attraction_score = pugiutil::get_attribute(dst_node_tag, "score", loc_data, pugiutil::REQUIRED).as_double(); + + VTR_ASSERT(src_block_id); + VTR_ASSERT(dst_block_id); + VTR_LOGV(verbosity > 2, "attraction: score: %f, src: %d:%s, dst: %d:%s\n", attraction_score, src_block_id, src_node_name.c_str(), dst_block_id, dst_node_name.c_str()); + attraction_data[src_block_id][dst_block_id] = attraction_score; + } + } + + } catch (pugiutil::XmlError& e) { // used for identifying any of the xml parsing library errors + vpr_throw(VPR_ERROR_OTHER, attraction_file_char, e.line(), e.what()); + } + + VTR_LOGV(verbosity > 2, "\n=============================\n\n"); + + for (auto srckv : attraction_data) { + for (auto dstkv : srckv.second) { + VTR_LOGV(verbosity > 2, "attraction: score: %f, src: %d, dst: %d\n", dstkv.second, srckv.first, dstkv.first); + } + } + + // for (auto& block_id : atom_ctx.nlist.blocks()) { + // std::string atom_name = atom_ctx.nlist.block_name(block_id); + // VTR_LOG("atom id: %d, name: %s\n", block_id, atom_name.c_str()); + // } } \ No newline at end of file diff --git a/vpr/src/pack/cluster_util.h b/vpr/src/pack/cluster_util.h index 9a91e47ea7a..87737ddeb75 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -139,10 +139,14 @@ bool check_cluster_legality(const int& verbosity, bool is_atom_blk_in_pb(const AtomBlockId blk_id, const t_pb* pb); void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, - std::map& gain, + const std::map& gain, t_pb* pb, + const ClusterBlockId cluster_index, int max_queue_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value); void remove_molecule_from_pb_stats_candidates(t_pack_molecule* molecule, t_pb* pb); @@ -228,6 +232,9 @@ void try_fill_cluster(const t_packer_opts& packer_opts, const ClusterBlockId clb_index, const int detailed_routing_stage, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, vtr::vector>& clb_inter_blk_nets, bool allow_unrelated_clustering, const int& high_fanout_threshold, @@ -256,7 +263,8 @@ void store_cluster_info_and_free(const t_packer_opts& packer_opts, const t_logical_block_type_ptr logic_block_type, const t_pb_type* le_pb_type, std::vector& le_count, - vtr::vector>& clb_inter_blk_nets); + vtr::vector>& clb_inter_blk_nets, + const int verbosity); void free_data_and_requeue_used_mols_if_illegal(const ClusterBlockId& clb_index, const int& savedseedindex, @@ -319,7 +327,8 @@ void update_cluster_stats(const t_pack_molecule* molecule, const int high_fanout_net_threshold, const SetupTimingInfo& timing_info, AttractionInfo& attraction_groups, - std::unordered_map& net_output_feeds_driving_block_input); + std::unordered_map& net_output_feeds_driving_block_input, + const int verbosity); void start_new_cluster(t_cluster_placement_stats* cluster_placement_stats, t_pb_graph_node** primitives_list, @@ -344,6 +353,9 @@ void start_new_cluster(t_cluster_placement_stats* cluster_placement_stats, t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const enum e_gain_type gain_mode, t_cluster_placement_stats* cluster_placement_stats_ptr, vtr::vector>& clb_inter_blk_nets, @@ -354,18 +366,29 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, std::map>& primitive_candidate_block_types); void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, + const ClusterBlockId cluster_index, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value); void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, + const ClusterBlockId cluster_index, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value); void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const int feasible_block_array_size, ClusterBlockId clb_index, std::map>& primitive_candidate_block_types); @@ -376,12 +399,27 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, const ClusterBlockId cluster_index, int transitive_fanout_threshold, const int feasible_block_array_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value); + +void add_cluster_molecule_candidates_by_external_attraction_data(t_pb* cur_pb, + const ClusterBlockId cluster_index, + t_cluster_placement_stats* cluster_placement_stats_ptr, + const int feasible_block_array_size, + AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value); bool check_free_primitives_for_molecule_atoms(t_pack_molecule* molecule, t_cluster_placement_stats* cluster_placement_stats_ptr); t_pack_molecule* get_molecule_for_cluster(t_pb* cur_pb, AttractionInfo& attraction_groups, + const std::unordered_map>& external_atom_attraction_data, + float external_attraction_default_weight, + float external_attraction_default_value, const bool allow_unrelated_clustering, const bool prioritize_transitive_connectivity, const int transitive_fanout_threshold, @@ -409,7 +447,7 @@ std::vector initialize_seed_atoms(const e_cluster_seed seed_type, t_pack_molecule* get_highest_gain_seed_molecule(int* seedindex, const std::vector seed_atoms); -float get_molecule_gain(t_pack_molecule* molecule, std::map& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, int num_molecule_failures); +float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_index, const std::map& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, const std::unordered_map>& external_atom_attraction_data, float external_attraction_default_weight, float external_attraction_default_value, int num_molecule_failures); int compare_molecule_gain(const void* a, const void* b); int net_sinks_reachable_in_cluster(const t_pb_graph_pin* driver_pb_gpin, const int depth, const AtomNetId net_id); @@ -452,4 +490,7 @@ bool cleanup_pb(t_pb* pb); void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_size); void init_clb_atoms_lookup(vtr::vector>& atoms_lookup); + +// Helper functions for load external attraction data +void load_external_attraction_data(const std::string& attraction_file, const int verbosity); #endif \ No newline at end of file diff --git a/vtr_flow/benchmarks/verilog/single_chain.v b/vtr_flow/benchmarks/verilog/single_chain.v new file mode 100644 index 00000000000..a6eadef0af4 --- /dev/null +++ b/vtr_flow/benchmarks/verilog/single_chain.v @@ -0,0 +1,18 @@ +module top(input clock, in, output reg out); + reg [9:0] register_chain; + + always @(posedge clock) begin + register_chain[0] <= in; + register_chain[1] <= register_chain[0]; + register_chain[2] <= register_chain[1] + register_chain[1]; + register_chain[3] <= register_chain[2] + register_chain[2]; + register_chain[4] <= register_chain[3] + register_chain[3]; + register_chain[5] <= register_chain[4]; + register_chain[6] <= register_chain[5]; + register_chain[7] <= register_chain[6]; + register_chain[8] <= register_chain[7]; + register_chain[9] <= register_chain[8]; + out <= register_chain[9]; + end + +endmodule diff --git a/vtr_flow/parse/pass_requirements/pass_requirements_worse_cluster.txt b/vtr_flow/parse/pass_requirements/pass_requirements_worse_cluster.txt new file mode 100644 index 00000000000..bf7c35e02a4 --- /dev/null +++ b/vtr_flow/parse/pass_requirements/pass_requirements_worse_cluster.txt @@ -0,0 +1,3 @@ +placed_wirelength_est;Range(1.05,2.0) +num_post_packed_nets;Range(1.05,2.0) +min_chan_width_routing_area_total;Range(1.05,2.0) \ No newline at end of file diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/config.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/config.txt new file mode 100644 index 00000000000..d8a1ff38c7d --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/config.txt @@ -0,0 +1,34 @@ +# +############################################ +# Configuration file for running experiments +############################################## + +# Path to directory of circuits to use +circuits_dir=benchmarks/verilog + +# Path to directory of architectures to use +archs_dir=arch/timing + +# Add circuits to list to sweep +circuit_list_add=single_chain.v + +# Add architectures to list to sweep +arch_list_add=EArch.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_worse_cluster.txt + +#Sweep option range +script_params_common = --cluster_seed_type timing --pack_verbosity 3 + +#additional_files_list_add =--external_attraction_file,sample_external_attraction_data.xml +# script_params_list_add =--seed 1 + +#additional_files_list_add =--external_attraction_file,sample_external_attraction_data_2.xml +script_params_list_add =--seed 1 --external_attraction_file ../../../../config/sample_external_attraction_data_2.xml diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/golden_results.txt new file mode 100644 index 00000000000..916e1e17a2e --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/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 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 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 crit_path_total_internal_heap_pushes crit_path_total_internal_heap_pops crit_path_total_external_heap_pushes crit_path_total_external_heap_pops crit_path_total_external_SOURCE_pushes crit_path_total_external_SOURCE_pops crit_path_total_internal_SOURCE_pushes crit_path_total_internal_SOURCE_pops crit_path_total_external_SINK_pushes crit_path_total_external_SINK_pops crit_path_total_internal_SINK_pushes crit_path_total_internal_SINK_pops crit_path_total_external_IPIN_pushes crit_path_total_external_IPIN_pops crit_path_total_internal_IPIN_pushes crit_path_total_internal_IPIN_pops crit_path_total_external_OPIN_pushes crit_path_total_external_OPIN_pops crit_path_total_internal_OPIN_pushes crit_path_total_internal_OPIN_pops crit_path_total_external_CHANX_pushes crit_path_total_external_CHANX_pops crit_path_total_internal_CHANX_pushes crit_path_total_internal_CHANX_pops crit_path_total_external_CHANY_pushes crit_path_total_external_CHANY_pops crit_path_total_internal_CHANY_pushes crit_path_total_internal_CHANY_pops crit_path_rt_node_SOURCE_pushes crit_path_rt_node_SINK_pushes crit_path_rt_node_IPIN_pushes crit_path_rt_node_OPIN_pushes crit_path_rt_node_CHANX_pushes crit_path_rt_node_CHANY_pushes crit_path_adding_all_rt crit_path_adding_high_fanout_rt crit_path_total_number_of_adding_all_rt_from_calling_high_fanout_rt 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 +EArch.xml single_chain.v common_--seed_1_--external_attraction_file_../../../../config/sample_external_attraction_data_2.xml 1.67 vpr 69.92 MiB -1 -1 0.08 23552 1 0.01 -1 -1 34404 -1 -1 3 2 0 0 success 4cb517a7f-dirty debug VTR_ASSERT_LEVEL=2 GNU 11.4.0 on Linux-6.2.0-32-generic x86_64 2023-09-10T16:03:13 siwei-X570 /home/siwei/Developer/vtr-verilog-to-routing/vtr_flow/tasks 71596 2 1 21 22 1 7 6 5 5 25 clb auto 31.6 MiB 0.03 12 69.9 MiB 0.00 0.00 0.97541 -7.57542 -0.97541 0.97541 0.23 0.000267334 0.000190603 0.00187422 0.00137103 12 25 5 323364 161682 13670.8 546.832 0.62 0.0139454 0.0111213 1380 2690 -1 23 1 4 4 180 104 0 0 180 104 4 4 0 0 20 18 0 0 28 28 0 0 4 4 0 0 73 24 0 0 51 26 0 0 4 0 0 0 0 0 4 0 0 1.19517 1.19517 -8.3775 -1.19517 0 0 17474.5 698.981 0.03 0.00 0.03 -1 -1 0.03 0.00432479 0.00331434 diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/sample_external_attraction_data_2.xml b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/sample_external_attraction_data_2.xml new file mode 100644 index 00000000000..9fb780e6ecd --- /dev/null +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/sample_external_attraction_data_2.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +