Skip to content

Commit

Permalink
[Prepacker] Removed Valid Flag From Molecules
Browse files Browse the repository at this point in the history
Pack molecules originally contained a flag called "valid" which
signified that the molecule has not been clustered yet. This flag is not
necessary since the Cluster Legalizer maintains this information
internally. Removed the valid flag from the pack molecule struct.

See issue verilog-to-routing#2791
  • Loading branch information
AlexandreSinger committed Nov 2, 2024
1 parent 660ecab commit 49f3ab3
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 102 deletions.
2 changes: 0 additions & 2 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ enum e_pack_pattern_molecule_type {
* t_pack_pattern_block->block_id
* chain_info : if this is a molecule representing a chained pack pattern, this data structure will
* hold the data shared between all molecules forming a chain together.
* valid : whether the molecule is still valid for packing or not.
* num_blocks : maximum number of atom blocks that can fit in this molecule
* root : index of the pack_pattern->root_block in the atom_blocks_ids. root_block_id = atom_block_ids[root]
* base_gain : intrinsic "goodness" score for molecule independent of rest of netlist
Expand All @@ -393,7 +392,6 @@ enum e_pack_pattern_molecule_type {
class t_pack_molecule {
public:
/* general molecule info */
bool valid;
float base_gain;
enum e_pack_pattern_molecule_type type;

Expand Down
2 changes: 0 additions & 2 deletions vpr/src/pack/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa

const t_molecule_stats max_molecule_stats = prepacker.calc_max_molecule_stats(atom_ctx.nlist);

prepacker.mark_all_molecules_valid();

cluster_stats.num_molecules = prepacker.get_num_molecules();

if (packer_opts.hill_climbing_flag) {
Expand Down
82 changes: 65 additions & 17 deletions vpr/src/pack/cluster_legalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,11 +997,70 @@ static void update_molecule_chain_info(t_pack_molecule* chain_molecule, const t_
VTR_ASSERT(false);
}

/**
* @brief Revalidate the molecules associated with this pb. The mol_validated
* flag is used to check if the mol has already been validated.
*/
static void revalid_molecules(const t_pb* pb,
bool &mol_validated,
const Prepacker& prepacker) {
const t_pb_type* pb_type = pb->pb_graph_node->pb_type;

if (pb_type->blif_model == nullptr) {
int mode = pb->mode;
for (int i = 0; i < pb_type->modes[mode].num_pb_type_children && pb->child_pbs != nullptr; i++) {
for (int j = 0; j < pb_type->modes[mode].pb_type_children[i].num_pb && pb->child_pbs[i] != nullptr; j++) {
if (pb->child_pbs[i][j].name != nullptr || pb->child_pbs[i][j].child_pbs != nullptr) {
revalid_molecules(&pb->child_pbs[i][j], mol_validated, prepacker);
}
}
}
} else {
//Primitive
auto& atom_ctx = g_vpr_ctx.mutable_atom();

auto blk_id = atom_ctx.lookup.pb_atom(pb);
if (blk_id) {
/* If any molecules were marked invalid because of this logic block getting packed, mark them valid */

//Update atom netlist mapping
atom_ctx.lookup.set_atom_clb(blk_id, ClusterBlockId::INVALID());
atom_ctx.lookup.set_atom_pb(blk_id, nullptr);

t_pack_molecule* cur_molecule = prepacker.get_atom_molecule(blk_id);
if (!mol_validated) {
int i;
for (i = 0; i < get_array_size_of_molecule(cur_molecule); i++) {
if (cur_molecule->atom_block_ids[i]) {
if (atom_ctx.lookup.atom_clb(cur_molecule->atom_block_ids[i]) != ClusterBlockId::INVALID()) {
break;
}
}
}
/* All atom blocks are open for this molecule, place back in queue */
if (i == get_array_size_of_molecule(cur_molecule)) {
mol_validated = true;
// when invalidating a molecule check if it's a chain molecule
// that is part of a long chain. If so, check if this molecule
// have modified the chain_id value based on the stale packing
// then reset the chain id and the first packed molecule pointer
// this is packing is being reset
if (cur_molecule->is_chain() && cur_molecule->chain_info->is_long_chain && cur_molecule->chain_info->first_packed_molecule == cur_molecule) {
cur_molecule->chain_info->first_packed_molecule = nullptr;
cur_molecule->chain_info->chain_id = -1;
}
}
}
}
}
}

/*
* @brief Revert trial atom block iblock and free up memory space accordingly.
*/
static void revert_place_atom_block(const AtomBlockId blk_id,
t_lb_router_data* router_data,
bool &mol_validated,
const Prepacker& prepacker,
vtr::vector_map<AtomBlockId, LegalizationClusterId>& atom_cluster) {
const AtomContext& atom_ctx = g_vpr_ctx.atom();
Expand All @@ -1020,7 +1079,7 @@ static void revert_place_atom_block(const AtomBlockId blk_id,
*/

t_pb* next = pb->parent_pb;
revalid_molecules(pb, prepacker);
revalid_molecules(pb, mol_validated, prepacker);
free_pb(pb);
pb = next;

Expand All @@ -1037,7 +1096,7 @@ static void revert_place_atom_block(const AtomBlockId blk_id,
/* If the code gets here, then that means that placing the initial seed molecule
* failed, don't free the actual complex block itself as the seed needs to find
* another placement */
revalid_molecules(pb, prepacker);
revalid_molecules(pb, mol_validated, prepacker);
free_pb(pb);
}
}
Expand Down Expand Up @@ -1386,14 +1445,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
if (!atom_blk_id.is_valid())
continue;

/* invalidate all molecules that share atom block with current molecule */
t_pack_molecule* cur_molecule = prepacker_.get_atom_molecule(atom_blk_id);
// TODO: This should really be named better. Something like
// "is_clustered". and then it should be set to true.
// Right now, valid implies "not clustered" which is
// confusing.
cur_molecule->valid = false;

commit_primitive(cluster.placement_stats, primitives_list[i]);

atom_cluster_[atom_blk_id] = cluster_id;
Expand Down Expand Up @@ -1421,10 +1472,11 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
remove_atom_from_target(cluster.router_data, atom_blk_id);
}
}
bool mol_validated = false;
for (int i = 0; i < failed_location; i++) {
AtomBlockId atom_blk_id = molecule->atom_block_ids[i];
if (atom_blk_id) {
revert_place_atom_block(atom_blk_id, cluster.router_data, prepacker_, atom_cluster_);
revert_place_atom_block(atom_blk_id, cluster.router_data, mol_validated, prepacker_, atom_cluster_);
}
}

Expand Down Expand Up @@ -1562,17 +1614,13 @@ void ClusterLegalizer::destroy_cluster(LegalizationClusterId cluster_id) {
VTR_ASSERT_SAFE(molecule_cluster_.find(mol) != molecule_cluster_.end() &&
molecule_cluster_[mol] == cluster_id);
molecule_cluster_[mol] = LegalizationClusterId::INVALID();
// The overall clustering algorithm uses this valid flag to indicate
// that a molecule has not been packed (clustered) yet. Since we are
// destroying a cluster, all of its molecules are now no longer clustered
// so they are all validated.
mol->valid = true;
// Revert the placement of all blocks in the molecule.
bool mol_validated = false;
int molecule_size = get_array_size_of_molecule(mol);
for (int i = 0; i < molecule_size; i++) {
AtomBlockId atom_blk_id = mol->atom_block_ids[i];
if (atom_blk_id) {
revert_place_atom_block(atom_blk_id, cluster.router_data, prepacker_, atom_cluster_);
revert_place_atom_block(atom_blk_id, cluster.router_data, mol_validated, prepacker_, atom_cluster_);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions vpr/src/pack/cluster_legalizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,21 @@ class ClusterLegalizer {
return get_atom_cluster(blk_id) != LegalizationClusterId::INVALID();
}

/// @brief Returns true if the given molecule has been packed into a
/// cluster, false otherwise.
inline bool is_mol_clustered(t_pack_molecule* mol) const {
VTR_ASSERT_SAFE(mol != nullptr);
// Check if the molecule has been assigned a cluster. It has not been
// assigned a cluster if it does not have an entry in the map or if the
// ID of the cluster it is assigned to is invalid.
const auto iter = molecule_cluster_.find(mol);
if (iter == molecule_cluster_.end())
return false;
if (!iter->second.is_valid())
return false;
return true;
}

/// @brief Returns a reference to the target_external_pin_util object. This
/// allows the user to modify the external pin utilization if needed.
inline t_ext_pin_util_targets& get_target_external_pin_util() {
Expand Down
18 changes: 9 additions & 9 deletions vpr/src/pack/cluster_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ t_pack_molecule* get_molecule_by_num_ext_inputs(const int ext_inps,
t_molecule_link* ptr = unclustered_list_head[ext_inps].next;
while (ptr != nullptr) {
/* TODO: Get better candidate atom block in future, eg. return most timing critical or some other smarter metric */
if (ptr->moleculeptr->valid) {
if (!cluster_legalizer.is_mol_clustered(ptr->moleculeptr)) {
/* TODO: I should be using a better filtering check especially when I'm
* dealing with multiple clock/multiple global reset signals where the clock/reset
* packed in matters, need to do later when I have the circuits to check my work */
Expand Down Expand Up @@ -1197,7 +1197,7 @@ t_pack_molecule* get_highest_gain_molecule(t_pb* cur_pb,
cur_pb->pb_stats->num_feasible_blocks--;
int index = cur_pb->pb_stats->num_feasible_blocks;
molecule = cur_pb->pb_stats->feasible_blocks[index];
VTR_ASSERT(molecule->valid == true);
VTR_ASSERT(!cluster_legalizer.is_mol_clustered(molecule));
return molecule;
}

Expand All @@ -1218,7 +1218,7 @@ void add_cluster_molecule_candidates_by_connectivity_and_timing(t_pb* cur_pb,
for (AtomBlockId blk_id : cur_pb->pb_stats->marked_blocks) {
if (!cluster_legalizer.is_atom_clustered(blk_id)) {
t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) {
add_molecule_to_pb_stats_candidates(molecule,
cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups);
Expand Down Expand Up @@ -1251,7 +1251,7 @@ void add_cluster_molecule_candidates_by_highfanout_connectivity(t_pb* cur_pb,

if (!cluster_legalizer.is_atom_clustered(blk_id)) {
t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) {
add_molecule_to_pb_stats_candidates(molecule,
cur_pb->pb_stats->gain, cur_pb, std::min(feasible_block_array_size, AAPACK_MAX_HIGH_FANOUT_EXPLORE), attraction_groups);
Expand Down Expand Up @@ -1328,7 +1328,7 @@ void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb,
if (!cluster_legalizer.is_atom_clustered(atom_id)
&& std::find(candidate_types.begin(), candidate_types.end(), cluster_type) != candidate_types.end()) {
t_pack_molecule* molecule = prepacker.get_atom_molecule(atom_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) {
add_molecule_to_pb_stats_candidates(molecule,
cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups);
Expand Down Expand Up @@ -1359,7 +1359,7 @@ void add_cluster_molecule_candidates_by_attraction_group(t_pb* cur_pb,
if (!cluster_legalizer.is_atom_clustered(blk_id)
&& std::find(candidate_types.begin(), candidate_types.end(), cluster_type) != candidate_types.end()) {
t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) {
add_molecule_to_pb_stats_candidates(molecule,
cur_pb->pb_stats->gain, cur_pb, feasible_block_array_size, attraction_groups);
Expand Down Expand Up @@ -1390,7 +1390,7 @@ void add_cluster_molecule_candidates_by_transitive_connectivity(t_pb* cur_pb,
/* Only consider candidates that pass a very simple legality check */
for (const auto& transitive_candidate : cur_pb->pb_stats->transitive_fanout_candidates) {
t_pack_molecule* molecule = transitive_candidate.second;
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (cluster_legalizer.is_molecule_compatible(molecule, legalization_cluster_id)) {
add_molecule_to_pb_stats_candidates(molecule,
cur_pb->pb_stats->gain, cur_pb, std::min(feasible_block_array_size, AAPACK_MAX_TRANSITIVE_EXPLORE), attraction_groups);
Expand Down Expand Up @@ -1659,7 +1659,7 @@ t_pack_molecule* get_highest_gain_seed_molecule(int& seed_index,
t_pack_molecule* best = nullptr;

t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (best == nullptr || (best->base_gain) < (molecule->base_gain)) {
best = molecule;
}
Expand Down Expand Up @@ -1764,7 +1764,7 @@ void load_transitive_fanout_candidates(LegalizationClusterId legalization_cluste
pb_stats->gain[blk_id] += 0.001;
}
t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (molecule->valid) {
if (!cluster_legalizer.is_mol_clustered(molecule)) {
transitive_fanout_candidates.insert({molecule->atom_block_ids[molecule->root], molecule});
}
}
Expand Down
2 changes: 0 additions & 2 deletions vpr/src/pack/prepack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,6 @@ static t_pack_molecule* alloc_and_load_pack_molecules(t_pack_patterns* list_of_p
bool rng_empty = (rng.first == rng.second);
if (rng_empty) {
cur_molecule = new t_pack_molecule;
cur_molecule->valid = true;
cur_molecule->type = MOLECULE_SINGLE_ATOM;
cur_molecule->num_blocks = 1;
cur_molecule->root = 0;
Expand Down Expand Up @@ -983,7 +982,6 @@ static t_pack_molecule* try_create_molecule(t_pack_patterns* list_of_pack_patter
}

molecule = new t_pack_molecule;
molecule->valid = true;
molecule->type = MOLECULE_FORCED_PACK;
molecule->pack_pattern = pack_pattern;
molecule->atom_block_ids = std::vector<AtomBlockId>(pack_pattern->num_blocks); //Initializes invalid
Expand Down
17 changes: 0 additions & 17 deletions vpr/src/pack/prepack.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,6 @@ class Prepacker {
return molecules;
}

/**
* @brief Marks all of the molecules as valid.
*
* Within clustering, the valid flag of a molecule is used to signify if any
* of the atoms in the molecule has been packed into a cluster yet or not.
* If any atom in the molecule has been packed, the flag will be false.
*
* This method is used before clustering to mark all the molecules as
* unpacked.
*/
inline void mark_all_molecules_valid() {
t_pack_molecule* molecule_head = list_of_pack_molecules;
for (auto cur_molecule = molecule_head; cur_molecule != nullptr; cur_molecule = cur_molecule->next) {
cur_molecule->valid = true;
}
}

/**
* @brief Calculates maximum molecule statistics accross all molecules,
*/
Expand Down
52 changes: 0 additions & 52 deletions vpr/src/util/vpr_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1539,58 +1539,6 @@ void free_pb(t_pb* pb) {
free_pb_stats(pb);
}

void revalid_molecules(const t_pb* pb, const Prepacker& prepacker) {
const t_pb_type* pb_type = pb->pb_graph_node->pb_type;

if (pb_type->blif_model == nullptr) {
int mode = pb->mode;
for (int i = 0; i < pb_type->modes[mode].num_pb_type_children && pb->child_pbs != nullptr; i++) {
for (int j = 0; j < pb_type->modes[mode].pb_type_children[i].num_pb && pb->child_pbs[i] != nullptr; j++) {
if (pb->child_pbs[i][j].name != nullptr || pb->child_pbs[i][j].child_pbs != nullptr) {
revalid_molecules(&pb->child_pbs[i][j], prepacker);
}
}
}
} else {
//Primitive
auto& atom_ctx = g_vpr_ctx.mutable_atom();

auto blk_id = atom_ctx.lookup.pb_atom(pb);
if (blk_id) {
/* If any molecules were marked invalid because of this logic block getting packed, mark them valid */

//Update atom netlist mapping
atom_ctx.lookup.set_atom_clb(blk_id, ClusterBlockId::INVALID());
atom_ctx.lookup.set_atom_pb(blk_id, nullptr);

t_pack_molecule* cur_molecule = prepacker.get_atom_molecule(blk_id);
if (cur_molecule->valid == false) {
int i;
for (i = 0; i < get_array_size_of_molecule(cur_molecule); i++) {
if (cur_molecule->atom_block_ids[i]) {
if (atom_ctx.lookup.atom_clb(cur_molecule->atom_block_ids[i]) != ClusterBlockId::INVALID()) {
break;
}
}
}
/* All atom blocks are open for this molecule, place back in queue */
if (i == get_array_size_of_molecule(cur_molecule)) {
cur_molecule->valid = true;
// when invalidating a molecule check if it's a chain molecule
// that is part of a long chain. If so, check if this molecule
// have modified the chain_id value based on the stale packing
// then reset the chain id and the first packed molecule pointer
// this is packing is being reset
if (cur_molecule->is_chain() && cur_molecule->chain_info->is_long_chain && cur_molecule->chain_info->first_packed_molecule == cur_molecule) {
cur_molecule->chain_info->first_packed_molecule = nullptr;
cur_molecule->chain_info->chain_id = -1;
}
}
}
}
}
}

void free_pb_stats(t_pb* pb) {
if (pb) {
if (pb->pb_stats == nullptr) {
Expand Down
1 change: 0 additions & 1 deletion vpr/src/util/vpr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ void parse_direct_pin_name(char* src_string, int line, int* start_pin_index, int

void free_pb_stats(t_pb* pb);
void free_pb(t_pb* pb);
void revalid_molecules(const t_pb* pb, const Prepacker& prepacker);

void print_switch_usage();
void print_usage_by_wire_length();
Expand Down

0 comments on commit 49f3ab3

Please sign in to comment.