Skip to content

[ClusterLegalizer] Cleaned Up Cluster Placement Stats #2728

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
1 change: 0 additions & 1 deletion libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,6 @@ class t_pb_graph_node {
int total_pb_pins; /* only valid for top-level */

void* temp_scratch_pad; /* temporary data, useful for keeping track of things when traversing data structure */
t_cluster_placement_primitive* cluster_placement_primitive; /* pointer to indexing structure useful during packing stage */

int* input_pin_class_size; /* Stores the number of pins that belong to a particular input pin class */
int num_input_pin_class; /* number of input pin classes that this pb_graph_node has */
Expand Down
97 changes: 0 additions & 97 deletions vpr/src/base/vpr_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,100 +452,3 @@ void t_pb::set_atom_pin_bit_index(const t_pb_graph_pin* gpin, BitIndex atom_pin_
pin_rotations_[gpin] = atom_pin_bit_idx;
}

/**
* Free linked lists found in cluster_placement_stats_list
*/
void free_cluster_placement_stats(t_cluster_placement_stats* cluster_placement_stats_list) {
auto& device_ctx = g_vpr_ctx.device();

for (const auto& type : device_ctx.logical_block_types) {
int index = type.index;
cluster_placement_stats_list[index].free_primitives();
}
delete[] cluster_placement_stats_list;
}

void t_cluster_placement_stats::move_inflight_to_tried() {
tried.insert(*in_flight.begin());
in_flight.clear();
}

void t_cluster_placement_stats::invalidate_primitive_and_increment_iterator(int pb_type_index, std::unordered_multimap<int, t_cluster_placement_primitive*>::iterator& it) {
invalid.insert(*it);
valid_primitives[pb_type_index].erase(it++);
}

void t_cluster_placement_stats::move_primitive_to_inflight(int pb_type_index, std::unordered_multimap<int, t_cluster_placement_primitive*>::iterator& it) {
in_flight.insert(*it);
valid_primitives[pb_type_index].erase(it);
}

/**
* @brief Put primitive back on the correct location of valid primitives vector based on the primitive pb type
*
* @note that valid status is not changed because if the primitive is not valid, it will get properly collected later
*/
void t_cluster_placement_stats::insert_primitive_in_valid_primitives(std::pair<int, t_cluster_placement_primitive*> cluster_placement_primitive) {
int i;
bool success = false;
int null_index = OPEN;
t_cluster_placement_primitive* input_cluster_placement_primitive = cluster_placement_primitive.second;

for (i = 0; i < num_pb_types && !success; i++) {
if (valid_primitives[i].empty()) {
null_index = i;
continue;
}
t_cluster_placement_primitive* cur_cluster_placement_primitive = valid_primitives[i].begin()->second;
if (input_cluster_placement_primitive->pb_graph_node->pb_type
== cur_cluster_placement_primitive->pb_graph_node->pb_type) {
success = true;
valid_primitives[i].insert(cluster_placement_primitive);
}
}
if (!success) {
VTR_ASSERT(null_index != OPEN);
valid_primitives[null_index].insert(cluster_placement_primitive);
}
}

void t_cluster_placement_stats::flush_queue(std::unordered_multimap<int, t_cluster_placement_primitive*>& queue) {
for (auto& it : queue) {
insert_primitive_in_valid_primitives(it);
}
queue.clear();
}

void t_cluster_placement_stats::flush_intermediate_queues() {
flush_queue(in_flight);
flush_queue(tried);
}

void t_cluster_placement_stats::flush_invalid_queue() {
flush_queue(invalid);
}

bool t_cluster_placement_stats::in_flight_empty() {
return in_flight.empty();
}

t_pb_type* t_cluster_placement_stats::in_flight_type() {
return in_flight.begin()->second->pb_graph_node->pb_type;
}

void t_cluster_placement_stats::free_primitives() {
for (auto& primitive : tried)
delete primitive.second;

for (auto& primitive : in_flight)
delete primitive.second;

for (auto& primitive : invalid)
delete primitive.second;

for (int j = 0; j < num_pb_types; j++) {
for (auto& primitive : valid_primitives[j]) {
delete primitive.second;
}
}
}
89 changes: 0 additions & 89 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,90 +430,6 @@ struct t_chain_info {
t_pack_molecule* first_packed_molecule = nullptr;
};

/**
* @brief Stats keeper for placement information during packing
*
* Contains data structure of placement locations based on status of primitive
*/
class t_cluster_placement_stats {
public:
int num_pb_types; ///<num primitive pb_types inside complex block
bool has_long_chain; ///<specifies if this cluster has a molecule placed in it that belongs to a long chain (a chain that spans more than one cluster)
const t_pack_molecule* curr_molecule; ///<current molecule being considered for packing

// Vector of size num_pb_types [0.. num_pb_types-1]. Each element is an unordered_map of the cluster_placement_primitives that are of this pb_type
// Each cluster_placement_primitive is associated with and index (key of the map) for easier lookup, insertion and deletion.
std::vector<std::unordered_map<int, t_cluster_placement_primitive*>> valid_primitives;

public:
// Moves primitives that are inflight to the tried map
void move_inflight_to_tried();

/**
* @brief Move the primitive at (it) to inflight and increment the current iterator.
*
* Because the element at (it) is deleted from valid_primitives, (it) is incremented to keep it valid and pointing at the next element.
*
* @param pb_type_index: is the index of this pb_type in valid_primitives vector
* @param it: is the iterator pointing at the element that needs to be moved to inflight
*/
void move_primitive_to_inflight(int pb_type_index, std::unordered_multimap<int, t_cluster_placement_primitive*>::iterator& it);

/**
* @brief Move the primitive at (it) to invalid and increment the current iterator
*
* Because the element at (it) is deleted from valid_primitives, (it) is incremented to keep it valid and pointing at the next element.
*
* @param pb_type_index: is the index of this pb_type in valid_primitives vector
* @param it: is the iterator pointing at the element that needs to be moved to invalid
*/
void invalidate_primitive_and_increment_iterator(int pb_type_index, std::unordered_multimap<int, t_cluster_placement_primitive*>::iterator& it);

/**
* @brief Add a primitive in its correct location in valid_primitives vector based on its pb_type
*
* @param cluster_placement_primitive: a pair of the cluster_placement_primtive and its corresponding index(for reference in pb_graph_node)
*/
void insert_primitive_in_valid_primitives(std::pair<int, t_cluster_placement_primitive*> cluster_placement_primitive);

/**
* @brief Move all the primitives from (in_flight and tried) maps to valid primitives and clear (in_flight and tried)
*/
void flush_intermediate_queues();

/**
* @brief Move all the primitives from invalid to valid_primitives and clear the invalid map
*/
void flush_invalid_queue();

/**
* @brief Return true if the in_flight map is empty (no primitive is in_flight currently)
*/
bool in_flight_empty();

/**
* @brief Return the type of the first element of the primitives currently being considered
*/
t_pb_type* in_flight_type();

/**
* @brief free the dynamically allocated memory for primitives
*/
void free_primitives();

private:
std::unordered_multimap<int, t_cluster_placement_primitive*> in_flight; ///<ptrs to primitives currently being considered to pack into
std::unordered_multimap<int, t_cluster_placement_primitive*> tried; ///<ptrs to primitives that are already tried but current logic block unable to pack to
std::unordered_multimap<int, t_cluster_placement_primitive*> invalid; ///<ptrs to primitives that are invalid (already occupied by another primitive in this cluster)

/**
* @brief iterate over elements of a queue and move its elements to valid_primitives
*
* @param queue the unordered_multimap to work on (e.g. in_flight, tried, or invalid)
*/
void flush_queue(std::unordered_multimap<int, t_cluster_placement_primitive*>& queue);
};

/******************************************************************
* Timing data types
*******************************************************************/
Expand Down Expand Up @@ -1841,11 +1757,6 @@ typedef vtr::vector<ClusterBlockId, std::vector<std::vector<RRNodeId>>> t_clb_op

typedef std::vector<std::map<int, int>> t_arch_switch_fanin;

/**
* @brief Free the linked lists to placement locations based on status of primitive inside placement stats data structure.
*/
void free_cluster_placement_stats(t_cluster_placement_stats* cluster_placement_stats);

struct pair_hash {
std::size_t operator()(const std::pair<ClusterBlockId, ClusterBlockId>& p) const noexcept {
return std::hash<ClusterBlockId>()(p.first) ^ (std::hash<ClusterBlockId>()(p.second) << 1);
Expand Down
4 changes: 0 additions & 4 deletions vpr/src/pack/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa

enum e_block_pack_status block_pack_status;

t_cluster_placement_stats* cur_cluster_placement_stats_ptr = nullptr;
t_pack_molecule *istart, *next_molecule, *prev_molecule;

auto& atom_ctx = g_vpr_ctx.atom();
Expand Down Expand Up @@ -275,7 +274,6 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa
/*it doesn't make sense to do a timing analysis here since there*
*is only one atom block clustered it would not change anything */
}
cur_cluster_placement_stats_ptr = cluster_legalizer.get_cluster_placement_stats(legalization_cluster_id);
cluster_stats.num_unrelated_clustering_attempts = 0;
next_molecule = get_molecule_for_cluster(cluster_legalizer.get_cluster_pb(legalization_cluster_id),
attraction_groups,
Expand All @@ -284,7 +282,6 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa
packer_opts.transitive_fanout_threshold,
packer_opts.feasible_block_array_size,
&cluster_stats.num_unrelated_clustering_attempts,
cur_cluster_placement_stats_ptr,
prepacker,
cluster_legalizer,
clb_inter_blk_nets,
Expand Down Expand Up @@ -317,7 +314,6 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa
try_fill_cluster(cluster_legalizer,
prepacker,
packer_opts,
cur_cluster_placement_stats_ptr,
prev_molecule,
next_molecule,
num_repeated_molecules,
Expand Down
Loading