Skip to content

Commit

Permalink
Merge pull request verilog-to-routing#2796 from AlexandreSinger/featu…
Browse files Browse the repository at this point in the history
…re-prepacker-rework

[Prepacker] Removed Valid Flag From Molecules
  • Loading branch information
AlexandreSinger authored Nov 6, 2024
2 parents 7a2cf8d + a34ebf1 commit 92babb5
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 103 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
47 changes: 29 additions & 18 deletions vpr/src/pack/cluster_legalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,12 +997,36 @@ static void update_molecule_chain_info(t_pack_molecule* chain_molecule, const t_
VTR_ASSERT(false);
}

/*
* @brief Reset molecule information created while trying to cluster it.
*
* This code only resets information that has to do with long chains.
*
* TODO: This information should not be stored in the molecule, but should be
* stored in the ClusterLegalizer class instead.
*
* TODO: This code may be removable. Tried turning it off and found no test
* failures or QoR degredations. Should be investigated in more detail.
*/
static void reset_molecule_info(t_pack_molecule* mol) {
// when invalidating a molecule check if it's a chain molecule
// that is part of a long chain. If so, check if this molecule
// has 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 (mol->is_chain()
&& mol->chain_info->is_long_chain
&& mol->chain_info->first_packed_molecule == mol) {
mol->chain_info->first_packed_molecule = nullptr;
mol->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,
const Prepacker& prepacker,
vtr::vector_map<AtomBlockId, LegalizationClusterId>& atom_cluster) {
const AtomContext& atom_ctx = g_vpr_ctx.atom();
AtomContext& mutable_atom_ctx = g_vpr_ctx.mutable_atom();
Expand All @@ -1020,7 +1044,6 @@ static void revert_place_atom_block(const AtomBlockId blk_id,
*/

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

Expand All @@ -1037,7 +1060,6 @@ 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);
free_pb(pb);
}
}
Expand Down Expand Up @@ -1386,14 +1408,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 @@ -1424,9 +1438,10 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
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, atom_cluster_);
}
}
reset_molecule_info(molecule);

// Record the failure of this molecule in the current pb stats
record_molecule_failure(molecule, cluster.pb);
Expand Down Expand Up @@ -1562,19 +1577,15 @@ 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.
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, atom_cluster_);
}
}
reset_molecule_info(mol);
}
cluster.molecules.clear();
// Free the rest of the cluster data.
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 92babb5

Please sign in to comment.