@@ -64,7 +64,6 @@ static void add_molecule_to_pb_stats_candidates(
64
64
PackMoleculeId molecule_id,
65
65
ClusterGainStats& cluster_gain_stats,
66
66
t_logical_block_type_ptr cluster_type,
67
- int max_queue_size,
68
67
AttractionInfo& attraction_groups,
69
68
const Prepacker& prepacker,
70
69
const AtomNetlist& atom_netlist,
@@ -219,13 +218,11 @@ ClusterGainStats GreedyCandidateSelector::create_cluster_gain_stats(
219
218
// Initialize the cluster gain stats.
220
219
ClusterGainStats cluster_gain_stats;
221
220
cluster_gain_stats.seed_molecule_id = cluster_seed_mol_id;
222
- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
223
221
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 ();
229
226
cluster_gain_stats.tie_break_high_fanout_net = AtomNetId::INVALID ();
230
227
cluster_gain_stats.explore_transitive_fanout = true ;
231
228
@@ -288,8 +285,10 @@ void GreedyCandidateSelector::update_cluster_gain_stats_candidate_success(
288
285
AttractGroupId atom_grp_id = attraction_groups.get_atom_attraction_group (blk_id);
289
286
290
287
/* reset list of feasible blocks */
291
- cluster_gain_stats.num_feasible_blocks = NOT_VALID;
292
288
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 ();
293
292
/* TODO: Allow clusters to have more than one attraction group. */
294
293
if (atom_grp_id.is_valid ())
295
294
cluster_gain_stats.attraction_grp_id = atom_grp_id;
@@ -684,8 +683,8 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
684
683
*/
685
684
686
685
// 1. Find unpacked molecules based on criticality and strong connectedness (connected by low fanout nets) with current cluster
687
- if (cluster_gain_stats.num_feasible_blocks == NOT_VALID ) {
688
- cluster_gain_stats.num_feasible_blocks = 0 ;
686
+ if (cluster_gain_stats.initial_search_for_feasible_blocks ) {
687
+ cluster_gain_stats.initial_search_for_feasible_blocks = false ;
689
688
add_cluster_molecule_candidates_by_connectivity_and_timing (cluster_gain_stats,
690
689
cluster_id,
691
690
cluster_legalizer,
@@ -695,31 +694,31 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
695
694
696
695
if (packer_opts_.prioritize_transitive_connectivity ) {
697
696
// 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
698
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
697
+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.explore_transitive_fanout ) {
699
698
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
700
699
cluster_id,
701
700
cluster_legalizer,
702
701
attraction_groups);
703
702
}
704
703
705
704
// 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
706
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
705
+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.tie_break_high_fanout_net ) {
707
706
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
708
707
cluster_id,
709
708
cluster_legalizer,
710
709
attraction_groups);
711
710
}
712
711
} else { // Reverse order
713
712
// 3. Find unpacked molecules based on weak connectedness (connected by high fanout nets) with current cluster
714
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.tie_break_high_fanout_net ) {
713
+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.tie_break_high_fanout_net ) {
715
714
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
716
715
cluster_id,
717
716
cluster_legalizer,
718
717
attraction_groups);
719
718
}
720
719
721
720
// 2. Find unpacked molecules based on transitive connections (eg. 2 hops away) with current cluster
722
- if (cluster_gain_stats.num_feasible_blocks == 0 && cluster_gain_stats.explore_transitive_fanout ) {
721
+ if (cluster_gain_stats.feasible_blocks . empty () && cluster_gain_stats.explore_transitive_fanout ) {
723
722
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
724
723
cluster_id,
725
724
cluster_legalizer,
@@ -728,23 +727,33 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
728
727
}
729
728
730
729
// 4. Find unpacked molecules based on attraction group of the current cluster (if the cluster has an attraction group)
731
- if (cluster_gain_stats.num_feasible_blocks == 0 ) {
730
+ if (cluster_gain_stats.feasible_blocks . empty () ) {
732
731
add_cluster_molecule_candidates_by_attraction_group (cluster_gain_stats,
733
732
cluster_id,
734
733
cluster_legalizer,
735
734
attraction_groups);
736
735
}
737
736
738
737
/* Grab highest gain molecule */
739
- // If this was a vector, this would just be a pop_back.
740
738
PackMoleculeId best_molecule = PackMoleculeId::INVALID ();
741
- if (cluster_gain_stats.num_feasible_blocks > 0 ) {
742
- cluster_gain_stats.num_feasible_blocks --;
743
- int index = cluster_gain_stats.num_feasible_blocks ;
744
- best_molecule = cluster_gain_stats.feasible_blocks [index ];
739
+ // If there are feasible blocks being proposed and the number of suggestions did not reach the limit.
740
+ // Get the block with highest gain from the top of the priority queue.
741
+ if (!cluster_gain_stats.feasible_blocks .empty () && !cluster_gain_stats.current_stage_candidates_proposed_limit_reached ()) {
742
+ best_molecule = cluster_gain_stats.feasible_blocks .pop ().first ;
743
+ VTR_ASSERT (best_molecule != PackMoleculeId::INVALID ());
744
+ cluster_gain_stats.num_candidates_proposed ++;
745
745
VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
746
746
}
747
747
748
+ // If we have no feasible blocks, or we have reached the limit of number of pops,
749
+ // then we need to clear the feasible blocks list and reset the number of pops.
750
+ // This ensures that we can continue searching for feasible blocks for the remaining
751
+ // steps (2.transitive, 3.high fanout, 4.attraction group).
752
+ if (cluster_gain_stats.feasible_blocks .empty () || cluster_gain_stats.current_stage_candidates_proposed_limit_reached ()) {
753
+ cluster_gain_stats.feasible_blocks .clear ();
754
+ cluster_gain_stats.num_candidates_proposed = 0 ;
755
+ }
756
+
748
757
// If we are allowing unrelated clustering and no molecule has been found,
749
758
// get unrelated candidate for cluster.
750
759
if (allow_unrelated_clustering_ && best_molecule == PackMoleculeId::INVALID ()) {
@@ -778,7 +787,9 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
778
787
LegalizationClusterId legalization_cluster_id,
779
788
const ClusterLegalizer& cluster_legalizer,
780
789
AttractionInfo& attraction_groups) {
781
- cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
790
+
791
+ cluster_gain_stats.explore_transitive_fanout = true ; /* If no legal molecules found, enable exploration of molecules two hops away */
792
+ cluster_gain_stats.candidates_propose_limit = packer_opts_.feasible_block_array_size ; // set the limit of candidates to propose
782
793
783
794
for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks ) {
784
795
// Get the molecule that contains this block.
@@ -789,7 +800,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
789
800
add_molecule_to_pb_stats_candidates (molecule_id,
790
801
cluster_gain_stats,
791
802
cluster_legalizer.get_cluster_type (legalization_cluster_id),
792
- packer_opts_.feasible_block_array_size ,
793
803
attraction_groups,
794
804
prepacker_,
795
805
atom_netlist_,
@@ -805,6 +815,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
805
815
AttractionInfo& attraction_groups) {
806
816
// TODO: For now, only done by fan-out; should also consider fan-in
807
817
cluster_gain_stats.explore_transitive_fanout = false ;
818
+ 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
808
819
809
820
/* First time finding transitive fanout candidates therefore alloc and load them */
810
821
load_transitive_fanout_candidates (cluster_gain_stats,
@@ -818,8 +829,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
818
829
add_molecule_to_pb_stats_candidates (molecule_id,
819
830
cluster_gain_stats,
820
831
cluster_legalizer.get_cluster_type (legalization_cluster_id),
821
- std::min (packer_opts_.feasible_block_array_size ,
822
- AAPACK_MAX_TRANSITIVE_EXPLORE),
823
832
attraction_groups,
824
833
prepacker_,
825
834
atom_netlist_,
@@ -838,6 +847,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
838
847
* related blocks */
839
848
840
849
AtomNetId net_id = cluster_gain_stats.tie_break_high_fanout_net ;
850
+ 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
841
851
842
852
int count = 0 ;
843
853
for (AtomPinId pin_id : atom_netlist_.net_pins (net_id)) {
@@ -852,8 +862,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
852
862
add_molecule_to_pb_stats_candidates (molecule_id,
853
863
cluster_gain_stats,
854
864
cluster_legalizer.get_cluster_type (legalization_cluster_id),
855
- std::min (packer_opts_.feasible_block_array_size ,
856
- AAPACK_MAX_HIGH_FANOUT_EXPLORE),
857
865
attraction_groups,
858
866
prepacker_,
859
867
atom_netlist_,
@@ -881,6 +889,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
881
889
* group molecules for candidate molecules.
882
890
*/
883
891
AttractGroupId grp_id = cluster_gain_stats.attraction_grp_id ;
892
+ cluster_gain_stats.candidates_propose_limit = packer_opts_.feasible_block_array_size ; // set the limit of candidates to propose
884
893
if (grp_id == AttractGroupId::INVALID ()) {
885
894
return ;
886
895
}
@@ -913,7 +922,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
913
922
add_molecule_to_pb_stats_candidates (molecule_id,
914
923
cluster_gain_stats,
915
924
cluster_legalizer.get_cluster_type (legalization_cluster_id),
916
- packer_opts_.feasible_block_array_size ,
917
925
attraction_groups,
918
926
prepacker_,
919
927
atom_netlist_,
@@ -935,7 +943,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
935
943
add_molecule_to_pb_stats_candidates (molecule_id,
936
944
cluster_gain_stats,
937
945
cluster_legalizer.get_cluster_type (legalization_cluster_id),
938
- packer_opts_.feasible_block_array_size ,
939
946
attraction_groups,
940
947
prepacker_,
941
948
atom_netlist_,
@@ -950,7 +957,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
950
957
static void add_molecule_to_pb_stats_candidates (PackMoleculeId molecule_id,
951
958
ClusterGainStats& cluster_gain_stats,
952
959
t_logical_block_type_ptr cluster_type,
953
- int max_queue_size,
954
960
AttractionInfo& attraction_groups,
955
961
const Prepacker& prepacker,
956
962
const AtomNetlist& atom_netlist,
@@ -1004,45 +1010,18 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1004
1010
}
1005
1011
}
1006
1012
1007
- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1008
- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1009
- return ; // already in queue, do nothing
1010
- }
1013
+ // if already in queue, do nothing
1014
+ if (cluster_gain_stats.feasible_blocks .contains (molecule_id)) {
1015
+ return ;
1011
1016
}
1012
1017
1013
- if (cluster_gain_stats.num_feasible_blocks >= max_queue_size - 1 ) {
1014
- /* maximum size for array, remove smallest gain element and sort */
1015
- 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)) {
1016
- /* single loop insertion sort */
1017
- int j;
1018
- for (j = 0 ; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1019
- 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)) {
1020
- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1021
- break ;
1022
- } else {
1023
- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1024
- }
1025
- }
1026
- if (j == cluster_gain_stats.num_feasible_blocks - 1 ) {
1027
- cluster_gain_stats.feasible_blocks [j] = molecule_id;
1028
- }
1029
- }
1030
- } else {
1031
- /* Expand array and single loop insertion sort */
1032
- int j;
1033
- for (j = cluster_gain_stats.num_feasible_blocks - 1 ; j >= 0 ; j--) {
1034
- 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)) {
1035
- cluster_gain_stats.feasible_blocks [j + 1 ] = cluster_gain_stats.feasible_blocks [j];
1036
- } else {
1037
- cluster_gain_stats.feasible_blocks [j + 1 ] = molecule_id;
1038
- break ;
1039
- }
1040
- }
1041
- if (j < 0 ) {
1042
- cluster_gain_stats.feasible_blocks [0 ] = molecule_id;
1043
- }
1044
- cluster_gain_stats.num_feasible_blocks ++;
1018
+ for (std::pair<PackMoleculeId, float >& feasible_block : cluster_gain_stats.feasible_blocks .heap ) {
1019
+ 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 );
1045
1020
}
1021
+
1022
+ // Insert the molecule into the queue sorted by gain, and maintain the heap property
1023
+ float molecule_gain = get_molecule_gain (molecule_id, cluster_gain_stats, cluster_att_grp, attraction_groups, num_molecule_failures, prepacker, atom_netlist, appack_ctx);
1024
+ cluster_gain_stats.feasible_blocks .push (molecule_id, molecule_gain);
1046
1025
}
1047
1026
1048
1027
/*
@@ -1053,27 +1032,7 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1053
1032
*/
1054
1033
static void remove_molecule_from_pb_stats_candidates (PackMoleculeId molecule_id,
1055
1034
ClusterGainStats& cluster_gain_stats) {
1056
- int molecule_index;
1057
- bool found_molecule = false ;
1058
-
1059
- // find the molecule index
1060
- for (int i = 0 ; i < cluster_gain_stats.num_feasible_blocks ; i++) {
1061
- if (cluster_gain_stats.feasible_blocks [i] == molecule_id) {
1062
- found_molecule = true ;
1063
- molecule_index = i;
1064
- }
1065
- }
1066
-
1067
- // if it is not in the array, return
1068
- if (found_molecule == false ) {
1069
- return ;
1070
- }
1071
-
1072
- // Otherwise, shift the molecules while removing the specified molecule
1073
- for (int j = molecule_index; j < cluster_gain_stats.num_feasible_blocks - 1 ; j++) {
1074
- cluster_gain_stats.feasible_blocks [j] = cluster_gain_stats.feasible_blocks [j + 1 ];
1075
- }
1076
- cluster_gain_stats.num_feasible_blocks --;
1035
+ cluster_gain_stats.feasible_blocks .remove_at_pop_time (molecule_id);
1077
1036
}
1078
1037
1079
1038
/*
0 commit comments