Skip to content

Change GreedySeedSelector to work with molecules instead of atoms #3024

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
6 changes: 2 additions & 4 deletions vpr/src/pack/greedy_clusterer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ GreedyClusterer::do_clustering(ClusterLegalizer& cluster_legalizer,
pre_cluster_timing_manager_);

// Pick the first seed molecule.
PackMoleculeId seed_mol_id = seed_selector.get_next_seed(prepacker,
cluster_legalizer);
PackMoleculeId seed_mol_id = seed_selector.get_next_seed(cluster_legalizer);

/****************************************************************
* Clustering
Expand Down Expand Up @@ -213,8 +212,7 @@ GreedyClusterer::do_clustering(ClusterLegalizer& cluster_legalizer,
cluster_legalizer);

// Pick new seed.
seed_mol_id = seed_selector.get_next_seed(prepacker,
cluster_legalizer);
seed_mol_id = seed_selector.get_next_seed(cluster_legalizer);
}

// If this architecture has LE physical block, report its usage.
Expand Down
99 changes: 55 additions & 44 deletions vpr/src/pack/greedy_seed_selector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include <algorithm>
#include <cmath>
#include <limits>
#include <vector>
#include "PreClusterTimingManager.h"
#include "atom_netlist.h"
#include "cluster_legalizer.h"
Expand Down Expand Up @@ -129,11 +131,12 @@ static inline float get_seed_gain(AtomBlockId blk_id,
* criticalities.
*/
static inline void print_seed_gains(const char* fname,
const std::vector<AtomBlockId>& seed_atoms,
const vtr::vector<AtomBlockId, float>& atom_gain,
const std::vector<PackMoleculeId>& seed_mols,
const vtr::vector<PackMoleculeId, float>& molecule_gain,
const vtr::vector<AtomBlockId, float>& atom_criticality,
const AtomNetlist& atom_netlist,
const LogicalModels& models) {
const LogicalModels& models,
const Prepacker& prepacker) {
FILE* fp = vtr::fopen(fname, "w");

// For pretty formatting determine the maximum name length
Expand All @@ -148,16 +151,18 @@ static inline void print_seed_gains(const char* fname,

fprintf(fp, "%-*s %-*s %8s %8s\n", max_name_len, "atom_block_name", max_type_len, "atom_block_type", "gain", "criticality");
fprintf(fp, "\n");
for (auto blk_id : seed_atoms) {
std::string name = atom_netlist.block_name(blk_id);
fprintf(fp, "%-*s ", max_name_len, name.c_str());
for (auto mol_id : seed_mols) {
for (AtomBlockId blk_id : prepacker.get_molecule(mol_id).atom_block_ids) {
std::string name = atom_netlist.block_name(blk_id);
fprintf(fp, "%-*s ", max_name_len, name.c_str());

std::string model_name = models.model_name(atom_netlist.block_model(blk_id));
fprintf(fp, "%-*s ", max_type_len, model_name.c_str());
std::string model_name = models.model_name(atom_netlist.block_model(blk_id));
fprintf(fp, "%-*s ", max_type_len, model_name.c_str());

fprintf(fp, "%*f ", std::max((int)strlen("gain"), 8), atom_gain[blk_id]);
fprintf(fp, "%*f ", std::max((int)strlen("criticality"), 8), atom_criticality[blk_id]);
fprintf(fp, "\n");
fprintf(fp, "%*f ", std::max((int)strlen("gain"), 8), molecule_gain[mol_id]);
fprintf(fp, "%*f ", std::max((int)strlen("criticality"), 8), atom_criticality[blk_id]);
fprintf(fp, "\n");
}
}

fclose(fp);
Expand All @@ -169,8 +174,8 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
const t_molecule_stats& max_molecule_stats,
const LogicalModels& models,
const PreClusterTimingManager& pre_cluster_timing_manager)
: seed_atoms_(atom_netlist.blocks().begin(), atom_netlist.blocks().end()) {
// Seed atoms list is initialized with all atoms in the atom netlist.
: seed_mols_(prepacker.molecules().begin(), prepacker.molecules().end()) {
// Seed molecule list is initialized with all molecule in the netlist.

// Pre-compute the criticality of each atom
// Default criticalities set to zero (e.g. if not timing driven)
Expand All @@ -183,20 +188,31 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
}
}

// Maintain a lookup table of the seed gain for each atom. This will be
// used to sort the seed atoms.
// Maintain a lookup table of the seed gain for each molecule. This will be
// used to sort the seed molecules.
// Initially all gains are zero.
vtr::vector<AtomBlockId, float> atom_gains(atom_netlist.blocks().size(), 0.f);

// Get the seed gain of each atom.
for (AtomBlockId blk_id : atom_netlist.blocks()) {
atom_gains[blk_id] = get_seed_gain(blk_id,
atom_netlist,
prepacker,
models,
seed_type,
max_molecule_stats,
atom_criticality);
vtr::vector<PackMoleculeId, float> molecule_gains(seed_mols_.size(), 0.f);

// Get the seed gain of each molecule.
for (PackMoleculeId mol_id : seed_mols_) {
// Gain of each molecule is the maximum gain of its atoms
float mol_gain = std::numeric_limits<float>::lowest();
const std::vector<AtomBlockId>& molecule_atoms = prepacker.get_molecule(mol_id).atom_block_ids;
for (AtomBlockId blk_id : molecule_atoms) {
// If the molecule does not fit the entire pack pattern, it's possible to have invalid block ids in the molecule_atoms vector
if (blk_id == AtomBlockId::INVALID()) {
continue;
}
float atom_gain = get_seed_gain(blk_id,
atom_netlist,
prepacker,
models,
seed_type,
max_molecule_stats,
atom_criticality);
mol_gain = std::max(mol_gain, atom_gain);
}
molecule_gains[mol_id] = mol_gain;
}

// Sort seeds in descending order of seed gain (i.e. highest seed gain first)
Expand All @@ -207,47 +223,42 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
// std::sort which does not specify how equal values are handled). Using a stable
// sort ensures that regardless of the underlying sorting algorithm the same seed
// order is produced regardless of compiler.
auto by_descending_gain = [&](const AtomBlockId lhs, const AtomBlockId rhs) {
return atom_gains[lhs] > atom_gains[rhs];
auto by_descending_gain = [&](const PackMoleculeId lhs, const PackMoleculeId rhs) {
return molecule_gains[lhs] > molecule_gains[rhs];
};
std::stable_sort(seed_atoms_.begin(), seed_atoms_.end(), by_descending_gain);
std::stable_sort(seed_mols_.begin(), seed_mols_.end(), by_descending_gain);

// Print the seed gains if requested.
if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_CLUSTERING_BLOCK_CRITICALITIES)) {
print_seed_gains(getEchoFileName(E_ECHO_CLUSTERING_BLOCK_CRITICALITIES),
seed_atoms_, atom_gains, atom_criticality, atom_netlist, models);
seed_mols_, molecule_gains, atom_criticality, atom_netlist, models, prepacker);
}

// Set the starting seed index (the index of the first molecule to propose).
// The index of the first seed to propose is the first molecule in the
// seed atoms vector (i.e. the one with the highest seed gain).
// seed molecules vector (i.e. the one with the highest seed gain).
seed_index_ = 0;
}

