@@ -64,7 +64,6 @@ static void add_molecule_to_pb_stats_candidates(
6464 PackMoleculeId molecule_id,
6565 ClusterGainStats& cluster_gain_stats,
6666 t_logical_block_type_ptr cluster_type,
67- int max_queue_size,
6867 AttractionInfo& attraction_groups,
6968 const Prepacker& prepacker,
7069 const AtomNetlist& atom_netlist,
@@ -219,13 +218,11 @@ ClusterGainStats GreedyCandidateSelector::create_cluster_gain_stats(
219218 // Initialize the cluster gain stats.
220219 ClusterGainStats cluster_gain_stats;
221220 cluster_gain_stats.seed_molecule_id = cluster_seed_mol_id;
222- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
223221 cluster_gain_stats.has_done_connectivity_and_timing = false ;
224- // TODO: The reason this is being resized and not reserved is due to legacy
225- // code which should be updated.
226- cluster_gain_stats.feasible_blocks .resize (packer_opts_.feasible_block_array_size );
227- for (int i = 0 ; i < packer_opts_.feasible_block_array_size ; i++)
228- cluster_gain_stats.feasible_blocks [i] = PackMoleculeId::INVALID ();
222+ cluster_gain_stats.initial_search_for_feasible_blocks = true ;
223+ cluster_gain_stats.num_candidates_proposed = 0 ;
224+ cluster_gain_stats.candidates_propose_limit = packer_opts_.feasible_block_array_size ;
225+ cluster_gain_stats.feasible_blocks .clear ();
229226 cluster_gain_stats.tie_break_high_fanout_net = AtomNetId::INVALID ();
230227 cluster_gain_stats.explore_transitive_fanout = true ;
231228
@@ -288,8 +285,10 @@ void GreedyCandidateSelector::update_cluster_gain_stats_candidate_success(
288285 AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group (blk_id);
289286
290287 /* reset list of feasible blocks */
291- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
292288 cluster_gain_stats.has_done_connectivity_and_timing = false ;
289+ cluster_gain_stats.initial_search_for_feasible_blocks = true ;
290+ cluster_gain_stats.num_candidates_proposed = 0 ;
291+ cluster_gain_stats.feasible_blocks .clear ();
293292 /* TODO: Allow clusters to have more than one attraction group. */
294293 if (atom_grp_id.is_valid ())
295294 cluster_gain_stats.attraction_grp_id = atom_grp_id;
@@ -680,8 +679,8 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
680679 */
681680
682681 // 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster
683- if (cluster_gain_stats.num_feasible_blocks == NOT_VALID ) {
684- cluster_gain_stats.num_feasible_blocks = 0 ;
682+ if (cluster_gain_stats.initial_search_for_feasible_blocks ) {
683+ cluster_gain_stats.initial_search_for_feasible_blocks = false ;
685684 add_cluster_molecule_candidates_by_connectivity_and_timing (cluster_gain_stats,
686685 cluster_id,
687686 cluster_legalizer,
@@ -691,31 +690,31 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
691690
692691 if (packer_opts_.prioritize_transitive_connectivity ) {
693692 // 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
694- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
693+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.explore_transitive_fanout ) {
695694 add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
696695 cluster_id,
697696 cluster_legalizer,
698697 attraction_groups);
699698 }
700699
701700 // 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
702- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
701+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.tie_break_high_fanout_net ) {
703702 add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
704703 cluster_id,
705704 cluster_legalizer,
706705 attraction_groups);
707706 }
708707 } else { // Reverse order
709708 // 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
710- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
709+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.tie_break_high_fanout_net ) {
711710 add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
712711 cluster_id,
713712 cluster_legalizer,
714713 attraction_groups);
715714 }
716715
717716 // 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
718- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
717+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.explore_transitive_fanout ) {
719718 add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
720719 cluster_id,
721720 cluster_legalizer,
@@ -724,23 +723,33 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
724723 }
725724
726725 // 4. Find unpacked molecules based on attraction group of the current cluster (if the cluster has an attraction group)
727- if (cluster_gain_stats.num_feasible_blocks == 0 ) {
726+ if (cluster_gain_stats.feasible_blocks . empty () ) {
728727 add_cluster_molecule_candidates_by_attraction_group (cluster_gain_stats,
729728 cluster_id,
730729 cluster_legalizer,
731730 attraction_groups);
732731 }
733732
734733 /* Grab highest gain molecule */
735- // If this was a vector, this would just be a pop_back.
736734 PackMoleculeId best_molecule = PackMoleculeId::INVALID ();
737- if (cluster_gain_stats.num_feasible_blocks > 0 ) {
738- cluster_gain_stats.num_feasible_blocks --;
739- int index = cluster_gain_stats.num_feasible_blocks ;
740- best_molecule = cluster_gain_stats.feasible_blocks [index];
735+ // If there are feasible blocks being proposed and the number of suggestions did not reach the limit.
736+ // Get the block with highest gain from the top of the priority queue.
737+ if (!cluster_gain_stats.feasible_blocks .empty () && !cluster_gain_stats.current_stage_candidates_proposed_limit_reached ()) {
738+ best_molecule = cluster_gain_stats.feasible_blocks .pop ().first ;
739+ VTR_ASSERT (best_molecule != PackMoleculeId::INVALID ());
740+ cluster_gain_stats.num_candidates_proposed ++;
741741 VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
742742 }
743743
744+ // If we have no feasible blocks, or we have reached the limit of number of pops,
745+ // then we need to clear the feasible blocks list and reset the number of pops.
746+ // This ensures that we can continue searching for feasible blocks for the remaining
747+ // steps (2.transitive, 3.high fanout, 4.attraction group).
748+ if (cluster_gain_stats.feasible_blocks .empty () || cluster_gain_stats.current_stage_candidates_proposed_limit_reached ()) {
749+ cluster_gain_stats.feasible_blocks .clear ();
750+ cluster_gain_stats.num_candidates_proposed = 0 ;
751+ }
752+
744753 // If we are allowing unrelated clustering and no molecule has been found,
745754 // get unrelated candidate for cluster.
746755 if (allow_unrelated_clustering_ && best_molecule == PackMoleculeId::INVALID ()) {
@@ -774,7 +783,9 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
774783 LegalizationClusterId legalization_cluster_id,
775784 const ClusterLegalizer& cluster_legalizer,
776785 AttractionInfo& attraction_groups) {
777- cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
786+
787+ cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
788+ cluster_gain_stats.candidates_propose_limit = packer_opts_.feasible_block_array_size ; // set the limit of candidates to propose
778789
779790 for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks ) {
780791 // Get the molecule that contains this block.
@@ -785,7 +796,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
785796 add_molecule_to_pb_stats_candidates (molecule_id,
786797 cluster_gain_stats,
787798 cluster_legalizer.get_cluster_type (legalization_cluster_id),
788- packer_opts_.feasible_block_array_size ,
789799 attraction_groups,
790800 prepacker_,
791801 atom_netlist_,
@@ -801,6 +811,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
801811 AttractionInfo& attraction_groups) {
802812 // TODO: For now, only done by fan-out; should also consider fan-in
803813 cluster_gain_stats.explore_transitive_fanout = false ;
814+ cluster_gain_stats.candidates_propose_limit = std::min (packer_opts_.feasible_block_array_size , AAPACK_MAX_TRANSITIVE_EXPLORE); // set the limit of candidates to propose
804815
805816 /* First time finding transitive fanout candidates therefore alloc and load them */
806817 load_transitive_fanout_candidates (cluster_gain_stats,
@@ -814,8 +825,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
814825 add_molecule_to_pb_stats_candidates (molecule_id,
815826 cluster_gain_stats,
816827 cluster_legalizer.get_cluster_type (legalization_cluster_id),
817- std::min (packer_opts_.feasible_block_array_size ,
818- AAPACK_MAX_TRANSITIVE_EXPLORE),
819828 attraction_groups,
820829 prepacker_,
821830 atom_netlist_,
@@ -834,6 +843,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
834843 * related blocks */
835844
836845 AtomNetId net_id = cluster_gain_stats.tie_break_high_fanout_net ;
846+ cluster_gain_stats.candidates_propose_limit = std::min (packer_opts_.feasible_block_array_size , AAPACK_MAX_TRANSITIVE_EXPLORE); // set the limit of candidates to propose
837847
838848 int count = 0 ;
839849 for (AtomPinId pin_id : atom_netlist_.net_pins (net_id)) {
@@ -848,8 +858,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
848858 add_molecule_to_pb_stats_candidates (molecule_id,
849859 cluster_gain_stats,
850860 cluster_legalizer.get_cluster_type (legalization_cluster_id),
851- std::min (packer_opts_.feasible_block_array_size ,
852- AAPACK_MAX_HIGH_FANOUT_EXPLORE),
853861 attraction_groups,
854862 prepacker_,
855863 atom_netlist_,
@@ -877,6 +885,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
877885 * group molecules for candidate molecules.
878886 */
879887 AttractGroupId grp_id = cluster_gain_stats.attraction_grp_id ;
888+ cluster_gain_stats.candidates_propose_limit = packer_opts_.feasible_block_array_size ; // set the limit of candidates to propose
880889 if (grp_id == AttractGroupId::INVALID ()) {
881890 return ;
882891 }
@@ -909,7 +918,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
909918 add_molecule_to_pb_stats_candidates (molecule_id,
910919 cluster_gain_stats,
911920 cluster_legalizer.get_cluster_type (legalization_cluster_id),
912- packer_opts_.feasible_block_array_size ,
913921 attraction_groups,
914922 prepacker_,
915923 atom_netlist_,
@@ -931,7 +939,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
931939 add_molecule_to_pb_stats_candidates (molecule_id,
932940 cluster_gain_stats,
933941 cluster_legalizer.get_cluster_type (legalization_cluster_id),
934- packer_opts_.feasible_block_array_size ,
935942 attraction_groups,
936943 prepacker_,
937944 atom_netlist_,
@@ -946,7 +953,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
946953static void add_molecule_to_pb_stats_candidates (PackMoleculeId molecule_id,
947954 ClusterGainStats& cluster_gain_stats,
948955 t_logical_block_type_ptr cluster_type,
949- int max_queue_size,
950956 AttractionInfo& attraction_groups,
951957 const Prepacker& prepacker,
952958 const AtomNetlist& atom_netlist,
@@ -996,45 +1002,18 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
9961002 }
9971003 }
9981004
999- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1000- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1001- return ; // already in queue, do nothing
1002- }
1005+ // if already in queue, do nothing
1006+ if (cluster_gain_stats.feasible_blocks .contains (molecule_id)) {
1007+ return ;
10031008 }
10041009
1005- if (cluster_gain_stats.num_feasible_blocks >= max_queue_size - 1 ) {
1006- /* maximum size for array, remove smallest gain element and sort */
1007- if (get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx) > get_molecule_gain (cluster_gain_stats.feasible_blocks [0 ], cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx)) {
1008- /* single loop insertion sort */
1009- int j;
1010- for (j = 0 ; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1011- if (get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx) <= get_molecule_gain (cluster_gain_stats.feasible_blocks [j + 1 ], cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx)) {
1012- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1013- break ;
1014- } else {
1015- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1016- }
1017- }
1018- if (j == cluster_gain_stats.num_feasible_blocks - 1 ) {
1019- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1020- }
1021- }
1022- } else {
1023- /* Expand array and single loop insertion sort */
1024- int j;
1025- for (j = cluster_gain_stats.num_feasible_blocks - 1 ; j >= 0 ; j--) {
1026- if (get_molecule_gain (cluster_gain_stats.feasible_blocks [j], cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx) > get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx)) {
1027- cluster_gain_stats.feasible_blocks [j + 1 ] = cluster_gain_stats.feasible_blocks [j];
1028- } else {
1029- cluster_gain_stats.feasible_blocks [j + 1 ] = molecule_id;
1030- break ;
1031- }
1032- }
1033- if (j < 0 ) {
1034- cluster_gain_stats.feasible_blocks [0 ] = molecule_id;
1035- }
1036- cluster_gain_stats.num_feasible_blocks ++;
1010+ for (std::pair<PackMoleculeId, float >& feasible_block : cluster_gain_stats.feasible_blocks .heap ) {
1011+ VTR_ASSERT_DEBUG (get_molecule_gain (feasible_block.first , cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx) == feasible_block.second );
10371012 }
1013+
1014+ // Insert the molecule into the queue sorted by gain, and maintain the heap property
1015+ float molecule_gain = get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx);
1016+ cluster_gain_stats.feasible_blocks .push (molecule_id, molecule_gain);
10381017}
10391018
10401019/*
@@ -1045,27 +1024,7 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
10451024 */
10461025static void remove_molecule_from_pb_stats_candidates (PackMoleculeId molecule_id,
10471026 ClusterGainStats& cluster_gain_stats) {
1048- int molecule_index;
1049- bool found_molecule = false ;
1050-
1051- // find the molecule index
1052- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1053- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1054- found_molecule = true ;
1055- molecule_index = i;
1056- }
1057- }
1058-
1059- // if it is not in the array, return
1060- if (found_molecule == false ) {
1061- return ;
1062- }
1063-
1064- // Otherwise, shift the molecules while removing the specified molecule
1065- for (int j = molecule_index; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1066- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1067- }
1068- cluster_gain_stats.num_feasible_blocks --;
1027+ cluster_gain_stats.feasible_blocks .remove_at_pop_time (molecule_id);
10691028}
10701029
10711030/*
0 commit comments