Skip to content

Conversation

soheilshahrouz
Copy link
Contributor

This PR includes the following changes:

  1. Creates nodes and edges in RR graph based on scatter-gather patterns specifed in the architecture file.
  2. Updates router lookahead map to handle CHANZ nodes properly.
  3. Computes indexed data for CHANZ nodes.
  4. Removes 3-d (with above and under) switch blocks from code

soheilshahrouz and others added 30 commits September 5, 2025 12:44
@soheilshahrouz soheilshahrouz changed the title [WIP] Scatter-gather patterns for 3D architectures Scatter-gather patterns for 3D architectures Sep 18, 2025
Copy link
Contributor

@AlexandreSinger AlexandreSinger left a comment

Choose a reason for hiding this comment

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

Gave a quick review.

@soheilshahrouz I love the cleanups you do, but man you got to split them across PRs; there's so much to review!

Copy link
Contributor

@AmirhosseinPoolad AmirhosseinPoolad left a comment

Choose a reason for hiding this comment

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

Only reviewed until vpr/src/route/DecompNetlistRouter.tpp

Copy link
Contributor

@AmirhosseinPoolad AmirhosseinPoolad left a comment

Choose a reason for hiding this comment

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

Reviewed from DecompNetlistRouter to build_scatter_gathers.cpp.

Comment on lines +158 to +159
// TODO: handle CHANZ nodes

Copy link
Contributor

Choose a reason for hiding this comment

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

TODO remaining in final code


int from_layer_num = rr_graph.node_layer(from_node);
int to_layer_num = rr_graph.node_layer(to_node);
// TODO: handle CHANZ nodes that span multiple layers
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO again. Not saying that you have to fix these right now, but a reminder that it is there. I sometimes forget about my TODOs so I'm just making sure that it's intended.

const auto& grid = device_ctx.grid;

const size_t num_layers = grid.get_num_layers();
const size_t chan_type_dim_size = (num_layers == 1) ? 2 : 3;
Copy link
Contributor

Choose a reason for hiding this comment

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

Add comment explaining this.

if (is_chanxy(from_type) || is_chanz(from_type)) {
int from_layer_num = rr_graph.node_layer(from_node);
int to_layer_num = rr_graph.node_layer(to_node);
// TODO: handle CHANZ nodes
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO. Again, just reminding that it exists.

Copy link
Contributor

@AmirhosseinPoolad AmirhosseinPoolad left a comment

Choose a reason for hiding this comment

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

More comments until 'switchblock_scatter_gather_common_utils.cpp'

const t_chan_details& chan_details_x,
const t_chan_details& chan_details_y,
std::vector<t_chan_loc>& correct_channels) {
correct_channels.clear();
Copy link
Contributor

Choose a reason for hiding this comment

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

If you're clearing this vector at the start of the function, why not just have it as return value then?

t_physical_tile_loc chan_loc;
e_rr_type chan_type;

index_into_correct_chan(loc, side, chan_details_x, chan_details_y, chan_loc, chan_type);
Copy link
Contributor

Choose a reason for hiding this comment

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

The name for these two functions are way to similar, I thought it was recursive at first glance. I think 'index_to_correct_channels' should have sg or scatter_gather somewhere in the name to differentiate it better.

for (const t_wire_switchpoints& wire_switchpoints : wire_switchpoints_vec) {
auto wire_type = vtr::string_view(wire_switchpoints.segment_name);

if (wire_type_sizes.find(wire_type) == wire_type_sizes.end()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer using contains from c++20

const t_chan_seg_details* chan_details = (chan_type == e_rr_type::CHANX) ? chan_details_x[chan_loc.x][chan_loc.y].data() : chan_details_y[chan_loc.x][chan_loc.y].data();

for (const t_wire_switchpoints& wire_switchpoints : wire_switchpoints_vec) {
auto wire_type = vtr::string_view(wire_switchpoints.segment_name);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we have a vtr::string_view? Maybe it's from when the project was not using C++17? Anyway I don't see why we need to use it now. Also, auto.

int wire_switchpoint = get_switchpoint_of_wire(chan_type, chan_details[iwire], seg_coord, chan_side);

// Check if this wire belongs to one of the specified switchpoints; add it to our 'wires' vector if so
if (wire_switchpoint != valid_switchpoint) continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

The loop seems backwards to me. You're going through all valid switchpoints then all wires, meaning that you do all the processing for the wire only to throw it away because in the outer loop we were looking for switchpoint number 1 instead of 2, even though switchpoint 2 might also be valid in the next iteration of the outer loop.

index_to_correct_channels(sg_pattern.scatter_pattern, scatter_loc, chan_details_x, chan_details_y, scatter_channels);

if (gather_channels.empty() || scatter_channels.empty()) {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably at least warn the user here that there's an ill formed pattern.

Comment on lines +209 to +219
auto gather_wire_candidates = find_candidate_wires(gather_channels,
sg_pattern.gather_pattern.from_switchpoint_set,
chan_details_x, chan_details_y,
wire_type_sizes_x, wire_type_sizes_y,
/*is_dest=*/false);

auto scatter_wire_candidates = find_candidate_wires(scatter_channels,
sg_pattern.scatter_pattern.to_switchpoint_set,
chan_details_x, chan_details_y,
wire_type_sizes_x, wire_type_sizes_y,
/*is_dest=*/true);
Copy link
Contributor

Choose a reason for hiding this comment

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

auto

bottleneck_fanout = std::min<int>(bottleneck_fanout, scatter_wire_candidates.size());

if (bottleneck_fanin == 0 || bottleneck_fanout == 0) {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto here, maybe we should warn the user. There's a potential problem of printing way too much stuff that should be considered.

t_wire_switchpoint wire_switchpoint; ///< Wire index and its valid switchpoint
};

/// Represents a scatter/gather bottleneck connection between two locations.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we referred to this as the "scatter-gather node" in the docs. I don't have an issue with the name bottleneck but I think you should say in the comments that the bottleneck connection is the same thing as scatter-gather node in the docs.

const float R_minW_pmos,
const int wire_to_arch_ipin_switch,
int* wire_to_rr_ipin_switch) {
RRSwitchId* wire_to_rr_ipin_switch) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you pass this by reference instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang-cpp C/C++ code libarchfpga Library for handling FPGA Architecture descriptions VPR VPR FPGA Placement & Routing Tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants