Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
998ba66
Add interposer crossing wire cutting
AmirhosseinPoolad Nov 6, 2025
2546789
Fix edge cutting
AmirhosseinPoolad Nov 10, 2025
21d5080
Fix integration with scatter-gather patterns
AmirhosseinPoolad Nov 11, 2025
72e8933
Add doxygen to interposer cut functions
AmirhosseinPoolad Nov 12, 2025
bc9a40a
Fix some code duplication issues
AmirhosseinPoolad Nov 12, 2025
b6f592a
Remove experimental interposer status from documentation
AmirhosseinPoolad Nov 12, 2025
349d672
Fix issue with interposers and 3D connection blocks
AmirhosseinPoolad Nov 12, 2025
e659e23
Address PR comments
AmirhosseinPoolad Nov 13, 2025
e9876b3
Change RR Graph warning enum to be clearer
AmirhosseinPoolad Nov 13, 2025
2d6de4f
Address PR comments on RR Graph changes
AmirhosseinPoolad Nov 17, 2025
16f26ce
Add doxygen to interposer_cut.h
AmirhosseinPoolad Nov 17, 2025
ea396cd
Fix formatting
AmirhosseinPoolad Nov 17, 2025
4d95419
Add .clangd to gitignore
AmirhosseinPoolad Nov 17, 2025
e2cee0c
Make remove_edges use ranges
AmirhosseinPoolad Nov 17, 2025
4573aa9
Pass RRNodeIds by value
AmirhosseinPoolad Nov 17, 2025
6b39edc
Add newline to 2D scatter-gather comment
AmirhosseinPoolad Nov 17, 2025
0fc6d07
Rename interposer_cut to rr_graph_interposer
AmirhosseinPoolad Nov 17, 2025
dda2e43
Add static function declarations to rr_graph_interposer.cpp
AmirhosseinPoolad Nov 17, 2025
61ebf99
Add std::pair include
AmirhosseinPoolad Nov 17, 2025
561b5fb
Fix formatting issues
AmirhosseinPoolad Nov 17, 2025
b57b08f
Fix bug with checking if device has interposer cuts
AmirhosseinPoolad Nov 17, 2025
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: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,4 @@ cmake-build-release
# Clangd
#
compile_commands.json
.clangd
3 changes: 1 addition & 2 deletions doc/src/arch/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ Grid Layout Example

.. note:: Exactly one of the ``x`` or ``y`` attributes must be specified.

.. note:: Interposers are experimental and are currently not supported by VPR and using the related tags will not actually result in any changes to the flow.
Defines an interposer cut for modelling 2.5D interposer-based architectures. An interposer cut will cut all connections at location 'loc' along the axis 'dim' Leaving the two sides completely unconnected.
To reconnect the two sides, this tag can have multiple <interdie_wire> tags as children to specify the connection between the two sides.

Expand Down Expand Up @@ -2751,7 +2750,7 @@ The number of any additional wires or muxes created by scatter-gather specificat
Overview of how scatter-gather patterns work. First, connections from a switchblock location are selected according to the specification.
These selected connection are then muxed and passed through the scatter-gather node, which is typically a wire segment. The scatter-gather node then fans out or scatters in another switchblock location.

.. note:: Scatter-Gather patterns are only supported for 3D architectures where the scatter-gather links are unidirectional. They are not currently supported in 2D architectures or with bidirectional sg_links.
.. note:: Scatter-Gather patterns are only supported for uni-directional 3D and uni-directional 2D architectures. Bidirectional sg_links are not currently supported.

When instantiated, a scatter-gather pattern gathers connections from a switchblock and passes the connection through a multiplexer and the scatter-gather node which is typically a wire segment, then scatters or fans out somewhere else in the device. These patterns can be used to define 3D switchblocks. An example is shown below:

