diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 73e52554e90..2d51c463372 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -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 @@ -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; diff --git a/vpr/src/pack/cluster.cpp b/vpr/src/pack/cluster.cpp index 93683858f3f..868a098cd96 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -145,8 +145,6 @@ std::map 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) { diff --git a/vpr/src/pack/cluster_legalizer.cpp b/vpr/src/pack/cluster_legalizer.cpp index ec722822fea..f85471e1636 100644 --- a/vpr/src/pack/cluster_legalizer.cpp +++ b/vpr/src/pack/cluster_legalizer.cpp @@ -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& atom_cluster) { const AtomContext& atom_ctx = g_vpr_ctx.atom(); AtomContext& mutable_atom_ctx = g_vpr_ctx.mutable_atom(); @@ -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; @@ -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); } } @@ -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; @@ -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); @@ -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. diff --git a/vpr/src/pack/cluster_legalizer.h b/vpr/src/pack/cluster_legalizer.h index 5be2404cfd1..1b0756cce32 100644 --- a/vpr/src/pack/cluster_legalizer.h +++ b/vpr/src/pack/cluster_legalizer.h @@ -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() { diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index 25b4af68441..284030202cb 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -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 */ @@ -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; } @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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; } @@ -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}); } } diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index a5928ba85f7..f7ade02d767 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -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; @@ -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(pack_pattern->num_blocks); //Initializes invalid diff --git a/vpr/src/pack/prepack.h b/vpr/src/pack/prepack.h index e6ac79cd425..74c1071a907 100644 --- a/vpr/src/pack/prepack.h +++ b/vpr/src/pack/prepack.h @@ -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, */ diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index 3caf87e43ba..7bc25df01a0 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -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) { diff --git a/vpr/src/util/vpr_utils.h b/vpr/src/util/vpr_utils.h index 9f08dcc0d2b..ae014df471e 100644 --- a/vpr/src/util/vpr_utils.h +++ b/vpr/src/util/vpr_utils.h @@ -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();