Skip to content

Commit 3eb9eff

Browse files
[Packer] Greedy Clustering Candidate Selector Class
Outlined all of the logic related to selecting a candidate molecule to pack into a given cluster into its own class. This class will maintain the information required for computing gains and selecting the highest gain molecule to pack. By separating out this logic, it makes it easier to modify and contribute to this code since it is now obvious where the code starts and where it ends. I have also went through and tried to modernize anything I could (for example, replacing C-style arrays for vectors). This code still needs a lot more cleanup, but this PR will be a good stepping stone for future refactorings.
1 parent 0b20db9 commit 3eb9eff

14 files changed

+1789
-1713
lines changed

vpr/src/pack/cluster_legalizer.cpp

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "atom_netlist.h"
2020
#include "cluster_placement.h"
2121
#include "cluster_router.h"
22-
#include "cluster_util.h"
2322
#include "globals.h"
2423
#include "logic_types.h"
2524
#include "netlist_utils.h"
@@ -80,7 +79,7 @@ static size_t calc_max_cluster_size(const std::vector<t_logical_block_type>& log
8079
*
8180
* Used to store information used during clustering.
8281
*/
83-
static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_size) {
82+
static void alloc_and_load_pb_stats(t_pb* pb) {
8483
/* Call this routine when starting to fill up a new cluster. It resets *
8584
* the gain vector, etc. */
8685

@@ -90,29 +89,8 @@ static void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_siz
9089
pb->pb_stats->output_pins_used = std::vector<std::unordered_map<size_t, AtomNetId>>(pb->pb_graph_node->num_output_pin_class);
9190
pb->pb_stats->lookahead_input_pins_used = std::vector<std::vector<AtomNetId>>(pb->pb_graph_node->num_input_pin_class);
9291
pb->pb_stats->lookahead_output_pins_used = std::vector<std::vector<AtomNetId>>(pb->pb_graph_node->num_output_pin_class);
93-
pb->pb_stats->num_feasible_blocks = NOT_VALID;
94-
pb->pb_stats->feasible_blocks = new t_pack_molecule*[feasible_block_array_size];
95-
96-
for (int i = 0; i < feasible_block_array_size; i++)
97-
pb->pb_stats->feasible_blocks[i] = nullptr;
98-
99-
pb->pb_stats->tie_break_high_fanout_net = AtomNetId::INVALID();
100-
101-
pb->pb_stats->pulled_from_atom_groups = 0;
102-
pb->pb_stats->num_att_group_atoms_used = 0;
103-
104-
pb->pb_stats->gain.clear();
105-
pb->pb_stats->timinggain.clear();
106-
pb->pb_stats->connectiongain.clear();
107-
pb->pb_stats->sharinggain.clear();
108-
pb->pb_stats->hillgain.clear();
109-
pb->pb_stats->transitive_fanout_candidates.clear();
110-
111-
pb->pb_stats->num_pins_of_net_in_pb.clear();
11292

11393
pb->pb_stats->num_child_blocks_in_pb = 0;
114-
115-
pb->pb_stats->explore_transitive_fanout = true;
11694
}
11795

11896
/*
@@ -176,22 +154,6 @@ static void free_pb_stats_recursive(t_pb* pb) {
176154
}
177155
}
178156

179-
/* Record the failure of the molecule in this cluster in the current pb stats.
180-
* If a molecule fails repeatedly, it's gain will be penalized if packing with
181-
* attraction groups on. */
182-
static void record_molecule_failure(t_pack_molecule* molecule, t_pb* pb) {
183-
//Only have to record the failure for the first atom in the molecule.
184-
//The convention when checking if a molecule has failed to pack in the cluster
185-
//is to check whether the first atoms has been recorded as having failed
186-
187-
auto got = pb->pb_stats->atom_failures.find(molecule->atom_block_ids[0]);
188-
if (got == pb->pb_stats->atom_failures.end()) {
189-
pb->pb_stats->atom_failures.insert({molecule->atom_block_ids[0], 1});
190-
} else {
191-
got->second++;
192-
}
193-
}
194-
195157
/**
196158
* @brief Checks whether an atom block can be added to a clustered block
197159
* without violating floorplanning constraints. It also updates the
@@ -572,7 +534,7 @@ try_place_atom_block_rec(const t_pb_graph_node* pb_graph_node,
572534
*parent = pb; /* this pb is parent of it's child that called this function */
573535
VTR_ASSERT(pb->pb_graph_node == pb_graph_node);
574536
if (pb->pb_stats == nullptr) {
575-
alloc_and_load_pb_stats(pb, feasible_block_array_size);
537+
alloc_and_load_pb_stats(pb);
576538
}
577539
const t_pb_type* pb_type = pb_graph_node->pb_type;
578540

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

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

@@ -1262,8 +1219,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
12621219
atom_noc_grp_id_,
12631220
log_verbosity_);
12641221
if (!block_pack_noc_grp_status) {
1265-
// Record the failure of this molecule in the current pb stats
1266-
record_molecule_failure(molecule, cluster.pb);
12671222
return e_block_pack_status::BLK_FAILED_NOC_GROUP;
12681223
}
12691224
}
@@ -1443,9 +1398,6 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
14431398
}
14441399
reset_molecule_info(molecule);
14451400

