@@ -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,8 @@ 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 ) {
685
+ cluster_gain_stats.initial_search_for_feasible_blocks = false ;
686
686
add_cluster_molecule_candidates_by_connectivity_and_timing (cluster_gain_stats,
687
687
cluster_id,
688
688
cluster_legalizer,
@@ -692,31 +692,31 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
692
692
693
693
if (packer_opts_.prioritize_transitive_connectivity ) {
694
694
// 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 ) {
695
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.explore_transitive_fanout ) {
696
696
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
697
697
cluster_id,
698
698
cluster_legalizer,
699
699
attraction_groups);
700
700
}
701
701
702
702
// 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 ) {
703
+ 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
704
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
705
705
cluster_id,
706
706
cluster_legalizer,
707
707
attraction_groups);
708
708
}
709
709
} else { // Reverse order
710
710
// 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 ) {
711
+ 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
712
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
713
713
cluster_id,
714
714
cluster_legalizer,
715
715
attraction_groups);
716
716
}
717
717
718
718
// 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 ) {
719
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 && cluster_gain_stats.explore_transitive_fanout ) {
720
720
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
721
721
cluster_id,
722
722
cluster_legalizer,
@@ -725,21 +725,35 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
725
725
}
726
726
727
727
// 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 ) {
728
+ if (! cluster_gain_stats.initial_search_for_feasible_blocks && cluster_gain_stats. feasible_blocks . size () == 0 ) {
729
729
add_cluster_molecule_candidates_by_attraction_group (cluster_gain_stats,
730
730
cluster_id,
731
731
cluster_legalizer,
732
732
attraction_groups);
733
733
}
734
734
735
735
/* Grab highest gain molecule */
736
- // If this was a vector, this would just be a pop_back.
737
736
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));
737
+ // checking if there are feasible blocks being proposed
738
+ // checking if number of suggestion reached the limit
739
+ 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 ) {
740
+ best_molecule = cluster_gain_stats.feasible_blocks .pop ().first ;
741
+ if (best_molecule != PackMoleculeId::INVALID ()) {
742
+ cluster_gain_stats.num_search_for_feasible_blocks_occured ++;
743
+ VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
744
+ }
745
+ }
746
+
747
+ // If we have no feasible blocks, or we have reached the limit of number of pops,
748
+ // then we need to clear the feasible blocks list and reset the number of pops.
749
+ // This ensures that we can continue searching for feasible blocks for the remaining
750
+ // steps (2.transitive, 3.high fanout, 4.attraction group).
751
+ if (cluster_gain_stats.feasible_blocks .size () == 0 ||
752
+ cluster_gain_stats.num_search_for_feasible_blocks_occured >= cluster_gain_stats.num_search_for_feasible_blocks_occurred_limit ||
753
+ cluster_gain_stats.feasible_blocks .delete_pending_set .size () == cluster_gain_stats.feasible_blocks .content_set .size ()
754
+ ){
755
+ cluster_gain_stats.feasible_blocks .clear ();
756
+ cluster_gain_stats.num_search_for_feasible_blocks_occured = 0 ;
743
757
}
744
758
745
759
// If we are allowing unrelated clustering and no molecule has been found,
@@ -775,6 +789,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
775
789
LegalizationClusterId legalization_cluster_id,
776
790
const ClusterLegalizer& cluster_legalizer,
777
791
AttractionInfo& attraction_groups) {
792
+
778
793
cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
779
794
780
795
for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks ) {
@@ -1001,45 +1016,17 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1001
1016
}
1002
1017
}
1003
1018
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
- }
1019
+ // if already in queue, do nothing
1020
+ if (cluster_gain_stats.feasible_blocks .contains (molecule_id)) {
1021
+ return ;
1008
1022
}
1009
1023
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 ++;
1024
+ for (std::pair<PackMoleculeId, float >& feasible_block : cluster_gain_stats.feasible_blocks .heap ) {
1025
+ 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
1026
}
1027
+
1028
+ // Insert the molecule into the queue sorted by gain, and maintain the heap property
1029
+ 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
1030
}
1044
1031
1045
1032
/*
@@ -1050,27 +1037,7 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1050
1037
*/
1051
1038
static void remove_molecule_from_pb_stats_candidates (PackMoleculeId molecule_id,
1052
1039
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 --;
1040
+ cluster_gain_stats.feasible_blocks .remove_at_pop_time (molecule_id);
1074
1041
}
1075
1042
1076
1043
/*
0 commit comments