Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
vaughnbetz authored Nov 22, 2024
2 parents 2bdc0e9 + b007516 commit 7c93264
Show file tree
Hide file tree
Showing 220 changed files with 1,646 additions and 1,397 deletions.
1 change: 0 additions & 1 deletion vpr/src/analytical_place/full_legalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "ShowSetup.h"
#include "ap_netlist_fwd.h"
#include "check_netlist.h"
#include "cluster.h"
#include "cluster_legalizer.h"
#include "cluster_util.h"
#include "clustered_netlist.h"
Expand Down
1 change: 0 additions & 1 deletion vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
#include "check_route.h"
#include "constant_nets.h"
#include "atom_netlist_utils.h"
#include "cluster.h"
#include "output_clustering.h"
#include "vpr_constraints_reader.h"
#include "place_constraints.h"
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/vpr_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ t_ext_pin_util_targets::t_ext_pin_util_targets(const std::vector<std::string>& s
//input pin utilization target which is high, but less than 100%.
if (logic_block_type != nullptr) {
constexpr float LOGIC_BLOCK_TYPE_AUTO_INPUT_UTIL = 0.8;
constexpr float LOGIC_BLOCK_TYPE_AUTO_OUTPUT_UTIL = 1.0;
constexpr float LOGIC_BLOCK_TYPE_AUTO_OUTPUT_UTIL = 0.6;

t_ext_pin_util logic_block_ext_pin_util(LOGIC_BLOCK_TYPE_AUTO_INPUT_UTIL, LOGIC_BLOCK_TYPE_AUTO_OUTPUT_UTIL);

Expand Down
32 changes: 0 additions & 32 deletions vpr/src/pack/cluster.h

This file was deleted.

208 changes: 26 additions & 182 deletions vpr/src/pack/cluster_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1523,156 +1523,6 @@ t_molecule_stats calc_molecule_stats(const t_pack_molecule* molecule, const Atom
return molecule_stats;
}

std::vector<AtomBlockId> initialize_seed_atoms(const e_cluster_seed seed_type,
const t_molecule_stats& max_molecule_stats,
const Prepacker& prepacker,
const vtr::vector<AtomBlockId, float>& atom_criticality) {
const AtomNetlist& atom_nlist = g_vpr_ctx.atom().nlist;

//Put all atoms in seed list
std::vector<AtomBlockId> seed_atoms(atom_nlist.blocks().begin(), atom_nlist.blocks().end());

//Initially all gains are zero
vtr::vector<AtomBlockId, float> atom_gains(atom_nlist.blocks().size(), 0.);

if (seed_type == e_cluster_seed::TIMING) {
VTR_ASSERT(atom_gains.size() == atom_criticality.size());

//By criticality
atom_gains = atom_criticality;

} else if (seed_type == e_cluster_seed::MAX_INPUTS) {
//By number of used molecule input pins
for (auto blk : atom_nlist.blocks()) {
const t_pack_molecule* blk_mol = prepacker.get_atom_molecule(blk);
const t_molecule_stats molecule_stats = calc_molecule_stats(blk_mol, atom_nlist);
atom_gains[blk] = molecule_stats.num_used_ext_inputs;
}

} else if (seed_type == e_cluster_seed::BLEND) {
//By blended gain (criticality and inputs used)
for (auto blk : atom_nlist.blocks()) {
/* Score seed gain of each block as a weighted sum of timing criticality,
* number of tightly coupled blocks connected to it, and number of external inputs */
float seed_blend_fac = 0.5;

const t_pack_molecule* blk_mol = prepacker.get_atom_molecule(blk);
const t_molecule_stats molecule_stats = calc_molecule_stats(blk_mol, atom_nlist);
VTR_ASSERT(max_molecule_stats.num_used_ext_inputs > 0);

float blend_gain = (seed_blend_fac * atom_criticality[blk]
+ (1 - seed_blend_fac) * (molecule_stats.num_used_ext_inputs / max_molecule_stats.num_used_ext_inputs));
blend_gain *= (1 + 0.2 * (molecule_stats.num_blocks - 1));
atom_gains[blk] = blend_gain;
}

} else if (seed_type == e_cluster_seed::MAX_PINS || seed_type == e_cluster_seed::MAX_INPUT_PINS) {
//By pins per molecule (i.e. available pins on primitives, not pins in use)

for (auto blk : atom_nlist.blocks()) {
const t_pack_molecule* mol = prepacker.get_atom_molecule(blk);
const t_molecule_stats molecule_stats = calc_molecule_stats(mol, atom_nlist);

int molecule_pins = 0;
if (seed_type == e_cluster_seed::MAX_PINS) {
//All pins
molecule_pins = molecule_stats.num_pins;
} else {
VTR_ASSERT(seed_type == e_cluster_seed::MAX_INPUT_PINS);
//Input pins only
molecule_pins = molecule_stats.num_input_pins;
}

atom_gains[blk] = molecule_pins;
}

} else if (seed_type == e_cluster_seed::BLEND2) {
for (auto blk : atom_nlist.blocks()) {
const t_pack_molecule* mol = prepacker.get_atom_molecule(blk);
const t_molecule_stats molecule_stats = calc_molecule_stats(mol, atom_nlist);

float pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_pins, max_molecule_stats.num_pins);
float input_pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_input_pins, max_molecule_stats.num_input_pins);
float output_pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_output_pins, max_molecule_stats.num_output_pins);
float used_ext_pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_used_ext_pins, max_molecule_stats.num_used_ext_pins);
float used_ext_input_pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_used_ext_inputs, max_molecule_stats.num_used_ext_inputs);
float used_ext_output_pin_ratio = vtr::safe_ratio<float>(molecule_stats.num_used_ext_outputs, max_molecule_stats.num_used_ext_outputs);
float num_blocks_ratio = vtr::safe_ratio<float>(molecule_stats.num_blocks, max_molecule_stats.num_blocks);
float criticality = atom_criticality[blk];