1446-
// Record the failure of this molecule in the current pb stats
1447-
record_molecule_failure(molecule, cluster.pb);
1448-
14491401
/* Packing failed, but a part of the pb tree is still allocated and pbs have their modes set.
14501402
* Before trying to pack next molecule the unused pbs need to be freed and, the most important,
14511403
* their modes reset. This task is performed by the cleanup_pb() function below. */
@@ -1481,7 +1433,7 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
14811433
// Create the physical block for this cluster based on the type.
14821434
t_pb* cluster_pb = new t_pb;
14831435
cluster_pb->pb_graph_node = cluster_type->pb_graph_head;
1484-
alloc_and_load_pb_stats(cluster_pb, feasible_block_array_size_);
1436+
alloc_and_load_pb_stats(cluster_pb);
14851437
cluster_pb->parent_pb = nullptr;
14861438
cluster_pb->mode = cluster_mode;
14871439

@@ -1821,6 +1773,20 @@ bool ClusterLegalizer::is_molecule_compatible(t_pack_molecule* molecule,
18211773
return true;
18221774
}
18231775

1776+
size_t ClusterLegalizer::get_num_cluster_inputs_available(
1777+
LegalizationClusterId cluster_id) const {
1778+
VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters_.size());
1779+
const LegalizationCluster& cluster = legalization_clusters_[cluster_id];
1780+
1781+
// Count the number of inputs available per pin class.
1782+
size_t inputs_avail = 0;
1783+
for (int i = 0; i < cluster.pb->pb_graph_node->num_input_pin_class; i++) {
1784+
inputs_avail += cluster.pb->pb_stats->input_pins_used[i].size();
1785+
}
1786+
1787+
return inputs_avail;
1788+
}
1789+
18241790
void ClusterLegalizer::finalize() {
18251791
for (LegalizationClusterId cluster_id : legalization_cluster_ids_) {
18261792
if (!cluster_id.is_valid())

vpr/src/pack/cluster_legalizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ class ClusterLegalizer {
428428
return cluster.molecules.size();
429429
}
430430

431+
/// @brief Gets the total number of cluster inputs available.
432+
size_t get_num_cluster_inputs_available(LegalizationClusterId cluster_id) const;
433+
431434
/// @brief Gets the ID of the cluster that contains the given atom block.
432435
inline LegalizationClusterId get_atom_cluster(AtomBlockId blk_id) const {
433436
VTR_ASSERT_SAFE(blk_id.is_valid() && (size_t)blk_id < atom_cluster_.size());

0 commit comments

Comments
 (0)