@@ -216,13 +216,11 @@ ClusterGainStats GreedyCandidateSelector::create_cluster_gain_stats(
216
216
// Initialize the cluster gain stats.
217
217
ClusterGainStats cluster_gain_stats;
218
218
cluster_gain_stats.seed_molecule_id = cluster_seed_mol_id;
219
- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
220
219
cluster_gain_stats.has_done_connectivity_and_timing = false ;
221
- // TODO: The reason this is being resized and not reserved is due to legacy
222
- // code which should be updated.
223
- cluster_gain_stats.feasible_blocks .resize (packer_opts_.feasible_block_array_size );
224
- for (int i = 0 ; i < packer_opts_.feasible_block_array_size ; i++)
225
- cluster_gain_stats.feasible_blocks [i] = PackMoleculeId::INVALID ();
220
+ cluster_gain_stats.initial_search_for_feasible_blocks = true ;
221
+ cluster_gain_stats.num_search_for_feasible_blocks_occured = 0 ;
222
+ cluster_gain_stats.num_search_for_feasible_blocks_occurred_limit = packer_opts_.feasible_block_array_size ;
223
+ cluster_gain_stats.feasible_blocks .clear ();
226
224
cluster_gain_stats.tie_break_high_fanout_net = AtomNetId::INVALID ();
227
225
cluster_gain_stats.explore_transitive_fanout = true ;
228
226
@@ -285,8 +283,10 @@ void GreedyCandidateSelector::update_cluster_gain_stats_candidate_success(
285
283
AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group (blk_id);
286
284
287
285
/* reset list of feasible blocks */
288
- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
289
286
cluster_gain_stats.has_done_connectivity_and_timing = false ;
287
+ cluster_gain_stats.initial_search_for_feasible_blocks = true ;
288
+ cluster_gain_stats.num_search_for_feasible_blocks_occured = 0 ;
289
+ cluster_gain_stats.feasible_blocks .clear ();
290
290
/* TODO: Allow clusters to have more than one attraction group. */
291
291
if (atom_grp_id.is_valid ())
292
292
cluster_gain_stats.attraction_grp_id = atom_grp_id;
@@ -681,8 +681,7 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
681
681
*/
682
682
683
683
// 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster
684
- if (cluster_gain_stats.num_feasible_blocks == NOT_VALID) {
685
- cluster_gain_stats.num_feasible_blocks = 0 ;
684
+ if (cluster_gain_stats.initial_search_for_feasible_blocks ) {
686
685
add_cluster_molecule_candidates_by_connectivity_and_timing (cluster_gain_stats,
687
686
cluster_id,
688
687
cluster_legalizer,
@@ -692,31 +691,31 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
692
691
693
692
if (packer_opts_.prioritize_transitive_connectivity ) {
694
693
// 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
695
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
694
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.explore_transitive_fanout ) {
696
695
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
697
696
cluster_id,
698
697
cluster_legalizer,
699
698
attraction_groups);
700
699
}
701
700
702
701
// 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
703
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
702
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
704
703
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
705
704
cluster_id,
706
705
cluster_legalizer,
707
706
attraction_groups);
708
707
}
709
708
} else { // Reverse order
710
709
// 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
711
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
710
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
712
711
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
713
712
cluster_id,
714
713
cluster_legalizer,
715
714
attraction_groups);
716
715
}
717
716
718
717
// 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
719
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
718
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.explore_transitive_fanout ) {
720
719
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
721
720
cluster_id,
722
721
cluster_legalizer,
@@ -725,21 +724,35 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
725
724
}
726
725
727
726
// 4. Find unpacked molecules based on attraction group of the current cluster (if the cluster has an attraction group)
728
- if (cluster_gain_stats.num_feasible_blocks == 0 ) {
727
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 ) {
729
728
add_cluster_molecule_candidates_by_attraction_group (cluster_gain_stats,
730
729
cluster_id,
731
730
cluster_legalizer,
732
731
attraction_groups);
733
732
}
734
733
735
734
/* Grab highest gain molecule */
736
- // If this was a vector, this would just be a pop_back.
737
735
PackMoleculeId best_molecule = PackMoleculeId::INVALID ();
738
- if (cluster_gain_stats.num_feasible_blocks > 0 ) {
739
- cluster_gain_stats.num_feasible_blocks --;
740
- int index = cluster_gain_stats.num_feasible_blocks ;
741
- best_molecule = cluster_gain_stats.feasible_blocks [index ];
742
- VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
736
+ // checking if there are feasible blocks being proposed
737
+ // checking if number of suggestion reached the limit
738
+ if (cluster_gain_stats.feasible_blocks .size () > 0 && cluster_gain_stats.num_search_for_feasible_blocks_occured < cluster_gain_stats.num_search_for_feasible_blocks_occurred_limit ) {
739
+ best_molecule = cluster_gain_stats.feasible_blocks .pop ().first ;
740
+ if (best_molecule != PackMoleculeId::INVALID ()) {
741
+ cluster_gain_stats.num_search_for_feasible_blocks_occured ++;
742
+ VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
743
+ }
744
+ }
745
+
746
+ // If we have no feasible blocks, or we have reached the limit of number of pops,
747
+ // then we need to clear the feasible blocks list and reset the number of pops.
748
+ // This ensures that we can continue searching for feasible blocks for the remaining
749
+ // steps (2.transitive, 3.high fanout, 4.attraction group).
750
+ if (cluster_gain_stats.feasible_blocks .size () == 0 ||
751
+ cluster_gain_stats.num_search_for_feasible_blocks_occured >= cluster_gain_stats.num_search_for_feasible_blocks_occurred_limit ||
752
+ cluster_gain_stats.feasible_blocks .delete_pending_set .size () == cluster_gain_stats.feasible_blocks .content_set .size ()
753
+ ){
754
+ cluster_gain_stats.feasible_blocks .clear ();
755
+ cluster_gain_stats.num_search_for_feasible_blocks_occured = 0 ;
743
756
}
744
757
745
758
// If we are allowing unrelated clustering and no molecule has been found,
@@ -775,6 +788,9 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
775
788
LegalizationClusterId legalization_cluster_id,
776
789
const ClusterLegalizer& cluster_legalizer,
777
790
AttractionInfo& attraction_groups) {
791
+
792
+ VTR_ASSERT (cluster_gain_stats.initial_search_for_feasible_blocks );
793
+ cluster_gain_stats.initial_search_for_feasible_blocks = false ;
778
794
cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
779
795
780
796
for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks ) {
@@ -1001,45 +1017,17 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1001
1017
}
1002
1018
}
1003
1019
1004
- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1005
- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1006
- return ; // already in queue, do nothing
1007
- }
1020
+ // if already in queue, do nothing
1021
+ if (cluster_gain_stats.feasible_blocks .contains (molecule_id)) {
1022
+ return ;
1008
1023
}
1009
1024
1010
- if (cluster_gain_stats.num_feasible_blocks >= max_queue_size - 1 ) {
1011
- /* maximum size for array, remove smallest gain element and sort */
1012
- 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)) {
1013
- /* single loop insertion sort */
1014
- int j;
1015
- for (j = 0 ; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1016
- 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)) {
1017
- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1018
- break ;
1019
- } else {
1020
- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1021
- }
1022
- }
1023
- if (j == cluster_gain_stats.num_feasible_blocks - 1 ) {
1024
- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1025
- }
1026
- }
1027
- } else {
1028
- /* Expand array and single loop insertion sort */
1029
- int j;
1030
- for (j = cluster_gain_stats.num_feasible_blocks - 1 ; j >= 0 ; j--) {
1031
- 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)) {
1032
- cluster_gain_stats.feasible_blocks [j + 1 ] = cluster_gain_stats.feasible_blocks [j];
1033
- } else {
1034
- cluster_gain_stats.feasible_blocks [j + 1 ] = molecule_id;
1035
- break ;
1036
- }
1037
- }
1038
- if (j < 0 ) {
1039
- cluster_gain_stats.feasible_blocks [0 ] = molecule_id;
1040
- }
1041
- cluster_gain_stats.num_feasible_blocks ++;
1025
+ for (std::pair<PackMoleculeId, float >& feasible_block : cluster_gain_stats.feasible_blocks .heap ) {
1026
+ 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 );
1042
1027
}
1028
+
1029
+ // Insert the molecule into the queue sorted by gain, and maintain the heap property
1030
+ cluster_gain_stats.feasible_blocks .push (molecule_id, get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx));
1043
1031
}
1044
1032
1045
1033
/*
@@ -1050,27 +1038,7 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1050
1038
*/
1051
1039
static void remove_molecule_from_pb_stats_candidates (PackMoleculeId molecule_id,
1052
1040
ClusterGainStats& cluster_gain_stats) {
1053
- int molecule_index;
1054
- bool found_molecule = false ;
1055
-
1056
- // find the molecule index
1057
- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1058
- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1059
- found_molecule = true ;
1060
- molecule_index = i;
1061
- }
1062
- }
1063
-
1064
- // if it is not in the array, return
1065
- if (found_molecule == false ) {
1066
- return ;
1067
- }
1068
-
1069
- // Otherwise, shift the molecules while removing the specified molecule
1070
- for (int j = molecule_index; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1071
- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1072
- }
1073
- cluster_gain_stats.num_feasible_blocks --;
1041
+ cluster_gain_stats.feasible_blocks .remove_at_pop_time (molecule_id);
1074
1042
}
1075
1043
1076
1044
/*
0 commit comments