Skip to content

[Pack] Pack Pattern Root IPIN #3007

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
merged 16 commits into from
May 6, 2025
Merged
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
79 changes: 74 additions & 5 deletions vpr/src/pack/prepack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,17 @@ static void find_all_equivalent_chains(t_pack_patterns* chain_pattern, const t_p
static void update_chain_root_pins(t_pack_patterns* chain_pattern,
const std::vector<t_pb_graph_pin*>& chain_input_pins);

static void get_all_connected_primitive_pins(const t_pb_graph_pin* cluster_input_pin, std::vector<t_pb_graph_pin*>& connected_primitive_pins);
/**
* @brief Get all primitive pins connected to the given cluster input pin
*
* @param cluster_input_pin Cluster input pin to get connected primitive pins from
* @param pattern_blocks Set of pb_types in the pack pattern. Pins on the blocks in this set will
* be added to the connected_primitive_pins vector
* @param connected_primitive_pins Vector to store connected primitive pins
*/
static void get_all_connected_primitive_pins(const t_pb_graph_pin* cluster_input_pin,
const std::unordered_set<t_pb_type*>& pattern_blocks,
std::vector<t_pb_graph_pin*>& connected_primitive_pins);

static void init_molecule_chain_info(const AtomBlockId blk_id,
t_pack_molecule& molecule,
Expand All @@ -117,6 +127,14 @@ static AtomBlockId get_driving_block(const AtomBlockId block_id,
const t_pack_pattern_connections& connections,
const AtomNetlist& atom_nlist);

/**
* @brief Get an unordered set of all pb_types in the given pack pattern
*
* @param pack_pattern Pack pattern to get pb_types from
* @return std::unordered_set<t_pb_type*> Set of pb_types in the pack pattern
*/
static std::unordered_set<t_pb_type*> get_pattern_blocks(const t_pack_patterns& pack_pattern);

static void print_chain_starting_points(t_pack_patterns* chain_pattern);

/*****************************************/
Expand Down Expand Up @@ -1172,6 +1190,51 @@ static AtomBlockId get_driving_block(const AtomBlockId block_id,
return AtomBlockId::INVALID();
}

static std::unordered_set<t_pb_type*> get_pattern_blocks(const t_pack_patterns& pack_pattern) {
std::unordered_set<t_pb_type*> pattern_blocks;

t_pack_pattern_connections* connections = pack_pattern.root_block->connections;
if (connections == nullptr) {
return pattern_blocks;
}
std::unordered_set<t_pb_graph_pin*> visited_from_pins;
std::unordered_set<t_pb_graph_pin*> visited_to_pins;
std::queue<t_pack_pattern_block*> pack_pattern_blocks;
pack_pattern_blocks.push(connections->from_block);

/** Start from the root block of the pack pattern and add the connected block to the queue */
while (!pack_pattern_blocks.empty()) {
t_pack_pattern_block* current_pattern_block = pack_pattern_blocks.front();
pack_pattern_blocks.pop();
t_pack_pattern_connections* current_connenction = current_pattern_block->connections;
/*
* Iterate through all the connections of the current pattern block to
* add the connected block to the queue
*/
while (current_connenction != nullptr) {
if (visited_from_pins.find(current_connenction->from_pin) != visited_from_pins.end()) {
if (visited_to_pins.find(current_connenction->to_pin) != visited_to_pins.end()) {
/* We've already seen this connection */
current_connenction = current_connenction->next;
continue;
}
}
/*
* To avoid visiting the same connection twice, since it is both stored in from_pin and to_pin,
* add the from_pin and to_pin to the visited sets
*/
visited_from_pins.insert(current_connenction->from_pin);
visited_to_pins.insert(current_connenction->to_pin);

/* The from_pin block belongs to the pattern block */
pattern_blocks.insert(current_connenction->from_pin->port->parent_pb_type);
pack_pattern_blocks.push(current_connenction->to_block);
current_connenction = current_connenction->next;
}
}
return pattern_blocks;
}

static void print_pack_molecules(const char* fname,
const std::vector<t_pack_patterns>& list_of_pack_patterns,
const int num_pack_patterns,
Expand Down Expand Up @@ -1564,9 +1627,10 @@ static void update_chain_root_pins(t_pack_patterns* chain_pattern,
const std::vector<t_pb_graph_pin*>& chain_input_pins) {
std::vector<std::vector<t_pb_graph_pin*>> primitive_input_pins;

std::unordered_set<t_pb_type*> pattern_blocks = get_pattern_blocks(*chain_pattern);
for (const auto pin_ptr : chain_input_pins) {
std::vector<t_pb_graph_pin*> connected_primitive_pins;
get_all_connected_primitive_pins(pin_ptr, connected_primitive_pins);
get_all_connected_primitive_pins(pin_ptr, pattern_blocks, connected_primitive_pins);

/**
* It is required that the chain pins are connected inside a complex
Expand All @@ -1590,7 +1654,9 @@ static void update_chain_root_pins(t_pack_patterns* chain_pattern,
* the Cin pin of all the adder primitives connected to this pin. Which is for typical architectures
* will be only one pin connected to the very first adder in the cluster.
*/
static void get_all_connected_primitive_pins(const t_pb_graph_pin* cluster_input_pin, std::vector<t_pb_graph_pin*>& connected_primitive_pins) {
static void get_all_connected_primitive_pins(const t_pb_graph_pin* cluster_input_pin,
const std::unordered_set<t_pb_type*>& pattern_blocks,
std::vector<t_pb_graph_pin*>& connected_primitive_pins) {
/* Skip pins for modes that are disabled for packing*/
if ((nullptr != cluster_input_pin->parent_node->pb_type->parent_mode)
&& (true == cluster_input_pin->parent_node->pb_type->parent_mode->disable_packing)) {
Expand All @@ -1601,9 +1667,12 @@ static void get_all_connected_primitive_pins(const t_pb_graph_pin* cluster_input
const auto& output_edge = cluster_input_pin->output_edges[iedge];
for (int ipin = 0; ipin < output_edge->num_output_pins; ipin++) {
if (output_edge->output_pins[ipin]->is_primitive_pin()) {
connected_primitive_pins.push_back(output_edge->output_pins[ipin]);
/** Add the output pin to the vector only if it belongs to a pb_type registered in the pattern_blocks set */
if (pattern_blocks.find(output_edge->output_pins[ipin]->parent_node->pb_type) != pattern_blocks.end()) {
connected_primitive_pins.push_back(output_edge->output_pins[ipin]);
}
} else {
get_all_connected_primitive_pins(output_edge->output_pins[ipin], connected_primitive_pins);
get_all_connected_primitive_pins(output_edge->output_pins[ipin], pattern_blocks, connected_primitive_pins);
}
}
}
Expand Down