Skip to content

Commit ad35684

Browse files
[SQUASH ME] Cleaned up cluster_utils.
1 parent 2e4c4ca commit ad35684

7 files changed

+166
-264
lines changed

vpr/src/base/vpr_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ struct ClusteringContext : public Context {
315315
* in packing or placement stages.
316316
*/
317317
struct ClusteringHelperContext : public Context {
318-
// A vector of routing resource nodes within each of logic cluster_ctx.blocks types [0 .. num_logical_block_type-1]
318+
// A vector of routing resource nodes within each of logic cluster_ctx.blocks types [1 .. num_logical_block_type-1]
319319
// FIXME: This is only used for a handoff between the vpr_setup and the packer.
320320
// This can be made cleaner.
321321
std::vector<t_lb_type_rr_node>* lb_type_rr_graphs;

vpr/src/pack/cluster.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,21 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa
342342
}
343343

344344
if (is_cluster_legal) {
345-
istart = save_cluster_routing_and_pick_new_seed(packer_opts, seed_atoms, cluster_legalizer, num_blocks_hill_added, seed_index, cluster_stats);
345+
// Pick new seed.
346+
istart = get_highest_gain_seed_molecule(seed_index, seed_atoms, cluster_legalizer);
347+
// Update cluster stats.
348+
if (packer_opts.timing_driven && num_blocks_hill_added > 0)
349+
cluster_stats.blocks_since_last_analysis += num_blocks_hill_added;
350+
346351
store_cluster_info_and_free(packer_opts, legalization_cluster_id, logic_block_type, le_pb_type, le_count, cluster_legalizer, clb_inter_blk_nets);
347352
} else {
348-
free_data_and_requeue_used_mols_if_illegal(legalization_cluster_id, cluster_legalizer, saved_seed_index, num_used_type_instances, total_clb_num, seed_index);
353+
// If the cluster is not legal, requeue used mols.
354+
num_used_type_instances[cluster_legalizer.get_cluster_type(legalization_cluster_id)]--;
355+
total_clb_num--;
356+
seed_index = saved_seed_index;
357+
// Destroy the illegal cluster.
358+
cluster_legalizer.destroy_cluster(legalization_cluster_id);
359+
cluster_legalizer.compress();
349360
}
350361
}
351362
}

vpr/src/pack/cluster_legalizer.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,49 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
9696
pb->pb_stats->explore_transitive_fanout = true;
9797
}
9898

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+
99142
/* Record the failure of the molecule in this cluster in the current pb stats.
100143
* If a molecule fails repeatedly, it's gain will be penalized if packing with
101144
* attraction groups on. */
@@ -1350,6 +1393,8 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
13501393
primitives_list != nullptr &&
13511394
lb_type_rr_graphs != nullptr);
13521395

1396+
const AtomContext& atom_ctx = g_vpr_ctx.atom();
1397+
13531398
// Create the physical block for this cluster based on the type.
13541399
t_pb* cluster_pb = new t_pb;
13551400
cluster_pb->pb_graph_node = cluster_type->pb_graph_head;
@@ -1385,8 +1430,17 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
13851430
FULL_EXTERNAL_PIN_UTIL);
13861431

13871432
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.
13881441
legalization_cluster_ids.push_back(new_cluster_id);
13891442
legalization_clusters.push_back(std::move(new_cluster));
1443+
// Update the molecule to cluster map.
13901444
molecule_cluster[molecule] = new_cluster_id;
13911445
} else {
13921446
// Delete the new_cluster.
@@ -1578,6 +1632,72 @@ void ClusterLegalizer::reset() {
15781632
cluster_placement_stats = alloc_and_load_cluster_placement_stats();
15791633
}
15801634

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+
15811701
void ClusterLegalizer::finalize() {
15821702
for (LegalizationClusterId cluster_id : legalization_cluster_ids) {
15831703
if (!cluster_id.is_valid())

vpr/src/pack/cluster_legalizer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,15 @@ class ClusterLegalizer {
233233
log_verbosity = verbosity;
234234
}
235235

236-
// FIXME: We should make a clean method to clean 1 or all clusters.
236+
// TODO: Should make a clean method to clean 1 or all clusters.
237237
// - free_pb_stats_recursive for example.
238238
// - free the router data.
239239
// - etc.
240240
// - This is to help reduce the memory overhead of the class without
241241
// breaking anything.
242242

243+
void verify();
244+
243245
void finalize();
244246

245247
void reset();

0 commit comments

Comments
 (0)