constexpr float PIN_WEIGHT = 0.;
constexpr float INPUT_PIN_WEIGHT = 0.5;
constexpr float OUTPUT_PIN_WEIGHT = 0.;
constexpr float USED_PIN_WEIGHT = 0.;
constexpr float USED_INPUT_PIN_WEIGHT = 0.2;
constexpr float USED_OUTPUT_PIN_WEIGHT = 0.;
constexpr float BLOCKS_WEIGHT = 0.2;
constexpr float CRITICALITY_WEIGHT = 0.1;

float gain = PIN_WEIGHT * pin_ratio
+ INPUT_PIN_WEIGHT * input_pin_ratio
+ OUTPUT_PIN_WEIGHT * output_pin_ratio

+ USED_PIN_WEIGHT * used_ext_pin_ratio
+ USED_INPUT_PIN_WEIGHT * used_ext_input_pin_ratio
+ USED_OUTPUT_PIN_WEIGHT * used_ext_output_pin_ratio

+ BLOCKS_WEIGHT * num_blocks_ratio
+ CRITICALITY_WEIGHT * criticality;

atom_gains[blk] = gain;
}

} else {
VPR_FATAL_ERROR(VPR_ERROR_PACK, "Unrecognized cluster seed type");
}

//Sort seeds in descending order of gain (i.e. highest gain first)
//
// Note that we use a *stable* sort here. It has been observed that different
// standard library implementations (e.g. gcc-4.9 vs gcc-5) use sorting algorithms
// which produce different orderings for seeds of equal gain (which is allowed with
// 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];
};
std::stable_sort(seed_atoms.begin(), seed_atoms.end(), by_descending_gain);

if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_CLUSTERING_BLOCK_CRITICALITIES)) {
print_seed_gains(getEchoFileName(E_ECHO_CLUSTERING_BLOCK_CRITICALITIES), seed_atoms, atom_gains, atom_criticality);
}

return seed_atoms;
}

t_pack_molecule* get_highest_gain_seed_molecule(int& seed_index,
const std::vector<AtomBlockId>& seed_atoms,
const Prepacker& prepacker,
const ClusterLegalizer& cluster_legalizer) {
while (seed_index < static_cast<int>(seed_atoms.size())) {
AtomBlockId blk_id = seed_atoms[seed_index++];

// Check if the atom has already been assigned to a cluster
if (!cluster_legalizer.is_atom_clustered(blk_id)) {
t_pack_molecule* best = nullptr;

t_pack_molecule* molecule = prepacker.get_atom_molecule(blk_id);
if (!cluster_legalizer.is_mol_clustered(molecule)) {
if (best == nullptr || (best->base_gain) < (molecule->base_gain)) {
best = molecule;
}
}
VTR_ASSERT(best != nullptr);
return best;
}
}

/*if it makes it to here , there are no more blocks available*/
return nullptr;
}

float get_molecule_gain(t_pack_molecule* molecule, std::map<AtomBlockId, float>& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, int num_molecule_failures) {
float gain;
int i;
Expand Down Expand Up @@ -1804,38 +1654,6 @@ std::map<const t_model*, std::vector<t_logical_block_type_ptr>> identify_primiti
return model_candidates;
}

