@@ -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;
@@ -680,8 +679,8 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
680
679
*/
681
680
682
681
// 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 ;
685
684
add_cluster_molecule_candidates_by_connectivity_and_timing (cluster_gain_stats,
686
685
cluster_id,
687
686
cluster_legalizer,
@@ -691,31 +690,31 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
691
690
692
691
if (packer_opts_.prioritize_transitive_connectivity ) {
693
692
// 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 ) {
695
694
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
696
695
cluster_id,
697
696
cluster_legalizer,
698
697
attraction_groups);
699
698
}
700
699
701
700
// 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 ) {
703
702
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
704
703
cluster_id,
705
704
cluster_legalizer,
706
705
attraction_groups);
707
706
}
708
707
} else { // Reverse order
709
708
// 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 ) {
711
710
add_cluster_molecule_candidates_by_highfanout_connectivity (cluster_gain_stats,
712
711
cluster_id,
713
712
cluster_legalizer,
714
713
attraction_groups);
715
714
}
716
715
717
716
// 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 ) {
719
718
add_cluster_molecule_candidates_by_transitive_connectivity (cluster_gain_stats,
720
719
cluster_id,
721
720
cluster_legalizer,
@@ -724,23 +723,33 @@ PackMoleculeId GreedyCandidateSelector::get_next_candidate_for_cluster(
724
723
}
725
724
726
725
// 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 () ) {
728
727
add_cluster_molecule_candidates_by_attraction_group (cluster_gain_stats,
729
728
cluster_id,
730
729
cluster_legalizer,
731
730
attraction_groups);
732
731
}
733
732
734
733
/* Grab highest gain molecule */
735
- // If this was a vector, this would just be a pop_back.
736
734
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 ++;
741
741
VTR_ASSERT (!cluster_legalizer.is_mol_clustered (best_molecule));
742
742
}
743
743
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
+
744
753
// If we are allowing unrelated clustering and no molecule has been found,
745
754
// get unrelated candidate for cluster.
746
755
if (allow_unrelated_clustering_ && best_molecule == PackMoleculeId::INVALID ()) {
@@ -774,7 +783,9 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
774
783
LegalizationClusterId legalization_cluster_id,
775
784
const ClusterLegalizer& cluster_legalizer,
776
785
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
778
789
779
790
for (AtomBlockId blk_id : cluster_gain_stats.marked_blocks ) {
780
791
// Get the molecule that contains this block.
@@ -785,7 +796,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_connectivity_an
785
796
add_molecule_to_pb_stats_candidates (molecule_id,
786
797
cluster_gain_stats,
787
798
cluster_legalizer.get_cluster_type (legalization_cluster_id),
788
- packer_opts_.feasible_block_array_size ,
789
799
attraction_groups,
790
800
prepacker_,
791
801
atom_netlist_,
@@ -801,6 +811,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
801
811
AttractionInfo& attraction_groups) {
802
812
// TODO: For now, only done by fan-out; should also consider fan-in
803
813
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
804
815
805
816
/* First time finding transitive fanout candidates therefore alloc and load them */
806
817
load_transitive_fanout_candidates (cluster_gain_stats,
@@ -814,8 +825,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_transitive_conn
814
825
add_molecule_to_pb_stats_candidates (molecule_id,
815
826
cluster_gain_stats,
816
827
cluster_legalizer.get_cluster_type (legalization_cluster_id),
817
- std::min (packer_opts_.feasible_block_array_size ,
818
- AAPACK_MAX_TRANSITIVE_EXPLORE),
819
828
attraction_groups,
820
829
prepacker_,
821
830
atom_netlist_,
@@ -834,6 +843,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
834
843
* related blocks */
835
844
836
845
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
837
847
838
848
int count = 0 ;
839
849
for (AtomPinId pin_id : atom_netlist_.net_pins (net_id)) {
@@ -848,8 +858,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_highfanout_conn
848
858
add_molecule_to_pb_stats_candidates (molecule_id,
849
859
cluster_gain_stats,
850
860
cluster_legalizer.get_cluster_type (legalization_cluster_id),
851
- std::min (packer_opts_.feasible_block_array_size ,
852
- AAPACK_MAX_HIGH_FANOUT_EXPLORE),
853
861
attraction_groups,
854
862
prepacker_,
855
863
atom_netlist_,
@@ -877,6 +885,7 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
877
885
* group molecules for candidate molecules.
878
886
*/
879
887
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
880
889
if (grp_id == AttractGroupId::INVALID ()) {
881
890
return ;
882
891
}
@@ -909,7 +918,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
909
918
add_molecule_to_pb_stats_candidates (molecule_id,
910
919
cluster_gain_stats,
911
920
cluster_legalizer.get_cluster_type (legalization_cluster_id),
912
- packer_opts_.feasible_block_array_size ,
913
921
attraction_groups,
914
922
prepacker_,
915
923
atom_netlist_,
@@ -931,7 +939,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
931
939
add_molecule_to_pb_stats_candidates (molecule_id,
932
940
cluster_gain_stats,
933
941
cluster_legalizer.get_cluster_type (legalization_cluster_id),
934
- packer_opts_.feasible_block_array_size ,
935
942
attraction_groups,
936
943
prepacker_,
937
944
atom_netlist_,
@@ -946,7 +953,6 @@ void GreedyCandidateSelector::add_cluster_molecule_candidates_by_attraction_grou
946
953
static void add_molecule_to_pb_stats_candidates (PackMoleculeId molecule_id,
947
954
ClusterGainStats& cluster_gain_stats,
948
955
t_logical_block_type_ptr cluster_type,
949
- int max_queue_size,
950
956
AttractionInfo& attraction_groups,
951
957
const Prepacker& prepacker,
952
958
const AtomNetlist& atom_netlist,
@@ -996,45 +1002,18 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
996
1002
}
997
1003
}
998
1004
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 ;
1003
1008
}
1004
1009
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 );
1037
1012
}
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);
1038
1017
}
1039
1018
1040
1019
/*
@@ -1045,27 +1024,7 @@ static void add_molecule_to_pb_stats_candidates(PackMoleculeId molecule_id,
1045
1024
*/
1046
1025
static void remove_molecule_from_pb_stats_candidates (PackMoleculeId molecule_id,
1047
1026
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);
1069
1028
}
1070
1029
1071
1030
/*
0 commit comments