Expand Down
11 changes: 11 additions & 0 deletions libs/librrgraph/src/base/rr_graph_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,17 @@ class RRGraphBuilder {
inline void alloc_and_load_edges(const t_rr_edge_info_set* rr_edges_to_create) {
node_storage_.alloc_and_load_edges(rr_edges_to_create);
}

/** @brief Removes a given list of RREdgeIds for the RR Graph.
* This method does not preserve the order of edges. If you're
* calling it after partition_edges has been called, you need
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"you need to call it again" --> you will need to call partition_edges again

* to call it again.
*
* @param rr_edges_to_remove list of RREdgeIds to be removed
*/
inline void remove_edges(std::vector<RREdgeId>& rr_edges_to_remove) {
node_storage_.remove_edges(rr_edges_to_remove);
}

/** @brief Overrides the associated switch for a given edge by
* updating the edge to use the passed in switch. */
Expand Down
67 changes: 56 additions & 11 deletions libs/librrgraph/src/base/rr_graph_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include "rr_graph_storage.h"
#include "physical_types.h"
#include "rr_graph_fwd.h"
#include "vtr_assert.h"
#include "vtr_error.h"
#include "librrgraph_types.h"
#include "vtr_util.h"

#include <algorithm>
#include <cstddef>
Expand Down Expand Up @@ -57,6 +59,46 @@ void t_rr_graph_storage::alloc_and_load_edges(const t_rr_edge_info_set* rr_edges
}
}

