@@ -96,6 +96,49 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
96
96
pb->pb_stats ->explore_transitive_fanout = true ;
97
97
}
98
98
99
+ /*
100
+ * @brief Check the atom blocks of a cluster pb. Used in the verify method.
101
+ */
102
+ /* TODO: May want to check that all atom blocks are actually reached */
103
+ static void check_cluster_atom_blocks (t_pb* pb, std::unordered_set<AtomBlockId>& blocks_checked) {
104
+ int i, j;
105
+ const t_pb_type* pb_type;
106
+ bool has_child = false ;
107
+ auto & atom_ctx = g_vpr_ctx.atom ();
108
+
109
+ pb_type = pb->pb_graph_node ->pb_type ;
110
+ if (pb_type->num_modes == 0 ) {
111
+ /* primitive */
112
+ auto blk_id = atom_ctx.lookup .pb_atom (pb);
113
+ if (blk_id) {
114
+ if (blocks_checked.count (blk_id)) {
115
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
116
+ " pb %s contains atom block %s but atom block is already contained in another pb.\n " ,
117
+ pb->name , atom_ctx.nlist .block_name (blk_id).c_str ());
118
+ }
119
+ blocks_checked.insert (blk_id);
120
+ if (pb != atom_ctx.lookup .atom_pb (blk_id)) {
121
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
122
+ " pb %s contains atom block %s but atom block does not link to pb.\n " ,
123
+ pb->name , atom_ctx.nlist .block_name (blk_id).c_str ());
124
+ }
125
+ }
126
+ } else {
127
+ /* this is a container pb, all container pbs must contain children */
128
+ for (i = 0 ; i < pb_type->modes [pb->mode ].num_pb_type_children ; i++) {
129
+ for (j = 0 ; j < pb_type->modes [pb->mode ].pb_type_children [i].num_pb ; j++) {
130
+ if (pb->child_pbs [i] != nullptr ) {
131
+ if (pb->child_pbs [i][j].name != nullptr ) {
132
+ has_child = true ;
133
+ check_cluster_atom_blocks (&pb->child_pbs [i][j], blocks_checked);
134
+ }
135
+ }
136
+ }
137
+ }
138
+ VTR_ASSERT (has_child);
139
+ }
140
+ }
141
+
99
142
/* Record the failure of the molecule in this cluster in the current pb stats.
100
143
* If a molecule fails repeatedly, it's gain will be penalized if packing with
101
144
* attraction groups on. */
@@ -1350,6 +1393,8 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
1350
1393
primitives_list != nullptr &&
1351
1394
lb_type_rr_graphs != nullptr );
1352
1395
1396
+ const AtomContext& atom_ctx = g_vpr_ctx.atom ();
1397
+
1353
1398
// Create the physical block for this cluster based on the type.
1354
1399
t_pb* cluster_pb = new t_pb;
1355
1400
cluster_pb->pb_graph_node = cluster_type->pb_graph_head ;
@@ -1385,8 +1430,17 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
1385
1430
FULL_EXTERNAL_PIN_UTIL);
1386
1431
1387
1432
if (pack_status == e_block_pack_status::BLK_PASSED) {
1433
+ // Give the new cluster pb a name. The current convention is to name the
1434
+ // cluster after the root atom of the first molecule packed into it.
1435
+ AtomBlockId root_atom = molecule->atom_block_ids [molecule->root ];
1436
+ const std::string& root_atom_name = atom_ctx.nlist .block_name (root_atom);
1437
+ if (new_cluster.pb ->name != nullptr )
1438
+ free (new_cluster.pb ->name );
1439
+ new_cluster.pb ->name = vtr::strdup (root_atom_name.c_str ());
1440
+ // Move the cluster into the vector of clusters and ids.
1388
1441
legalization_cluster_ids.push_back (new_cluster_id);
1389
1442
legalization_clusters.push_back (std::move (new_cluster));
1443
+ // Update the molecule to cluster map.
1390
1444
molecule_cluster[molecule] = new_cluster_id;
1391
1445
} else {
1392
1446
// Delete the new_cluster.
@@ -1578,6 +1632,72 @@ void ClusterLegalizer::reset() {
1578
1632
cluster_placement_stats = alloc_and_load_cluster_placement_stats ();
1579
1633
}
1580
1634
1635
+ void ClusterLegalizer::verify () {
1636
+ std::unordered_set<AtomBlockId> atoms_checked;
1637
+ auto & atom_ctx = g_vpr_ctx.atom ();
1638
+
1639
+ if (clusters ().size () == 0 ) {
1640
+ VTR_LOG_WARN (" Packing produced no clustered blocks" );
1641
+ }
1642
+
1643
+ /*
1644
+ * Check that each atom block connects to one physical primitive and that the primitive links up to the parent clb
1645
+ */
1646
+ for (auto blk_id : atom_ctx.nlist .blocks ()) {
1647
+ // Each atom should be part of a pb
1648
+ const t_pb* atom_pb = atom_ctx.lookup .atom_pb (blk_id);
1649
+ if (!atom_pb) {
1650
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
1651
+ " Atom block %s is not mapped to a pb\n " ,
1652
+ atom_ctx.nlist .block_name (blk_id).c_str ());
1653
+ }
1654
+
1655
+ // Check the reverse mapping is consistent
1656
+ if (atom_ctx.lookup .pb_atom (atom_pb) != blk_id) {
1657
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
1658
+ " pb %s does not contain atom block %s but atom block %s maps to pb.\n " ,
1659
+ atom_pb->name ,
1660
+ atom_ctx.nlist .block_name (blk_id).c_str (),
1661
+ atom_ctx.nlist .block_name (blk_id).c_str ());
1662
+ }
1663
+
1664
+ VTR_ASSERT (atom_ctx.nlist .block_name (blk_id) == atom_pb->name );
1665
+
1666
+ const t_pb* cur_pb = atom_pb;
1667
+ while (cur_pb->parent_pb ) {
1668
+ cur_pb = cur_pb->parent_pb ;
1669
+ VTR_ASSERT (cur_pb->name );
1670
+ }
1671
+
1672
+ LegalizationClusterId cluster_id = get_atom_cluster (blk_id);
1673
+ if (cluster_id == LegalizationClusterId::INVALID ()) {
1674
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
1675
+ " Atom %s is not mapped to a CLB\n " ,
1676
+ atom_ctx.nlist .block_name (blk_id).c_str ());
1677
+ }
1678
+
1679
+ if (cur_pb != get_cluster_pb (cluster_id)) {
1680
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
1681
+ " CLB %s does not match CLB contained by pb %s.\n " ,
1682
+ cur_pb->name , atom_pb->name );
1683
+ }
1684
+ }
1685
+
1686
+ /* Check that I do not have spurious links in children pbs */
1687
+ for (LegalizationClusterId cluster_id : clusters ()) {
1688
+ check_cluster_atom_blocks (get_cluster_pb (cluster_id),
1689
+ atoms_checked);
1690
+ }
1691
+
1692
+ for (auto blk_id : atom_ctx.nlist .blocks ()) {
1693
+ if (!atoms_checked.count (blk_id)) {
1694
+ VPR_FATAL_ERROR (VPR_ERROR_PACK,
1695
+ " Atom block %s not found in any cluster.\n " ,
1696
+ atom_ctx.nlist .block_name (blk_id).c_str ());
1697
+ }
1698
+ }
1699
+ }
1700
+
1581
1701
void ClusterLegalizer::finalize () {
1582
1702
for (LegalizationClusterId cluster_id : legalization_cluster_ids) {
1583
1703
if (!cluster_id.is_valid ())
0 commit comments