Skip to content

Added cleaning of a pb after unsuccessful molecule packing #1656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions vpr/src/pack/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,76 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
}
/*****************************************/

/**
* Cleans up a pb after unsuccessful molecule packing
*
* Recursively frees pbs from a t_pb tree. The given root pb itself is not
* deleted.
*
* If a pb object has its children allocated then before freeing them the
* function checks if there is no atom that corresponds to any of them. The
* check is performed only for leaf (primitive) pbs. The function recurses for
* non-primitive pbs.
*
* The cleaning itself includes deleting all child pbs, resetting mode of the
* pb and also freeing its name. This prepares the pb for another round of
* molecule packing tryout.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to comment this routine and how it works as much as you can.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly is it cleaning up? When is it safe to call?

static bool cleanup_pb(t_pb* pb) {
bool can_free = true;

/* Recursively check if there are any children with already assigned atoms */
if (pb->child_pbs != nullptr) {
const t_mode* mode = &pb->pb_graph_node->pb_type->modes[pb->mode];
VTR_ASSERT(mode != nullptr);

/* Check each mode */
for (int i = 0; i < mode->num_pb_type_children; ++i) {
/* Check each child */
if (pb->child_pbs[i] != nullptr) {
for (int j = 0; j < mode->pb_type_children[i].num_pb; ++j) {
t_pb* pb_child = &pb->child_pbs[i][j];
t_pb_type* pb_type = pb_child->pb_graph_node->pb_type;

/* Primitive, check occupancy */
if (pb_type->num_modes == 0) {
if (pb_child->name != nullptr) {
can_free = false;
}
}

/* Non-primitive, recurse */
else {
if (!cleanup_pb(pb_child)) {
can_free = false;
}
}
}
}
}

/* Free if can */
if (can_free) {
for (int i = 0; i < mode->num_pb_type_children; ++i) {
if (pb->child_pbs[i] != nullptr) {
delete[] pb->child_pbs[i];
}
}

delete[] pb->child_pbs;
pb->child_pbs = nullptr;
pb->mode = 0;

if (pb->name) {
free(pb->name);
pb->name = nullptr;
}
}
}

return can_free;
}

/**
* Try pack molecule into current cluster
*/
Expand Down Expand Up @@ -1358,6 +1428,12 @@ static enum e_block_pack_status try_pack_molecule(t_cluster_placement_stats* clu
revert_place_atom_block(molecule->atom_block_ids[i], router_data, atom_molecules);
}
}

/* Packing failed, but a part of the pb tree is still allocated and pbs have their modes set.
* Before trying to pack next molecule the unused pbs need to be freed and, the most important,
* their modes reset. This task is performed by the cleanup_pb() function below. */
cleanup_pb(pb);

} else {
VTR_LOGV(verbosity > 3, "\t\tPASSED pack molecule\n");
}
Expand Down
Loading