Skip to content

Commit 8dcd60c

Browse files
authored
Merge pull request #1656 from antmicro/cluster_fix
Added cleaning of a pb after unsuccessful molecule packing
2 parents 7be7cbe + 5fe4b9b commit 8dcd60c

File tree

9 files changed

+1031
-20
lines changed

9 files changed

+1031
-20
lines changed

vpr/src/pack/cluster.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,76 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
11791179
}
11801180
/*****************************************/
11811181

1182+
/**
1183+
* Cleans up a pb after unsuccessful molecule packing
1184+
*
1185+
* Recursively frees pbs from a t_pb tree. The given root pb itself is not
1186+
* deleted.
1187+
*
1188+
* If a pb object has its children allocated then before freeing them the
1189+
* function checks if there is no atom that corresponds to any of them. The
1190+
* check is performed only for leaf (primitive) pbs. The function recurses for
1191+
* non-primitive pbs.
1192+
*
1193+
* The cleaning itself includes deleting all child pbs, resetting mode of the
1194+
* pb and also freeing its name. This prepares the pb for another round of
1195+
* molecule packing tryout.
1196+
*/
1197+
static bool cleanup_pb(t_pb* pb) {
1198+
bool can_free = true;
1199+
1200+
/* Recursively check if there are any children with already assigned atoms */
1201+
if (pb->child_pbs != nullptr) {
1202+
const t_mode* mode = &pb->pb_graph_node->pb_type->modes[pb->mode];
1203+
VTR_ASSERT(mode != nullptr);
1204+
1205+
/* Check each mode */
1206+
for (int i = 0; i < mode->num_pb_type_children; ++i) {
1207+
/* Check each child */
1208+
if (pb->child_pbs[i] != nullptr) {
1209+
for (int j = 0; j < mode->pb_type_children[i].num_pb; ++j) {
1210+
t_pb* pb_child = &pb->child_pbs[i][j];
1211+
t_pb_type* pb_type = pb_child->pb_graph_node->pb_type;
1212+
1213+
/* Primitive, check occupancy */
1214+
if (pb_type->num_modes == 0) {
1215+
if (pb_child->name != nullptr) {
1216+
can_free = false;
1217+
}
1218+
}
1219+
1220+
/* Non-primitive, recurse */
1221+
else {
1222+
if (!cleanup_pb(pb_child)) {
1223+
can_free = false;
1224+
}
1225+
}
1226+
}
1227+
}
1228+
}
1229+
1230+
/* Free if can */
1231+
if (can_free) {
1232+
for (int i = 0; i < mode->num_pb_type_children; ++i) {
1233+
if (pb->child_pbs[i] != nullptr) {
1234+
delete[] pb->child_pbs[i];
1235+
}
1236+
}
1237+
1238+
delete[] pb->child_pbs;
1239+
pb->child_pbs = nullptr;
1240+
pb->mode = 0;
1241+
1242+
if (pb->name) {
1243+
free(pb->name);
1244+
pb->name = nullptr;
1245+
}
1246+
}
1247+
}
1248+
1249+
return can_free;
1250+
}
1251+
11821252
/**
11831253
* Try pack molecule into current cluster
11841254
*/
@@ -1358,6 +1428,12 @@ static enum e_block_pack_status try_pack_molecule(t_cluster_placement_stats* clu
13581428
revert_place_atom_block(molecule->atom_block_ids[i], router_data, atom_molecules);
13591429
}
13601430
}
1431+
1432+
/* Packing failed, but a part of the pb tree is still allocated and pbs have their modes set.
1433+
* Before trying to pack next molecule the unused pbs need to be freed and, the most important,
1434+
* their modes reset. This task is performed by the cleanup_pb() function below. */
1435+
cleanup_pb(pb);
1436+
13611437
} else {
13621438
VTR_LOGV(verbosity > 3, "\t\tPASSED pack molecule\n");
13631439
}

0 commit comments

Comments
 (0)