void print_seed_gains(const char* fname, const std::vector<AtomBlockId>& seed_atoms, const vtr::vector<AtomBlockId, float>& atom_gain, const vtr::vector<AtomBlockId, float>& atom_criticality) {
FILE* fp = vtr::fopen(fname, "w");

const AtomContext& atom_ctx = g_vpr_ctx.atom();

//For prett formatting determine the maximum name length
int max_name_len = strlen("atom_block_name");
int max_type_len = strlen("atom_block_type");
for (auto blk_id : atom_ctx.nlist.blocks()) {
max_name_len = std::max(max_name_len, (int)atom_ctx.nlist.block_name(blk_id).size());

const t_model* model = atom_ctx.nlist.block_model(blk_id);
max_type_len = std::max(max_type_len, (int)strlen(model->name));
}

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_ctx.nlist.block_name(blk_id);
fprintf(fp, "%-*s ", max_name_len, name.c_str());

const t_model* model = atom_ctx.nlist.block_model(blk_id);
fprintf(fp, "%-*s ", max_type_len, model->name);

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");
}

fclose(fp);
}

size_t update_pb_type_count(const t_pb* pb, std::map<t_pb_type*, int>& pb_type_count, size_t depth) {
size_t max_depth = depth;

Expand Down Expand Up @@ -1879,6 +1697,32 @@ void print_pb_type_count_recurr(t_pb_type* pb_type, size_t max_name_chars, size_
}
}

void print_pb_type_count(const ClusteredNetlist& clb_nlist) {
auto& device_ctx = g_vpr_ctx.device();

std::map<t_pb_type*, int> pb_type_count;

size_t max_depth = 0;
for (ClusterBlockId blk : clb_nlist.blocks()) {
size_t pb_max_depth = update_pb_type_count(clb_nlist.block_pb(blk), pb_type_count, 0);

max_depth = std::max(max_depth, pb_max_depth);
}

size_t max_pb_type_name_chars = 0;
for (auto& pb_type : pb_type_count) {
max_pb_type_name_chars = std::max(max_pb_type_name_chars, strlen(pb_type.first->name));
}

VTR_LOG("\nPb types usage...\n");
for (const auto& logical_block_type : device_ctx.logical_block_types) {
if (!logical_block_type.pb_type) continue;

print_pb_type_count_recurr(logical_block_type.pb_type, max_pb_type_name_chars + max_depth, 0, pb_type_count);
}
VTR_LOG("\n");
}

t_logical_block_type_ptr identify_logic_block_type(std::map<const t_model*, std::vector<t_logical_block_type_ptr>>& primitive_candidate_block_types) {
std::string lut_name = ".names";

Expand Down
17 changes: 5 additions & 12 deletions vpr/src/pack/cluster_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,16 +428,6 @@ t_pack_molecule* get_molecule_for_cluster(t_pb* cur_pb,
*/
t_molecule_stats calc_molecule_stats(const t_pack_molecule* molecule, const AtomNetlist& atom_nlist);

std::vector<AtomBlockId> initialize_seed_atoms(const e_cluster_seed seed_type,
const t_molecule_stats& max_molecule_stats,
const Prepacker& prepacker,
const vtr::vector<AtomBlockId, float>& atom_criticality);

t_pack_molecule* get_highest_gain_seed_molecule(int& seed_index,
const std::vector<AtomBlockId>& seed_atoms,
const Prepacker& prepacker,
const ClusterLegalizer& cluster_legalizer);

/*
* @brief Get gain of packing molecule into current cluster.
*
Expand All @@ -448,8 +438,6 @@ t_pack_molecule* get_highest_gain_seed_molecule(int& seed_index,
*/
float get_molecule_gain(t_pack_molecule* molecule, std::map<AtomBlockId, float>& blk_gain, AttractGroupId cluster_attraction_group_id, AttractionInfo& attraction_groups, int num_molecule_failures);

void print_seed_gains(const char* fname, const std::vector<AtomBlockId>& seed_atoms, const vtr::vector<AtomBlockId, float>& atom_gain, const vtr::vector<AtomBlockId, float>& atom_criticality);

/**
* @brief Score unclustered atoms that are two hops away from current cluster
*
Expand Down Expand Up @@ -481,6 +469,11 @@ void update_le_count(const t_pb* pb, const t_logical_block_type_ptr logic_block_

void print_pb_type_count_recurr(t_pb_type* type, size_t max_name_chars, size_t curr_depth, std::map<t_pb_type*, int>& pb_type_count);

/**
* Print the total number of used physical blocks for each pb type in the architecture
*/
void print_pb_type_count(const ClusteredNetlist& clb_nlist);

/*
* @brief This function identifies the logic block type which is defined by the
* block type which has a lut primitive.
Expand Down
Loading

0 comments on commit 7c93264

Please sign in to comment.