From 4ef3f2d56a5e8c16bd83df588c2acb1b15b06d72 Mon Sep 17 00:00:00 2001 From: Louis-He Date: Mon, 31 Jul 2023 22:57:56 -0400 Subject: [PATCH 1/6] Add option to read external attraction data --- vpr/src/base/SetupVPR.cpp | 1 + vpr/src/base/ShowSetup.cpp | 6 ++ vpr/src/base/read_options.cpp | 5 ++ vpr/src/base/read_options.h | 1 + vpr/src/base/vpr_context.h | 4 + vpr/src/base/vpr_types.h | 1 + vpr/src/pack/cluster.cpp | 6 ++ vpr/src/pack/cluster_util.cpp | 141 ++++++++++++++++++++++++++++------ vpr/src/pack/cluster_util.h | 24 ++++-- 9 files changed, 161 insertions(+), 28 deletions(-) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 84650d654b7..88c8413321d 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -553,6 +553,7 @@ 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->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 ba8e9d74cc2..f1c14f9731c 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 74a5159da96..bd101ac0b13 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 7c83980fcc4..54424b450c5 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -340,6 +340,10 @@ 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 DBL_MIN + std::vector> external_atom_attraction_data; + ~ClusteringHelperContext() { delete[] primitives_list; } diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 5db0c4b82be..39830f0486b 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -903,6 +903,7 @@ struct t_packer_opts { e_unrelated_clustering allow_unrelated_clustering; bool connection_driven; int pack_verbosity; + std::string external_attraction_file; 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..19e090f8bd4 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,9 @@ std::map do_clustering(const t_packer_opts& pa istart = nullptr; + // load external attraction data + load_external_attraction_data(packer_opts.external_attraction_file); + /* determine bound on cluster size and primitive input size */ helper_ctx.max_cluster_size = 0; max_pb_depth = 0; @@ -304,6 +308,7 @@ 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, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -350,6 +355,7 @@ std::map do_clustering(const t_packer_opts& pa clb_index, detailed_routing_stage, attraction_groups, + cl_helper_ctx.external_atom_attraction_data, clb_inter_blk_nets, allow_unrelated_clustering, high_fanout_threshold, diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 0e12305dc70..f90cd5979d1 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,11 @@ 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, int max_queue_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data) { int i, j; int num_molecule_failures = 0; @@ -460,12 +465,14 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, } } + float new_molecule_gain = get_molecule_gain(molecule, gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, 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], gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, 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], gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, num_molecule_failures)) { pb->pb_stats->feasible_blocks[j] = molecule; break; } else { @@ -479,7 +486,7 @@ 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], gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, 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 +1500,7 @@ void try_fill_cluster(const t_packer_opts& packer_opts, const ClusterBlockId clb_index, const int detailed_routing_stage, AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data, vtr::vector>& clb_inter_blk_nets, bool allow_unrelated_clustering, const int& high_fanout_threshold, @@ -1553,6 +1561,7 @@ 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, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -1606,6 +1615,7 @@ 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, allow_unrelated_clustering, packer_opts.prioritize_transitive_connectivity, packer_opts.transitive_fanout_threshold, @@ -2197,6 +2207,7 @@ 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::vector>& external_atom_attraction_data, const enum e_gain_type gain_mode, t_cluster_placement_stats* cluster_placement_stats_ptr, vtr::vector>& clb_inter_blk_nets, @@ -2217,36 +2228,41 @@ 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_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } 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); } // 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_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } } 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_placement_stats_ptr, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } // 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); } } // 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, feasible_block_array_size, cluster_index, primitive_candidate_block_types); } /* Grab highest gain molecule */ @@ -2266,7 +2282,8 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data) { VTR_ASSERT(cur_pb->pb_stats->num_feasible_blocks == NOT_VALID); cur_pb->pb_stats->num_feasible_blocks = 0; @@ -2283,7 +2300,8 @@ 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, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } } } @@ -2295,7 +2313,8 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups) { + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data) { /* 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 +2340,9 @@ 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, + std::min(feasible_block_array_size, AAPACK_MAX_HIGH_FANOUT_EXPLORE), + attraction_groups, external_atom_attraction_data); count++; } } @@ -2342,6 +2363,7 @@ 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::vector>& external_atom_attraction_data, const int feasible_block_array_size, ClusterBlockId clb_index, std::map>& primitive_candidate_block_types) { @@ -2410,7 +2432,8 @@ 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, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } } } @@ -2445,7 +2468,8 @@ 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, feasible_block_array_size, + attraction_groups, external_atom_attraction_data); } } } @@ -2460,7 +2484,8 @@ 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::vector>& external_atom_attraction_data) { //TODO: For now, only done by fan-out; should also consider fan-in cur_pb->pb_stats->explore_transitive_fanout = false; @@ -2476,7 +2501,8 @@ void add_cluster_molecule_candidates_by_transitive_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_TRANSITIVE_EXPLORE), attraction_groups); + cur_pb->pb_stats->gain, cur_pb, std::min(feasible_block_array_size, AAPACK_MAX_TRANSITIVE_EXPLORE), + attraction_groups, external_atom_attraction_data); } } } @@ -2506,6 +2532,7 @@ 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::vector>& external_atom_attraction_data, const bool allow_unrelated_clustering, const bool prioritize_transitive_connectivity, const int transitive_fanout_threshold, @@ -2527,7 +2554,7 @@ 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, 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); @@ -2856,7 +2883,8 @@ t_pack_molecule* get_highest_gain_seed_molecule(int* seedindex, const std::vecto * + molecule_base_gain*some_factor * - introduced_input_nets_of_unrelated_blocks_pulled_in_by_molecule*some_other_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 get_molecule_gain(t_pack_molecule* molecule, const std::map& blk_gain, AttractGroupId cluster_attraction_group_id, + AttractionInfo& attraction_groups, const std::vector>& external_atom_attraction_data, int num_molecule_failures) { float gain; int i; int num_introduced_inputs_of_indirectly_related_block; @@ -2870,7 +2898,7 @@ float get_molecule_gain(t_pack_molecule* molecule, std::map& auto blk_id = molecule->atom_block_ids[i]; if (blk_id) { if (blk_gain.count(blk_id) > 0) { - gain += blk_gain[blk_id]; + gain += blk_gain.at(blk_id); } else { /* This block has no connection with current cluster, penalize molecule for having this block */ @@ -3688,4 +3716,73 @@ void init_clb_atoms_lookup(vtr::vector>(num_atom, std::vector(num_atom, __DBL_MIN__)); + + pugi::xml_document doc; + pugiutil::loc_data loc_data; + + VTR_LOG("\nLoad 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_LOG("attraction: score: %f, %d:%s -> %d:%s\n", attraction_score, src_block_id, src_node_name.c_str(), dst_block_id, dst_node_name.c_str()); + attraction_data[static_cast(src_block_id)][static_cast(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_LOG("\n=============================\n\n"); + + for (size_t i = 0; i < num_atom; i++) + { + for (size_t j = 0; j < num_atom; j++) + { + if (i == j) continue; + + if (attraction_data[i][j] == __DBL_MIN__) continue; + VTR_LOG("attraction: score: %f, %d -> %d\n", attraction_data[i][j], i, j); + } + } + + 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 1316229abc5..53d0b4a5f08 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -139,10 +139,11 @@ 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, int max_queue_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data); void remove_molecule_from_pb_stats_candidates(t_pack_molecule* molecule, t_pb* pb); @@ -228,6 +229,7 @@ void try_fill_cluster(const t_packer_opts& packer_opts, const ClusterBlockId clb_index, const int detailed_routing_stage, AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data, vtr::vector>& clb_inter_blk_nets, bool allow_unrelated_clustering, const int& high_fanout_threshold, @@ -344,6 +346,7 @@ 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::vector>& external_atom_attraction_data, const enum e_gain_type gain_mode, t_cluster_placement_stats* cluster_placement_stats_ptr, vtr::vector>& clb_inter_blk_nets, @@ -356,16 +359,19 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data); void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, t_cluster_placement_stats* cluster_placement_stats_ptr, const int feasible_block_array_size, - AttractionInfo& attraction_groups); + AttractionInfo& attraction_groups, + const std::vector>& external_atom_attraction_data); 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::vector>& external_atom_attraction_data, const int feasible_block_array_size, ClusterBlockId clb_index, std::map>& primitive_candidate_block_types); @@ -376,12 +382,14 @@ 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::vector>& external_atom_attraction_data); 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::vector>& external_atom_attraction_data, const bool allow_unrelated_clustering, const bool prioritize_transitive_connectivity, const int transitive_fanout_threshold, @@ -409,7 +417,8 @@ 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 std::map& blk_gain, AttractGroupId cluster_attraction_group_id, + AttractionInfo& attraction_groups, const std::vector>& external_atom_attraction_data, 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 +461,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); #endif \ No newline at end of file From 4cb517a7f343bd3ae0630908f3c426d4f1007bbb Mon Sep 17 00:00:00 2001 From: Louis-He Date: Mon, 21 Aug 2023 23:56:53 -0400 Subject: [PATCH 2/6] support external attraction data and add it as a factor of clustering --- vpr/src/base/SetupVPR.cpp | 2 + vpr/src/base/vpr_context.h | 12 +- vpr/src/base/vpr_types.h | 2 + vpr/src/pack/cluster.cpp | 10 ++ vpr/src/pack/cluster_util.cpp | 271 ++++++++++++++++++++++++---------- vpr/src/pack/cluster_util.h | 43 ++++-- 6 files changed, 254 insertions(+), 86 deletions(-) diff --git a/vpr/src/base/SetupVPR.cpp b/vpr/src/base/SetupVPR.cpp index 88c8413321d..d244e1badcd 100644 --- a/vpr/src/base/SetupVPR.cpp +++ b/vpr/src/base/SetupVPR.cpp @@ -554,6 +554,8 @@ void SetupPackerOpts(const t_options& Options, 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/vpr_context.h b/vpr/src/base/vpr_context.h index 54424b450c5..86109bca31b 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -341,8 +341,16 @@ struct ClusteringHelperContext : public Context { // 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 DBL_MIN - std::vector> external_atom_attraction_data; + // 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 39830f0486b..c66e2535327 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -904,6 +904,8 @@ struct t_packer_opts { 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 19e090f8bd4..9c76c0374d8 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -178,6 +178,9 @@ std::map do_clustering(const t_packer_opts& pa // load external attraction data load_external_attraction_data(packer_opts.external_attraction_file); + // 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; @@ -309,6 +312,8 @@ std::map do_clustering(const t_packer_opts& pa 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, @@ -356,6 +361,8 @@ std::map do_clustering(const t_packer_opts& pa 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, @@ -392,6 +399,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 f90cd5979d1..1d0008bf2fd 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -433,9 +433,11 @@ void remove_molecule_from_pb_stats_candidates(t_pack_molecule* molecule, void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, const std::map& gain, t_pb* pb, + const ClusterBlockId cluster_index, int max_queue_size, AttractionInfo& attraction_groups, - const std::vector>& external_atom_attraction_data) { + 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; @@ -465,14 +467,18 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, } } - float new_molecule_gain = get_molecule_gain(molecule, gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, num_molecule_failures); + 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 (new_molecule_gain > get_molecule_gain(pb->pb_stats->feasible_blocks[0], gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, 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 (new_molecule_gain <= get_molecule_gain(pb->pb_stats->feasible_blocks[j + 1], gain, cluster_att_grp, attraction_groups, external_atom_attraction_data, 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 { @@ -486,7 +492,8 @@ 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, external_atom_attraction_data, num_molecule_failures) > new_molecule_gain) { + 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; @@ -1500,7 +1507,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::vector>& external_atom_attraction_data, + 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, @@ -1562,6 +1571,8 @@ 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, @@ -1616,6 +1627,8 @@ 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, @@ -1933,6 +1946,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; @@ -1945,6 +1959,13 @@ 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(blk_id) >= 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); + const t_pb* atom_pb = atom_ctx.lookup.atom_pb(blk_id); VTR_ASSERT(atom_pb); @@ -2207,7 +2228,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::vector>& external_atom_attraction_data, + 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, @@ -2228,8 +2251,9 @@ 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, external_atom_attraction_data); + 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) { @@ -2237,34 +2261,49 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, 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, external_atom_attraction_data); + 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, external_atom_attraction_data); + 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, external_atom_attraction_data); + 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, external_atom_attraction_data); + 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, external_atom_attraction_data, + 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) { @@ -2280,10 +2319,12 @@ 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, - const std::vector>& external_atom_attraction_data) { + 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; @@ -2300,8 +2341,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, external_atom_attraction_data); + 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); } } } @@ -2311,10 +2353,12 @@ 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, - const std::vector>& external_atom_attraction_data) { + 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 */ @@ -2340,9 +2384,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, + 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); + attraction_groups, external_atom_attraction_data, + external_attraction_default_weight, external_attraction_default_value); count++; } } @@ -2363,7 +2408,8 @@ 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::vector>& external_atom_attraction_data, + 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) { @@ -2432,8 +2478,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, external_atom_attraction_data); + 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); } } } @@ -2468,8 +2515,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, external_atom_attraction_data); + 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); } } } @@ -2485,7 +2533,8 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, int transitive_fanout_threshold, const int feasible_block_array_size, AttractionInfo& attraction_groups, - const std::vector>& external_atom_attraction_data) { + 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; @@ -2500,9 +2549,54 @@ 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, external_atom_attraction_data); + 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); + } + } + } } } } @@ -2532,7 +2626,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::vector>& external_atom_attraction_data, + 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, @@ -2554,7 +2650,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, external_atom_attraction_data, + 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); @@ -2880,59 +2977,89 @@ 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, const std::map& blk_gain, AttractGroupId cluster_attraction_group_id, - AttractionInfo& attraction_groups, const std::vector>& external_atom_attraction_data, 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.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); + if (!blk_id) continue; - 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); + // 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; + } - 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; - } + // 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); + + 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 + 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; @@ -3733,7 +3860,6 @@ void load_external_attraction_data(const std::string& attraction_file) { size_t num_atom = atom_ctx.nlist.blocks().size(); // initialize external attraction data in clustering helper context auto& attraction_data = g_vpr_ctx.mutable_cl_helper().external_atom_attraction_data; - attraction_data = std::vector>(num_atom, std::vector(num_atom, __DBL_MIN__)); pugi::xml_document doc; pugiutil::loc_data loc_data; @@ -3760,7 +3886,7 @@ void load_external_attraction_data(const std::string& attraction_file) { double attraction_score = pugiutil::get_attribute(dst_node_tag, "score", loc_data, pugiutil::REQUIRED).as_double(); VTR_LOG("attraction: score: %f, %d:%s -> %d:%s\n", attraction_score, src_block_id, src_node_name.c_str(), dst_block_id, dst_node_name.c_str()); - attraction_data[static_cast(src_block_id)][static_cast(dst_block_id)] = attraction_score; + attraction_data[src_block_id][dst_block_id] = attraction_score; } } @@ -3770,14 +3896,11 @@ void load_external_attraction_data(const std::string& attraction_file) { VTR_LOG("\n=============================\n\n"); - for (size_t i = 0; i < num_atom; i++) + for (auto srckv : attraction_data) { - for (size_t j = 0; j < num_atom; j++) + for (auto dstkv : srckv.second) { - if (i == j) continue; - - if (attraction_data[i][j] == __DBL_MIN__) continue; - VTR_LOG("attraction: score: %f, %d -> %d\n", attraction_data[i][j], i, j); + VTR_LOG("attraction: score: %f, %d -> %d\n", dstkv.second, srckv.first, dstkv.first); } } diff --git a/vpr/src/pack/cluster_util.h b/vpr/src/pack/cluster_util.h index 53d0b4a5f08..6b5a8e576d5 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -141,9 +141,11 @@ 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, const std::map& gain, t_pb* pb, + const ClusterBlockId cluster_index, int max_queue_size, AttractionInfo& attraction_groups, - const std::vector>& external_atom_attraction_data); + 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); @@ -229,7 +231,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::vector>& external_atom_attraction_data, + 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, @@ -346,7 +350,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::vector>& external_atom_attraction_data, + 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, @@ -357,21 +363,26 @@ 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, - const std::vector>& external_atom_attraction_data); + 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, - const std::vector>& external_atom_attraction_data); + 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::vector>& external_atom_attraction_data, + 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); @@ -383,13 +394,24 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, int transitive_fanout_threshold, const int feasible_block_array_size, AttractionInfo& attraction_groups, - const std::vector>& external_atom_attraction_data); + 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::vector>& external_atom_attraction_data, + 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, @@ -417,8 +439,9 @@ 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, const std::map& blk_gain, AttractGroupId cluster_attraction_group_id, - AttractionInfo& attraction_groups, const std::vector>& external_atom_attraction_data, 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); From df71e4679efe11c6c6e940adcf7a47ee964975cb Mon Sep 17 00:00:00 2001 From: Louis-He Date: Sun, 10 Sep 2023 17:02:50 -0400 Subject: [PATCH 3/6] Add regression test for external attraction data. Add assertion for external atrraction data load --- vpr/src/pack/cluster.cpp | 7 +-- vpr/src/pack/cluster_util.cpp | 51 ++++++++++++++----- vpr/src/pack/cluster_util.h | 8 +-- vtr_flow/benchmarks/verilog/single_chain.v | 18 +++++++ .../pass_requirements_worse_cluster.txt | 3 ++ .../config/config.txt | 34 +++++++++++++ .../config/golden_results.txt | 2 + .../sample_external_attraction_data_2.xml | 28 ++++++++++ 8 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 vtr_flow/benchmarks/verilog/single_chain.v create mode 100644 vtr_flow/parse/pass_requirements/pass_requirements_worse_cluster.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/config.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/golden_results.txt create mode 100644 vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_cluster_external_attraction/config/sample_external_attraction_data_2.xml diff --git a/vpr/src/pack/cluster.cpp b/vpr/src/pack/cluster.cpp index 9c76c0374d8..7fd660c97a8 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -176,7 +176,7 @@ std::map do_clustering(const t_packer_opts& pa istart = nullptr; // load external attraction data - load_external_attraction_data(packer_opts.external_attraction_file); + 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(); @@ -299,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) { @@ -382,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); } diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 1d0008bf2fd..8892b1354a4 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -1618,7 +1618,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) { @@ -1677,7 +1678,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(); @@ -1690,6 +1692,18 @@ 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 @@ -1707,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)); @@ -1935,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. @@ -1960,12 +1978,17 @@ void update_cluster_stats(const t_pack_molecule* molecule, atom_ctx.lookup.set_atom_clb(blk_id, clb_index); //Update clustring clb to atoms mapping - if (static_cast(blk_id) >= cl_helper_ctx.incomplete_cluster_to_atoms_lookup.size()) { + 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); @@ -3845,7 +3868,7 @@ void init_clb_atoms_lookup(vtr::vector 1, "\nLoadign external attracion data\n"); // go through the file try { // load the file @@ -3885,7 +3908,9 @@ void load_external_attraction_data(const std::string& attraction_file) { double attraction_score = pugiutil::get_attribute(dst_node_tag, "score", loc_data, pugiutil::REQUIRED).as_double(); - VTR_LOG("attraction: score: %f, %d:%s -> %d:%s\n", attraction_score, src_block_id, src_node_name.c_str(), dst_block_id, dst_node_name.c_str()); + 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; } } @@ -3894,18 +3919,18 @@ void load_external_attraction_data(const std::string& attraction_file) { vpr_throw(VPR_ERROR_OTHER, attraction_file_char, e.line(), e.what()); } - VTR_LOG("\n=============================\n\n"); + VTR_LOGV(verbosity > 2,"\n=============================\n\n"); for (auto srckv : attraction_data) { for (auto dstkv : srckv.second) { - VTR_LOG("attraction: score: %f, %d -> %d\n", dstkv.second, srckv.first, dstkv.first); + 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()); - } + // 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 6b5a8e576d5..bdd7e18b7c9 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -262,7 +262,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, @@ -325,7 +326,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, @@ -486,5 +488,5 @@ 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); +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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 61d571f3a3082b58938023971cda86bf806345d0 Mon Sep 17 00:00:00 2001 From: Louis-He Date: Mon, 25 Sep 2023 23:59:09 -0400 Subject: [PATCH 4/6] fix bug: don't change default flow when there is no external attraction data --- vpr/src/pack/cluster_util.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 8892b1354a4..5abf545f4e9 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -3060,22 +3060,25 @@ float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_ } // Calculate the score affected by external atom attraction data - 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; - } + 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; - } + 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); + external_attraction_score += external_atom_attraction_data.at(blk).at(blk_id); + } } } From 12e801ef31b9e82eabba4114ff3664df77c65ea0 Mon Sep 17 00:00:00 2001 From: Louis-He Date: Tue, 26 Sep 2023 20:18:21 -0400 Subject: [PATCH 5/6] reformat Cpp code --- vpr/src/pack/cluster_util.cpp | 93 +++++++++++++++++------------------ vpr/src/pack/cluster_util.h | 22 +++++---- 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 5abf545f4e9..43fb86a3373 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -437,7 +437,8 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, int max_queue_size, AttractionInfo& attraction_groups, const std::unordered_map>& external_atom_attraction_data, - float external_attraction_default_weight, float external_attraction_default_value) { + float external_attraction_default_weight, + float external_attraction_default_value) { int i, j; int num_molecule_failures = 0; @@ -472,13 +473,13 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, if (pb->pb_stats->num_feasible_blocks >= max_queue_size - 1) { /* maximum size for array, remove smallest gain element and sort */ - 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)) { + 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 (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)) { + external_attraction_default_weight, external_attraction_default_value, num_molecule_failures)) { pb->pb_stats->feasible_blocks[j] = molecule; break; } else { @@ -493,7 +494,8 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, /* 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], 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) { + 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; @@ -1701,8 +1703,6 @@ void store_cluster_info_and_free(const t_packer_opts& packer_opts, } VTR_LOG("\n"); } - - auto cur_pb = cluster_ctx.clb_nlist.block_pb(clb_index); @@ -1984,8 +1984,7 @@ void update_cluster_stats(const t_pack_molecule* molecule, 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) - { + if (verbosity > 2) { VTR_LOG("Adding block %s to cluster %d\n", atom_ctx.nlist.block_name(blk_id).c_str(), clb_index); } @@ -2275,8 +2274,8 @@ 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_index, cluster_placement_stats_ptr, feasible_block_array_size, - attraction_groups, external_atom_attraction_data, external_attraction_default_weight, - external_attraction_default_value); + attraction_groups, external_atom_attraction_data, external_attraction_default_weight, + external_attraction_default_value); } if (prioritize_transitive_connectivity) { @@ -2291,15 +2290,15 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, // 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_index, cluster_placement_stats_ptr, feasible_block_array_size, - attraction_groups, external_atom_attraction_data, external_attraction_default_weight, - external_attraction_default_value); + 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_index, cluster_placement_stats_ptr, feasible_block_array_size, - attraction_groups, external_atom_attraction_data, external_attraction_default_weight, - external_attraction_default_value); + 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 @@ -2313,16 +2312,15 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb, // 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, external_atom_attraction_data, + 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, + 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); } @@ -2347,7 +2345,8 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, 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) { + 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; @@ -2381,7 +2380,8 @@ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, 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) { + 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 */ @@ -2432,7 +2432,8 @@ 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, + 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) { @@ -2557,7 +2558,8 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, 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) { + 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; @@ -2572,7 +2574,7 @@ 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, cluster_index, + 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); @@ -2581,24 +2583,23 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, } } -void add_cluster_molecule_candidates_by_external_attraction_data(t_pb * cur_pb, +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, + 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) { + 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 + // 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; @@ -3005,9 +3006,7 @@ t_pack_molecule* get_highest_gain_seed_molecule(int* seedindex, const std::vecto * - 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, 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 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; @@ -3038,7 +3037,7 @@ float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_ 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); @@ -3060,8 +3059,7 @@ float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_ } // Calculate the score affected by external atom attraction data - if (!external_atom_attraction_data.empty()) - { + 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); @@ -3071,8 +3069,7 @@ float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_ } auto dst_itr = itr->second.find(blk_id); - if (dst_itr == itr->second.end()) - { + if (dst_itr == itr->second.end()) { external_attraction_score += external_attraction_default_value; continue; } @@ -3081,7 +3078,7 @@ float get_molecule_gain(t_pack_molecule* molecule, const ClusterBlockId cluster_ } } } - + 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); @@ -3922,16 +3919,14 @@ void load_external_attraction_data(const std::string& attraction_file, const int vpr_throw(VPR_ERROR_OTHER, attraction_file_char, e.line(), e.what()); } - VTR_LOGV(verbosity > 2,"\n=============================\n\n"); + 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 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()); diff --git a/vpr/src/pack/cluster_util.h b/vpr/src/pack/cluster_util.h index 8655934c816..87737ddeb75 100644 --- a/vpr/src/pack/cluster_util.h +++ b/vpr/src/pack/cluster_util.h @@ -145,7 +145,8 @@ void add_molecule_to_pb_stats_candidates(t_pack_molecule* molecule, int max_queue_size, AttractionInfo& attraction_groups, const std::unordered_map>& external_atom_attraction_data, - float external_attraction_default_weight, float external_attraction_default_value); + float external_attraction_default_weight, + float external_attraction_default_value); void remove_molecule_from_pb_stats_candidates(t_pack_molecule* molecule, t_pb* pb); @@ -370,7 +371,8 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb, 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); + 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, @@ -378,13 +380,15 @@ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb, 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); + 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, + 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); @@ -397,7 +401,8 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb, 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); + 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, @@ -405,7 +410,8 @@ void add_cluster_molecule_candidates_by_external_attraction_data(t_pb* cur_pb, 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); + 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); @@ -441,9 +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, 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 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); From bb44c040c1666d01f7417b38d0774b89b8dcf402 Mon Sep 17 00:00:00 2001 From: Louis-He Date: Tue, 26 Sep 2023 21:36:35 -0400 Subject: [PATCH 6/6] fix compilation warning --- vpr/src/pack/cluster_util.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 43fb86a3373..3fa3fa49be9 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -3880,7 +3880,6 @@ void load_external_attraction_data(const std::string& attraction_file, const int } auto& atom_ctx = g_vpr_ctx.atom(); - size_t num_atom = atom_ctx.nlist.blocks().size(); // initialize external attraction data in clustering helper context auto& attraction_data = g_vpr_ctx.mutable_cl_helper().external_atom_attraction_data;