PackMoleculeId GreedySeedSelector::get_next_seed(const Prepacker& prepacker,
const ClusterLegalizer& cluster_legalizer) {
while (seed_index_ < seed_atoms_.size()) {
// Get the current seed atom at the seed index and increment the
PackMoleculeId GreedySeedSelector::get_next_seed(const ClusterLegalizer& cluster_legalizer) {
while (seed_index_ < seed_mols_.size()) {
// Get the current seed molecule at the seed index and increment the
// seed index.
// All previous seed indices have been either proposed already or
// are already clustered. This process assumes that once an atom
// is clustered it will never become unclustered.
AtomBlockId seed_blk_id = seed_atoms_[seed_index_++];
PackMoleculeId seed_molecule_id = seed_mols_[seed_index_++];

// If this atom has been clustered, it cannot be proposed as a seed.
// If this molecule has been clustered, it cannot be proposed as a seed.
// Skip to the next seed.
if (cluster_legalizer.is_atom_clustered(seed_blk_id))
if (cluster_legalizer.is_mol_clustered(seed_molecule_id)) {
continue;

// Get the molecule that contains this atom and return it as the
// next seed.
PackMoleculeId seed_molecule_id = prepacker.get_atom_molecule(seed_blk_id);
VTR_ASSERT(!cluster_legalizer.is_mol_clustered(seed_molecule_id));
}
return seed_molecule_id;
}

// If the previous loop does not return a molecule, it implies that all
// atoms have been clustered or have already been proposed as a seed.
// molecule have been clustered or have already been proposed as a seed.
// Return nullptr to signify that there are no further seeds.
return PackMoleculeId::INVALID();
}
18 changes: 5 additions & 13 deletions vpr/src/pack/greedy_seed_selector.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,32 +68,24 @@ class GreedySeedSelector {
* This method assumes that once a molecule is clustered, it will never be
* unclustered.
*
* @param prepacker
* The prepacker object that stores the molecules.
* @param cluster_legalizer
* The cluster legalizer object that is used to create the
* clusters. This is used to check if a molecule has already
* been clustered or not.
*/
PackMoleculeId get_next_seed(const Prepacker& prepacker,
const ClusterLegalizer& cluster_legalizer);
PackMoleculeId get_next_seed(const ClusterLegalizer& cluster_legalizer);

// TODO: Maybe create an update_seed_gains method to update the seed atoms
// TODO: Maybe create an update_seed_gains method to update the seed molecules
// list using current clustering information.

private:
/// @brief The index of the next seed to propose in the seed_atoms vector.
/// @brief The index of the next seed to propose in the seed_mols_ vector.
/// This is set to 0 in the constructor and incremented as more seeds
/// are proposed.
size_t seed_index_;

/// @brief A list of seed atoms, sorted in decreasing order of gain. This
/// @brief A list of seed molecules, sorted in decreasing order of gain. This
/// is computed in the constructor and is traversed when a new seed
/// is being proposed.
// FIXME: This should really be seed molecules. It looks like the only
// reason it isn't is because of the atom criticality. May want to
// create the concept of molecule criticality. Currently, the max
// criticality of any block in the molecule is technically being
// used.
std::vector<AtomBlockId> seed_atoms_;
std::vector<PackMoleculeId> seed_mols_;
};
Loading