Skip to content

[Packer] Greedy Clustering Candidate Selector Class #2856

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
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
68 changes: 17 additions & 51 deletions vpr/src/pack/cluster_legalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "atom_netlist.h"
#include "cluster_placement.h"
#include "cluster_router.h"
#include "cluster_util.h"
#include "globals.h"
#include "logic_types.h"
#include "netlist_utils.h"
Expand Down Expand Up @@ -80,7 +79,7 @@ static size_t calc_max_cluster_size(const std::vector<t_logical_block_type>& log
*
* Used to store information used during clustering.
*/
static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_size) {
static void alloc_and_load_pb_stats(t_pb* pb) {
/* Call this routine when starting to fill up a new cluster. It resets *
* the gain vector, etc. */

Expand All @@ -90,29 +89,8 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
pb->pb_stats->output_pins_used = std::vector<std::unordered_map<size_t, AtomNetId>>(pb->pb_graph_node->num_output_pin_class);
pb->pb_stats->lookahead_input_pins_used = std::vector<std::vector<AtomNetId>>(pb->pb_graph_node->num_input_pin_class);
pb->pb_stats->lookahead_output_pins_used = std::vector<std::vector<AtomNetId>>(pb->pb_graph_node->num_output_pin_class);
pb->pb_stats->num_feasible_blocks = NOT_VALID;
pb->pb_stats->feasible_blocks = new t_pack_molecule*[feasible_block_array_size];

for (int i = 0; i < feasible_block_array_size; i++)
pb->pb_stats->feasible_blocks[i] = nullptr;

pb->pb_stats->tie_break_high_fanout_net = AtomNetId::INVALID();

pb->pb_stats->pulled_from_atom_groups = 0;
pb->pb_stats->num_att_group_atoms_used = 0;

pb->pb_stats->gain.clear();
pb->pb_stats->timinggain.clear();
pb->pb_stats->connectiongain.clear();
pb->pb_stats->sharinggain.clear();
pb->pb_stats->hillgain.clear();
pb->pb_stats->transitive_fanout_candidates.clear();

pb->pb_stats->num_pins_of_net_in_pb.clear();

pb->pb_stats->num_child_blocks_in_pb = 0;

pb->pb_stats->explore_transitive_fanout = true;
}

/*
Expand Down Expand Up @@ -176,22 +154,6 @@ static void free_pb_stats_recursive(t_pb* pb) {
}
}

/* Record the failure of the molecule in this cluster in the current pb stats.
* If a molecule fails repeatedly, it's gain will be penalized if packing with
* attraction groups on. */
static void record_molecule_failure(t_pack_molecule* molecule, t_pb* pb) {
//Only have to record the failure for the first atom in the molecule.
//The convention when checking if a molecule has failed to pack in the cluster
//is to check whether the first atoms has been recorded as having failed

auto got = pb->pb_stats->atom_failures.find(molecule->atom_block_ids[0]);
if (got == pb->pb_stats->atom_failures.end()) {
pb->pb_stats->atom_failures.insert({molecule->atom_block_ids[0], 1});
} else {
got->second++;
}
}

/**
* @brief Checks whether an atom block can be added to a clustered block
* without violating floorplanning constraints. It also updates the
Expand Down Expand Up @@ -572,7 +534,7 @@ try_place_atom_block_rec(const t_pb_graph_node* pb_graph_node,
*parent = pb; /* this pb is parent of it's child that called this function */
VTR_ASSERT(pb->pb_graph_node == pb_graph_node);
if (pb->pb_stats == nullptr) {
alloc_and_load_pb_stats(pb, feasible_block_array_size);
alloc_and_load_pb_stats(pb);
}
const t_pb_type* pb_type = pb_graph_node->pb_type;

Expand Down Expand Up @@ -1216,9 +1178,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
// macros that limit placement flexibility.
if (cluster.placement_stats->has_long_chain && molecule->is_chain() && molecule->chain_info->is_long_chain) {
VTR_LOGV(log_verbosity_ > 4, "\t\t\tFAILED Placement Feasibility Filter: Only one long chain per cluster is allowed\n");
//Record the failure of this molecule in the current pb stats
record_molecule_failure(molecule, cluster.pb);
// Free the allocated data.
return e_block_pack_status::BLK_FAILED_FEASIBLE;
}

Expand All @@ -1240,8 +1199,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
log_verbosity_,
cluster_pr_needs_update);
if (!block_pack_floorplan_status) {
// Record the failure of this molecule in the current pb stats
record_molecule_failure(molecule, cluster.pb);
return e_block_pack_status::BLK_FAILED_FLOORPLANNING;
}

Expand All @@ -1262,8 +1219,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
atom_noc_grp_id_,
log_verbosity_);
if (!block_pack_noc_grp_status) {
// Record the failure of this molecule in the current pb stats
record_molecule_failure(molecule, cluster.pb);
return e_block_pack_status::BLK_FAILED_NOC_GROUP;
}
}
Expand Down Expand Up @@ -1443,9 +1398,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
}
reset_molecule_info(molecule);

// Record the failure of this molecule in the current pb stats
record_molecule_failure(molecule, cluster.pb);

/* 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. */
Expand Down Expand Up @@ -1481,7 +1433,7 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
// Create the physical block for this cluster based on the type.
t_pb* cluster_pb = new t_pb;
cluster_pb->pb_graph_node = cluster_type->pb_graph_head;
alloc_and_load_pb_stats(cluster_pb, feasible_block_array_size_);
alloc_and_load_pb_stats(cluster_pb);
cluster_pb->parent_pb = nullptr;
cluster_pb->mode = cluster_mode;

Expand Down Expand Up @@ -1821,6 +1773,20 @@ bool ClusterLegalizer::is_molecule_compatible(t_pack_molecule* molecule,
return true;
}

size_t ClusterLegalizer::get_num_cluster_inputs_available(
LegalizationClusterId cluster_id) const {
VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters_.size());
const LegalizationCluster& cluster = legalization_clusters_[cluster_id];

// Count the number of inputs available per pin class.
size_t inputs_avail = 0;
for (int i = 0; i < cluster.pb->pb_graph_node->num_input_pin_class; i++) {
inputs_avail += cluster.pb->pb_stats->input_pins_used[i].size();
}

return inputs_avail;
}

void ClusterLegalizer::finalize() {
for (LegalizationClusterId cluster_id : legalization_cluster_ids_) {
if (!cluster_id.is_valid())
Expand Down
3 changes: 3 additions & 0 deletions vpr/src/pack/cluster_legalizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ class ClusterLegalizer {
return cluster.molecules.size();
}

/// @brief Gets the total number of cluster inputs available.
size_t get_num_cluster_inputs_available(LegalizationClusterId cluster_id) const;

/// @brief Gets the ID of the cluster that contains the given atom block.
inline LegalizationClusterId get_atom_cluster(AtomBlockId blk_id) const {
VTR_ASSERT_SAFE(blk_id.is_valid() && (size_t)blk_id < atom_cluster_.size());
Expand Down
Loading
Loading