void t_rr_graph_storage::remove_edges(std::vector<RREdgeId>& rr_edges_to_remove) {
VTR_ASSERT(!edges_read_);

size_t starting_edge_count = edge_dest_node_.size();

// Sort and make sure all edge indices are unique
vtr::uniquify(rr_edges_to_remove);
VTR_ASSERT_SAFE(std::is_sorted(rr_edges_to_remove.begin(), rr_edges_to_remove.end()));

// Index of the last edge
size_t edge_list_end = edge_dest_node_.size() - 1;

// Iterate backwards through the list of indices we want to remove.
for (auto it = rr_edges_to_remove.rbegin(); it != rr_edges_to_remove.rend(); ++it) {
RREdgeId erase_idx = *it;

// Copy what's at the end of the list to the index we wanted to remove
edge_dest_node_[erase_idx] = edge_dest_node_[RREdgeId(edge_list_end)];
edge_src_node_[erase_idx] = edge_src_node_[RREdgeId(edge_list_end)];
edge_switch_[erase_idx] = edge_switch_[RREdgeId(edge_list_end)];
edge_remapped_[erase_idx] = edge_remapped_[RREdgeId(edge_list_end)];

// At this point we have no copies of what was at erase_idx and two copies of
// what was at the end of the list. If we make the list one element shorter,
// we end up with a list that has removed the element at erase_idx.
edge_list_end--;

}

// We have a new index to the end of the list, call erase on the elements past that index
// to update the std::vector and shrink the actual data structures.
edge_dest_node_.erase(edge_dest_node_.begin() + edge_list_end + 1, edge_dest_node_.end());
edge_src_node_.erase(edge_src_node_.begin() + edge_list_end + 1, edge_src_node_.end());
edge_switch_.erase(edge_switch_.begin() + edge_list_end + 1, edge_switch_.end());
edge_remapped_.erase(edge_remapped_.begin() + edge_list_end + 1, edge_remapped_.end());

VTR_ASSERT(edge_dest_node_.size() == (starting_edge_count - rr_edges_to_remove.size()));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should set partitioned = false here



void t_rr_graph_storage::assign_first_edges() {
VTR_ASSERT(node_first_edge_.empty());

Expand All @@ -68,39 +110,42 @@ void t_rr_graph_storage::assign_first_edges() {
edge_src_node_.end()));

size_t node_id = 0;
size_t first_id = 0;
size_t second_id = 0;
size_t first_edge_id = 0;
size_t second_edge_id = 0;

size_t num_edges = edge_src_node_.size();
VTR_ASSERT(edge_dest_node_.size() == num_edges);
VTR_ASSERT(edge_switch_.size() == num_edges);
VTR_ASSERT(edge_remapped_.size() == num_edges);

while (true) {
VTR_ASSERT(first_id < num_edges);
VTR_ASSERT(second_id < num_edges);
size_t current_node_id = size_t(edge_src_node_[RREdgeId(second_id)]);
VTR_ASSERT(first_edge_id < num_edges);
VTR_ASSERT(second_edge_id < num_edges);

size_t current_node_id = size_t(edge_src_node_[RREdgeId(second_edge_id)]);
if (node_id < current_node_id) {
// All edges belonging to node_id are assigned.
while (node_id < current_node_id) {
// Store any edges belongs to node_id.
VTR_ASSERT(node_id < node_first_edge_.size());
node_first_edge_[RRNodeId(node_id)] = RREdgeId(first_id);
first_id = second_id;
node_first_edge_[RRNodeId(node_id)] = RREdgeId(first_edge_id);
first_edge_id = second_edge_id;
node_id += 1;
}

VTR_ASSERT(node_id == current_node_id);
node_first_edge_[RRNodeId(node_id)] = RREdgeId(second_id);
node_first_edge_[RRNodeId(node_id)] = RREdgeId(second_edge_id);
} else {
second_id += 1;
if (second_id == num_edges) {
second_edge_id += 1;
if (second_edge_id == num_edges) {
break;
}
}
}

// All remaining nodes have no edges, set as such.
for (size_t inode = node_id + 1; inode < node_first_edge_.size(); ++inode) {
node_first_edge_[RRNodeId(inode)] = RREdgeId(second_id);
node_first_edge_[RRNodeId(inode)] = RREdgeId(second_edge_id);
}

VTR_ASSERT_SAFE(verify_first_edges());
Expand Down
17 changes: 17 additions & 0 deletions libs/librrgraph/src/base/rr_graph_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,14 @@ class t_rr_graph_storage {
return vtr::StrongIdRange<RREdgeId>(first_edge(id), last_edge(id));
}

/** @brief Returns a range of all edges in the RR Graph.
* This method does not depend on the edges begin correctly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

begin -> being

* sorted and can be used before partition_edges is called.
*/
inline vtr::StrongIdRange<RREdgeId> all_edges() const {
return vtr::StrongIdRange<RREdgeId>(RREdgeId(0), RREdgeId(edge_src_node_.size()));
}

/** @brief Retrieve the RREdgeId for iedge'th edge in RRNodeId.
*
* This method should generally not be used, and instead first_edge and
Expand Down Expand Up @@ -776,6 +784,15 @@ class t_rr_graph_storage {
/** @brief Adds a batch of edges.*/
void alloc_and_load_edges(const t_rr_edge_info_set* rr_edges_to_create);

/** @brief Removes a given list of RREdgeIds for the RR Graph.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'for the RR' -> 'from the RR'
'has been called, you need to call it again' -> 'has been called, you need to call partition_edges again'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should say this operation is O(num_edges) in the RR graph, so it should not be called often and edges should be removed in bulk if at all possible.

* This method does not preserve the order of edges. If you're
* calling it after partition_edges has been called, you need
* to call it again.
*
* @param rr_edges_to_remove list of RREdgeIds to be removed
*/
void remove_edges(std::vector<RREdgeId>& rr_edges_to_remove);

/* Edge finalization methods */

/** @brief Counts the number of rr switches needed based on fan in to support mux
Expand Down
2 changes: 0 additions & 2 deletions libs/librrgraph/src/base/rr_graph_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,3 @@ bool RRGraphView::validate_in_edges() const {
}
return true;
}


15 changes: 14 additions & 1 deletion libs/librrgraph/src/base/rr_graph_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@
#include "metadata_storage.h"
#include "rr_node.h"
#include "physical_types.h"
#include "rr_node_types.h"
#include "rr_spatial_lookup.h"
#include "vtr_geometry.h"
#include "rr_graph_utils.h"
#include "vtr_range.h"

class RRGraphView {
/* -- Constructors -- */
Expand Down Expand Up @@ -584,14 +586,25 @@ class RRGraphView {
* @example
* RRGraphView rr_graph; // A dummy rr_graph for a short example
* RRNodeId node; // A dummy node for a short example
* for (RREdgeId edge : rr_graph.edges(node)) {
* for (t_edge_size edge : rr_graph.edges(node)) {
* // Do something with the edge
* }
*
* @note Iterating on the range returned by this function will not give you an RREdgeId, but instead gives you the index among a node's outgoing edges
*/
inline edge_idx_range edges(const RRNodeId& id) const {
return vtr::make_range(edge_idx_iterator(0), edge_idx_iterator(num_edges(id)));
}

/** @brief Returns a range of all edges in the RR Graph.
* This method does not depend on the edges begin correctly
* sorted and can be used before partition_edges is called.
*/
inline vtr::StrongIdRange<RREdgeId> all_edges() const {
return node_storage_.all_edges();
}


/**
* @brief Return ID range for outgoing edges.
*/
Expand Down
Loading