4
4
* @date September 2024
5
5
* @brief The implementation of the Cluster Legalizer class.
6
6
*
7
- * Most of the code in this file was original part of cluster_util.cpp and was
7
+ * Most of the code in this file was originally part of cluster_util.cpp and was
8
8
* highly integrated with the clusterer in VPR. All code that was used for
9
9
* legalizing the clusters was moved into this file and all the functionality
10
10
* was moved into the ClusterLegalizer class.
40
40
41
41
/*
42
42
* @brief Gets the max cluster size that any logical block can have.
43
+ *
44
+ * This is the maximum number of primitives any cluster can contain.
43
45
*/
44
46
static size_t calc_max_cluster_size (const std::vector<t_logical_block_type>& logical_block_types) {
45
47
size_t max_cluster_size = 0 ;
@@ -63,11 +65,6 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
63
65
64
66
pb->pb_stats = new t_pb_stats;
65
67
66
- /* If statement below is for speed. If nets are reasonably low-fanout, *
67
- * only a relatively small number of blocks will be marked, and updating *
68
- * only those atom block structures will be fastest. If almost all blocks *
69
- * have been touched it should be faster to just run through them all *
70
- * in order (less addressing and better cache locality). */
71
68
pb->pb_stats ->input_pins_used = std::vector<std::unordered_map<size_t , AtomNetId>>(pb->pb_graph_node ->num_input_pin_class );
72
69
pb->pb_stats ->output_pins_used = std::vector<std::unordered_map<size_t , AtomNetId>>(pb->pb_graph_node ->num_output_pin_class );
73
70
pb->pb_stats ->lookahead_input_pins_used = std::vector<std::vector<AtomNetId>>(pb->pb_graph_node ->num_input_pin_class );
@@ -304,10 +301,10 @@ static bool check_cluster_noc_group(AtomBlockId atom_blk_id,
304
301
}
305
302
306
303
/* *
307
- * This function takes the root block of a chain molecule and a proposed
308
- * placement primitive for this block. The function then checks if this
309
- * chain root block has a placement constraint (such as being driven from
310
- * outside the cluster) and returns the status of the placement accordingly.
304
+ * @brief This function takes the root block of a chain molecule and a proposed
305
+ * placement primitive for this block. The function then checks if this
306
+ * chain root block has a placement constraint (such as being driven from
307
+ * outside the cluster) and returns the status of the placement accordingly.
311
308
*/
312
309
static enum e_block_pack_status check_chain_root_placement_feasibility (const t_pb_graph_node* pb_graph_node,
313
310
const t_pack_molecule* molecule,
@@ -368,7 +365,7 @@ static enum e_block_pack_status check_chain_root_placement_feasibility(const t_p
368
365
369
366
/*
370
367
* @brief Check that the two atom blocks blk_id and sibling_blk_id (which should
371
- * both be memory slices) are feasible, in the sence that they have
368
+ * both be memory slices) are feasible, in the sense that they have
372
369
* precicely the same net connections (with the exception of nets in data
373
370
* port classes).
374
371
*
@@ -480,7 +477,7 @@ static bool primitive_feasible(const AtomBlockId blk_id, t_pb* cur_pb) {
480
477
}
481
478
482
479
/* *
483
- * Try place atom block into current primitive location
480
+ * @brief Try to place atom block into current primitive location
484
481
*/
485
482
static enum e_block_pack_status
486
483
try_place_atom_block_rec (const t_pb_graph_node* pb_graph_node,
@@ -613,7 +610,10 @@ try_place_atom_block_rec(const t_pb_graph_node* pb_graph_node,
613
610
return block_pack_status;
614
611
}
615
612
616
- /* Resets nets used at different pin classes for determining pin feasibility */
613
+ /*
614
+ * @brief Resets nets used at different pin classes for determining pin
615
+ * feasibility.
616
+ */
617
617
static void reset_lookahead_pins_used (t_pb* cur_pb) {
618
618
const t_pb_type* pb_type = cur_pb->pb_graph_node ->pb_type ;
619
619
if (cur_pb->pb_stats == nullptr ) {
@@ -674,7 +674,7 @@ static int net_sinks_reachable_in_cluster(const t_pb_graph_pin* driver_pb_gpin,
674
674
}
675
675
676
676
/* *
677
- * Returns the pb_graph_pin of the atom pin defined by the driver_pin_id in the driver_pb
677
+ * @brief Returns the pb_graph_pin of the atom pin defined by the driver_pin_id in the driver_pb
678
678
*/
679
679
static t_pb_graph_pin* get_driver_pb_graph_pin (const t_pb* driver_pb, const AtomPinId driver_pin_id) {
680
680
const AtomContext& atom_ctx = g_vpr_ctx.atom ();
@@ -701,12 +701,12 @@ static t_pb_graph_pin* get_driver_pb_graph_pin(const t_pb* driver_pb, const Atom
701
701
}
702
702
703
703
/* *
704
- * Given a pin and its assigned net, mark all pin classes that are affected.
705
- * Check if connecting this pin to it's driver pin or to all sink pins will
706
- * require leaving a pb_block starting from the parent pb_block of the
707
- * primitive till the root block (depth = 0). If leaving a pb_block is
708
- * required add this net to the pin class (to increment the number of used
709
- * pins from this class) that should be used to leave the pb_block.
704
+ * @brief Given a pin and its assigned net, mark all pin classes that are affected.
705
+ * Check if connecting this pin to it's driver pin or to all sink pins will
706
+ * require leaving a pb_block starting from the parent pb_block of the
707
+ * primitive till the root block (depth = 0). If leaving a pb_block is
708
+ * required add this net to the pin class (to increment the number of used
709
+ * pins from this class) that should be used to leave the pb_block.
710
710
*/
711
711
static void compute_and_mark_lookahead_pins_used_for_pin (const t_pb_graph_pin* pb_graph_pin,
712
712
const t_pb* primitive_pb,
@@ -834,7 +834,9 @@ static void compute_and_mark_lookahead_pins_used_for_pin(const t_pb_graph_pin* p
834
834
}
835
835
836
836
837
- /* Determine if pins of speculatively packed pb are legal */
837
+ /*
838
+ * @brief Determine if pins of speculatively packed pb are legal
839
+ */
838
840
static void compute_and_mark_lookahead_pins_used (const AtomBlockId blk_id,
839
841
const vtr::vector_map<AtomBlockId, LegalizationClusterId>& atom_cluster) {
840
842
const AtomContext& atom_ctx = g_vpr_ctx.atom ();
@@ -851,7 +853,9 @@ static void compute_and_mark_lookahead_pins_used(const AtomBlockId blk_id,
851
853
}
852
854
}
853
855
854
- /* Determine if speculatively packed cur_pb is pin feasible
856
+ /*
857
+ * @brief Determine if speculatively packed cur_pb is pin feasible
858
+ *
855
859
* Runtime is actually not that bad for this. It's worst case O(k^2) where k is the
856
860
* number of pb_graph pins. Can use hash tables or make incremental if becomes an issue.
857
861
*/
@@ -881,7 +885,10 @@ static void try_update_lookahead_pins_used(t_pb* cur_pb,
881
885
}
882
886
}
883
887
884
- /* Check if the number of available inputs/outputs for a pin class is sufficient for speculatively packed blocks */
888
+ /*
889
+ * @brief Check if the number of available inputs/outputs for a pin class is
890
+ * sufficient for speculatively packed blocks.
891
+ */
885
892
static bool check_lookahead_pins_used (t_pb* cur_pb, t_ext_pin_util max_external_pin_util) {
886
893
const t_pb_type* pb_type = cur_pb->pb_graph_node ->pb_type ;
887
894
@@ -943,11 +950,11 @@ static bool check_lookahead_pins_used(t_pb* cur_pb, t_ext_pin_util max_external_
943
950
}
944
951
945
952
/* *
946
- * This function takes a chain molecule, and the pb_graph_node that is chosen
947
- * for packing the molecule's root block. Using the given root_primitive, this
948
- * function will identify which chain id this molecule is being mapped to and
949
- * will update the chain id value inside the chain info data structure of this
950
- * molecule
953
+ * @brief This function takes a chain molecule, and the pb_graph_node that is
954
+ * chosen for packing the molecule's root block. Using the given
955
+ * root_primitive, this function will identify which chain id this
956
+ * molecule is being mapped to and will update the chain id value inside
957
+ * the chain info data structure of this molecule.
951
958
*/
952
959
static void update_molecule_chain_info (t_pack_molecule* chain_molecule, const t_pb_graph_node* root_primitive) {
953
960
VTR_ASSERT (chain_molecule->chain_info ->chain_id == -1 && chain_molecule->chain_info ->is_long_chain );
@@ -969,7 +976,8 @@ static void update_molecule_chain_info(t_pack_molecule* chain_molecule, const t_
969
976
VTR_ASSERT (false );
970
977
}
971
978
972
- /* Revert trial atom block iblock and free up memory space accordingly
979
+ /*
980
+ * @brief Revert trial atom block iblock and free up memory space accordingly.
973
981
*/
974
982
static void revert_place_atom_block (const AtomBlockId blk_id,
975
983
t_lb_router_data* router_data,
@@ -1021,7 +1029,9 @@ static void revert_place_atom_block(const AtomBlockId blk_id,
1021
1029
mutable_atom_ctx.lookup .set_atom_pb (blk_id, nullptr );
1022
1030
}
1023
1031
1024
- /* Speculation successful, commit input/output pins used */
1032
+ /*
1033
+ * @brief Speculation successful, commit input/output pins used.
1034
+ */
1025
1035
static void commit_lookahead_pins_used (t_pb* cur_pb) {
1026
1036
const t_pb_type* pb_type = cur_pb->pb_graph_node ->pb_type ;
1027
1037
@@ -1055,7 +1065,7 @@ static void commit_lookahead_pins_used(t_pb* cur_pb) {
1055
1065
}
1056
1066
1057
1067
/* *
1058
- * Cleans up a pb after unsuccessful molecule packing
1068
+ * @brief Cleans up a pb after unsuccessful molecule packing
1059
1069
*
1060
1070
* Recursively frees pbs from a t_pb tree. The given root pb itself is not
1061
1071
* deleted.
@@ -1135,7 +1145,7 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
1135
1145
VTR_ASSERT_DEBUG (cluster.pb != nullptr );
1136
1146
VTR_ASSERT_DEBUG (cluster.type != nullptr );
1137
1147
1138
- // TODO: Remove these global accesses.
1148
+ // TODO: Remove these global accesses to the contexts .
1139
1149
// AtomContext used for:
1140
1150
// - printing verbose statements
1141
1151
// - Looking up the primitive pb
@@ -1349,7 +1359,7 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
1349
1359
cluster.noc_grp_id = new_cluster_noc_grp_id;
1350
1360
1351
1361
// Insert the molecule into the cluster for bookkeeping.
1352
- cluster.molecules .insert (molecule);
1362
+ cluster.molecules .push_back (molecule);
1353
1363
1354
1364
for (int i = 0 ; i < molecule_size; i++) {
1355
1365
AtomBlockId atom_blk_id = molecule->atom_block_ids [i];
@@ -1653,10 +1663,13 @@ ClusterLegalizer::ClusterLegalizer(const AtomNetlist& atom_netlist,
1653
1663
feasible_block_array_size_ = feasible_block_array_size;
1654
1664
log_verbosity_ = log_verbosity;
1655
1665
// Get the target external pin utilization
1656
- // NOTE: This is really silly, but this can potentially fail. If it does
1657
- // it is important that everything is allocated. If not, when it fails
1658
- // it will call the reset method when only parts of the class are
1659
- // allocated which may cause havoc...
1666
+ // NOTE: This has to be initialized last due to the fact that VPR_FATA_ERROR
1667
+ // may be called within the constructor of t_ext_pin_util_targets. If
1668
+ // this occurs, an excpetion is thrown which will drain the stack. If
1669
+ // the cluster legalizer object is stored on the stack, this can call
1670
+ // the destructor prematurely (before certain structures are allocated).
1671
+ // Therefore, this is created at the end, when the class is in a state
1672
+ // where it can be destroyed.
1660
1673
target_external_pin_util_ = t_ext_pin_util_targets (target_external_pin_util_str);
1661
1674
}
1662
1675
0 commit comments