Skip to content

Deploy RRGraphBuilder in RRGraph Clock Builder to replace the use of rr_node_indices #1801

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 7 commits into from
Jul 18, 2021
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
52 changes: 36 additions & 16 deletions vpr/src/device/rr_spatial_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,18 @@ RRNodeId RRSpatialLookup::find_node(int x,
return RRNodeId(rr_node_indices_[type][node_x][node_y][node_side][ptc]);
}

std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
int y,
t_rr_type type) const {
std::vector<RRNodeId> RRSpatialLookup::find_nodes(int x,
int y,
t_rr_type type,
e_side side) const {
/* TODO: The implementation of this API should be worked
* when rr_node_indices adapts RRNodeId natively!
*/
std::vector<RRNodeId> channel_nodes;
std::vector<RRNodeId> nodes;

/* Pre-check: the x, y, type are valid! Otherwise, return an empty vector */
if ((x < 0 || y < 0) && (type == CHANX || type == CHANY)) {
return channel_nodes;
if (x < 0 || y < 0) {
return nodes;
}

/* Currently need to swap x and y for CHANX because of chan, seg convention
Expand All @@ -106,30 +107,44 @@ std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
* - Return an empty list if any out-of-range is detected
*/
if (size_t(type) >= rr_node_indices_.size()) {
return channel_nodes;
return nodes;
}

if (node_x >= rr_node_indices_[type].dim_size(0)) {
return channel_nodes;
return nodes;
}

if (node_y >= rr_node_indices_[type].dim_size(1)) {
return channel_nodes;
return nodes;
}

/* By default, we always added the channel nodes to the TOP side (to save memory) */
e_side node_side = TOP;
if (node_side >= rr_node_indices_[type].dim_size(2)) {
return channel_nodes;
if (side >= rr_node_indices_[type].dim_size(2)) {
return nodes;
}

for (const auto& node : rr_node_indices_[type][node_x][node_y][node_side]) {
for (const auto& node : rr_node_indices_[type][node_x][node_y][side]) {
if (RRNodeId(node)) {
channel_nodes.push_back(RRNodeId(node));
nodes.push_back(RRNodeId(node));
}
}

return channel_nodes;
return nodes;
}

std::vector<RRNodeId> RRSpatialLookup::find_channel_nodes(int x,
int y,
t_rr_type type) const {
/* Pre-check: node type should be routing tracks! */
if (type != CHANX && type != CHANY) {
return std::vector<RRNodeId>();
}

return find_nodes(x, y, type);
}

std::vector<RRNodeId> RRSpatialLookup::find_sink_nodes(int x,
int y) const {
return find_nodes(x, y, SINK);
}

std::vector<RRNodeId> RRSpatialLookup::find_nodes_at_all_sides(int x,
Expand Down Expand Up @@ -167,6 +182,11 @@ void RRSpatialLookup::add_node(RRNodeId node,
VTR_ASSERT(node); /* Must have a valid node id to be added */
VTR_ASSERT_SAFE(3 == rr_node_indices_[type].ndims());

/* For non-IPIN/OPIN nodes, the side should always be the TOP side which follows the convention in find_node() API! */
if (type != IPIN && type != OPIN) {
VTR_ASSERT(side == SIDES[0]);
}

resize_nodes(x, y, type, side);

if (size_t(ptc) >= rr_node_indices_[type][x][y][side].size()) {
Expand Down
28 changes: 26 additions & 2 deletions vpr/src/device/rr_spatial_lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ class RRSpatialLookup {
int y,
t_rr_type type) const;

/**
* Returns the indices of the specified routing resource nodes,
* representing virtual sinks.
* - (x, y) are the coordinate of the sink nodes within the FPGA
*
* Note:
* - Return an empty list if there are no sinks at the given (x, y) location
* - The node list returned only contains valid ids
*/
std::vector<RRNodeId> find_sink_nodes(int x,
int y) const;

/**
* Like find_node() but returns all matching nodes on all the sides.
* This is particularly useful for getting all instances
Expand Down Expand Up @@ -118,7 +130,7 @@ class RRSpatialLookup {
int y,
t_rr_type type,
int ptc,
e_side side);
e_side side = SIDES[0]);

/**
* Mirror the last dimension of a look-up, i.e., a list of nodes, from a source coordinate to
Expand Down Expand Up @@ -168,6 +180,18 @@ class RRSpatialLookup {
t_rr_type type,
e_side side);

/* -- Internal data queries -- */
private:
/* An internal API to find all the nodes in a specific location with a given type
* For OPIN/IPIN nodes that may exist on multiple sides, a specific side must be provided
* This API is NOT public because its too powerful for developers with very limited sanity checks
* But it is used to build the public APIs find_channel_nodes() etc., where sufficient sanity checks are applied
*/
std::vector<RRNodeId> find_nodes(int x,
int y,
t_rr_type type,
e_side side = SIDES[0]) const;

/* -- Internal data storage -- */
private:
/* TODO: When the refactoring effort finishes,
Expand All @@ -179,7 +203,7 @@ class RRSpatialLookup {
* or inside the data structures to be changed later.
* That explains why the reference is used here temporarily
*/
/* Fast look-up */
/* Fast look-up: TODO: Should rework the data type. Currently it is based on a 3-dimensional arrqay mater where some dimensions must always be accessed with a specific index. Such limitation should be overcome */
t_rr_node_indices& rr_node_indices_;
};

Expand Down
75 changes: 36 additions & 39 deletions vpr/src/route/clock_connection_builders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,17 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
std::srand(seed);

auto& device_ctx = g_vpr_ctx.device();
auto& rr_node_indices = device_ctx.rr_node_indices;
const auto& node_lookup = device_ctx.rr_graph.node_lookup();

int virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
RRNodeId virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
{
auto& mut_device_ctx = g_vpr_ctx.mutable_device();
mut_device_ctx.virtual_clock_network_root_idx = virtual_clock_network_root_idx;
mut_device_ctx.virtual_clock_network_root_idx = size_t(virtual_clock_network_root_idx);
}

// rr_node indices for x and y channel routing wires and clock wires to connect to
auto x_wire_indices = get_rr_node_chan_wires_at_location(
rr_node_indices, CHANX, switch_location.x, switch_location.y);
auto y_wire_indices = get_rr_node_chan_wires_at_location(
rr_node_indices, CHANY, switch_location.x, switch_location.y);
auto x_wire_indices = node_lookup.find_channel_nodes(switch_location.x, switch_location.y, CHANX);
auto y_wire_indices = node_lookup.find_channel_nodes(switch_location.x, switch_location.y, CHANY);
auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location(
clock_to_connect_to, switch_point_name, switch_location.x, switch_location.y);

Expand All @@ -76,52 +74,53 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
// Connect to x-channel wires
unsigned num_wires_x = x_wire_indices.size() * fc;
for (size_t i = 0; i < num_wires_x; i++) {
clock_graph.add_edge(rr_edges_to_create, x_wire_indices[i], clock_index, arch_switch_idx);
clock_graph.add_edge(rr_edges_to_create, size_t(x_wire_indices[i]), clock_index, arch_switch_idx);
}

// Connect to y-channel wires
unsigned num_wires_y = y_wire_indices.size() * fc;
for (size_t i = 0; i < num_wires_y; i++) {
clock_graph.add_edge(rr_edges_to_create, y_wire_indices[i], clock_index, arch_switch_idx);
clock_graph.add_edge(rr_edges_to_create, size_t(y_wire_indices[i]), clock_index, arch_switch_idx);
}

// Connect to virtual clock sink node
// used by the two stage router
clock_graph.add_edge(rr_edges_to_create, clock_index, virtual_clock_network_root_idx, arch_switch_idx);
clock_graph.add_edge(rr_edges_to_create, clock_index, size_t(virtual_clock_network_root_idx), arch_switch_idx);
}
}

int RoutingToClockConnection::create_virtual_clock_network_sink_node(
int x,
int y) {
RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, int y) {
auto& device_ctx = g_vpr_ctx.mutable_device();
auto& rr_nodes = device_ctx.rr_nodes;
rr_nodes.emplace_back();
auto node_index = rr_nodes.size() - 1;
auto& rr_graph = device_ctx.rr_nodes;
auto& node_lookup = device_ctx.rr_graph_builder.node_lookup();
rr_graph.emplace_back();
RRNodeId node_index = RRNodeId(rr_graph.size() - 1);

//Determine the a valid PTC
std::vector<int> nodes_at_loc;
get_rr_node_indices(device_ctx.rr_node_indices,
x, y,
SINK,
&nodes_at_loc);
std::vector<RRNodeId> nodes_at_loc = node_lookup.find_sink_nodes(x, y);

int max_ptc = 0;
for (int inode : nodes_at_loc) {
max_ptc = std::max<int>(max_ptc, device_ctx.rr_nodes[inode].ptc_num());
for (RRNodeId inode : nodes_at_loc) {
max_ptc = std::max<int>(max_ptc, rr_graph.node_ptc_num(inode));
}
int ptc = max_ptc + 1;

rr_nodes[node_index].set_ptc_num(ptc);
rr_nodes[node_index].set_coordinates(x, y, x, y);
rr_nodes[node_index].set_capacity(1);
rr_nodes[node_index].set_cost_index(SINK_COST_INDEX);
rr_nodes[node_index].set_type(SINK);
rr_graph.set_node_ptc_num(node_index, ptc);
rr_graph.set_node_coordinates(node_index, x, y, x, y);
rr_graph.set_node_capacity(node_index, 1);
rr_graph.set_node_cost_index(node_index, SINK_COST_INDEX);
rr_graph.set_node_type(node_index, SINK);
float R = 0.;
float C = 0.;
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(R, C));
rr_graph.set_node_rc_index(node_index, find_create_rr_rc_data(R, C));

add_to_rr_node_indices(device_ctx.rr_node_indices, rr_nodes, node_index);
// Use a generic way when adding nodes to lookup.
// However, since the SINK node has the same xhigh/xlow as well as yhigh/ylow, we can probably use a shortcut
for (int ix = rr_graph.node_xlow(node_index); ix <= rr_graph.node_xhigh(node_index); ++ix) {
for (int iy = rr_graph.node_ylow(node_index); iy <= rr_graph.node_yhigh(node_index); ++iy) {
node_lookup.add_node(node_index, ix, iy, rr_graph.node_type(node_index), rr_graph.node_ptc_num(node_index));
}
}

return node_index;
}
Expand Down Expand Up @@ -243,7 +242,7 @@ size_t ClockToPinsConnection::estimate_additional_nodes() {

void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) {
auto& device_ctx = g_vpr_ctx.device();
auto& rr_node_indices = device_ctx.rr_node_indices;
const auto& node_lookup = device_ctx.rr_graph.node_lookup();
auto& grid = clock_graph.grid();

for (size_t x = 0; x < grid.width(); x++) {
Expand Down Expand Up @@ -304,13 +303,11 @@ void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_gra
clock_y_offset = -1; // pick the chanx below the block
}

auto clock_pin_node_idx = get_rr_node_index(
rr_node_indices,
x,
y,
IPIN,
clock_pin_idx,
side);
auto clock_pin_node_idx = node_lookup.find_node(x,
y,
IPIN,
clock_pin_idx,
side);

auto clock_network_indices = clock_graph.get_rr_node_indices_at_switch_location(
clock_to_connect_from,
Expand All @@ -320,7 +317,7 @@ void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_gra

//Create edges depending on Fc
for (size_t i = 0; i < clock_network_indices.size() * fc; i++) {
clock_graph.add_edge(rr_edges_to_create, clock_network_indices[i], clock_pin_node_idx, arch_switch_idx);
clock_graph.add_edge(rr_edges_to_create, clock_network_indices[i], size_t(clock_pin_node_idx), arch_switch_idx);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we change the function prototype to avoid the cast (send in an RRNodeId instead)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See my reply in a previous comment on the t_rr_edge_info

}
}
}
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/route/clock_connection_builders.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class RoutingToClockConnection : public ClockConnection {
/* Connects the inter-block routing to the clock source at the specified coordinates */
void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) override;
size_t estimate_additional_nodes() override;
int create_virtual_clock_network_sink_node(int x, int y);
RRNodeId create_virtual_clock_network_sink_node(int x, int y);
};

class ClockToClockConneciton : public ClockConnection {
Expand Down
Loading