Skip to content

Move rr_graph_reader & rr_graph_writer to librrgraph. #2101

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 25 commits into from
Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e785f1c
Files moved to Librrgraph and Files added to Libarchfpga
oscarcheng105 Jul 18, 2022
377186b
Merge branch 'verilog-to-routing:master' into master
oscarcheng105 Jul 18, 2022
93a7dc6
Fix input parameters for load_rr_graph(), write_rr_graph(), check_rr_…
oscarcheng105 Jul 18, 2022
b42102a
Fix input parameters of add_rr_edge_metadata(), add_rr_node_metadata(…
oscarcheng105 Jul 18, 2022
5db7988
[vpr] move VTR_ENABLE_CAPNPROTO to librrgraph CMakeList.txt
oscarcheng105 Jul 19, 2022
0bb613f
[vpr] move cmake dependencies in vpr/src/route to librrgraph/src/base/
oscarcheng105 Jul 20, 2022
3cccda7
Merge branch 'verilog-to-routing:master' into librrgraph_vpr
oscarcheng105 Jul 20, 2022
e428f8a
[vpr] clean up dead code
oscarcheng105 Jul 20, 2022
a30ca69
[vpr] clean up dead code 2
oscarcheng105 Jul 21, 2022
7840120
[vpr] format fix
oscarcheng105 Jul 21, 2022
3200ba9
[vpr] move files to corresponding folder in librrgraph/src
oscarcheng105 Jul 23, 2022
916c6fe
[vpr] fix parameters of check_rr_graph, check_rr_node, RrGraphSeriali…
oscarcheng105 Jul 23, 2022
ff83a48
[vpr] move histogram to libarchfpga, merge rr_graph_util, add alloc_a…
oscarcheng105 Jul 25, 2022
77971b0
Merge branch 'verilog-to-routing:master' into librrgraph_vpr
oscarcheng105 Jul 25, 2022
bfcb7ec
[vpr] move describe_rr_node.cpp to librrgraph/src/utils
oscarcheng105 Jul 25, 2022
c3ff424
[vpr] add get_parallel_segs.cpp to librrgraph
oscarcheng105 Jul 26, 2022
ca391d3
[vpr] format fix
oscarcheng105 Jul 26, 2022
70cc0b4
[vpr] format
oscarcheng105 Jul 26, 2022
9682216
[vpr] format fix 2
oscarcheng105 Jul 26, 2022
2280445
[vpr] categorize files to rr_graph_type & rr_graph_cost in librrgraph
oscarcheng105 Jul 26, 2022
2aa7ce6
Merge branch 'verilog-to-routing:master' into librrgraph_vpr
oscarcheng105 Jul 29, 2022
4a4eb96
[vpr] code cleanup
oscarcheng105 Jul 29, 2022
783fa6b
Merge branch 'librrgraph_vpr' of github.com:oscarcheng105/vtr-verilog…
oscarcheng105 Jul 29, 2022
e900c68
[vpr] doc update
oscarcheng105 Aug 2, 2022
1b8d060
Merge branch 'verilog-to-routing:master' into librrgraph_vpr
oscarcheng105 Aug 8, 2022
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "device_grid.h"
#include "vpr_utils.h"

DeviceGrid::DeviceGrid(std::string grid_name, vtr::Matrix<t_grid_tile> grid)
: name_(grid_name)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions libs/librrgraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ file(GLOB_RECURSE LIB_SOURCES src/*/*.cpp)
file(GLOB_RECURSE LIB_HEADERS src/*/*.h)
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)

if(${VTR_ENABLE_CAPNPROTO})
add_definitions("-DVTR_ENABLE_CAPNPROTO")
endif()

#Create the library
add_library(librrgraph STATIC
${LIB_HEADERS}
Expand All @@ -23,6 +27,10 @@ target_link_libraries(librrgraph
libarchfpga
)

if(${VTR_ENABLE_CAPNPROTO})
target_link_libraries(librrgraph libvtrcapnproto)
endif()

target_compile_definitions(librrgraph PUBLIC ${INTERCHANGE_SCHEMA_HEADERS})

# Unit tests
Expand All @@ -33,3 +41,21 @@ target_compile_definitions(librrgraph PUBLIC ${INTERCHANGE_SCHEMA_HEADERS})

# Run unit tests: comment out for now
#add_test(NAME test_rr_graph COMMAND test_rr_graph --use-colour=yes)

add_custom_target(
generate_rr_graph_serializers
COMMAND ${CMAKE_COMMAND} -E remove_directory rr_graph_generate
COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx
COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E copy
rr_graph_generate/rr_graph_uxsdcxx.h
rr_graph_generate/rr_graph_uxsdcxx_capnp.h
rr_graph_generate/rr_graph_uxsdcxx_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/src/base/gen
COMMAND ${CMAKE_COMMAND} -E copy rr_graph_generate/rr_graph_uxsdcxx.capnp ${CMAKE_CURRENT_SOURCE_DIR}/../libvtrcapnproto/gen
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,30 @@ mediated via RrGraphBase located in `rr_graph_uxsdcxx_interface.h`.

If `rr_graph.xsd` is modified, then the following files must be updated:

- `vpr/src/route/gen/rr_graph_uxsdcxx.h`
- `vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h`
- `vpr/src/route/gen/rr_graph_uxsdcxx_interface.h`
- `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h`
- `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h`
- `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h`
- `libs/libvtrcapnproto/rr_graph_uxsdcxx.capnp`

### Instructions to update generated files (using CMake)

1. Run target `generate_rr_graph_serializers`, e.g. run `make generate_rr_graph_serializers`.
2. Run target `format`, e.g. run `make format`.
3. Update `vpr/src/route/rr_graph_uxsdcxx_interface_impl.h`, implement or
3. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or
update interfaces that are new or are changed. The compiler will complain
that virtual methods are missing if the schema has changed.

### Instructions to update generated files (manually)

1. Clone https://github.com/duck2/uxsdcxx/
2. Run `python3 -mpip install --user -r requirements.txt`
3. Run `python3 uxsdcxx.py vpr/src/route/rr_graph.xsd`
3. Run `python3 uxsdcap.py vpr/src/route/rr_graph.xsd`
3. Run `python3 uxsdcxx.py libs/librrgraph/src/base/rr_graph.xsd`
3. Run `python3 uxsdcap.py libs/librrgraph/src/base/rr_graph.xsd`
4. Copy `rr_graph_uxsdcxx.h`, `rr_graph_uxsdcxx_capnp.h`,
`rr_graph_uxsdcxx_interface.h` to `vpr/src/route/`
5. Copy `rr_graph_uxsdcxx.capnp` to `libs/libvtrcapnproto/`
`rr_graph_uxsdcxx_interface.h` to `libs/librrgraph/src/base/`
5. Copy `rr_graph_uxsdcxx.capnp` to `../libvtrcapnproto/`
6. Run `make format`
7. Update `vpr/src/route/rr_graph_uxsdcxx_interface_impl.h`, implement or
7. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or
update interfaces that are new or are changed. The compiler will complain
that virtual methods are missing if the schema has changed.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
#include "vtr_log.h"
#include "vtr_memory.h"
#include "vtr_util.h"

#include "vpr_types.h"
#include "vpr_error.h"

#include "globals.h"
#include "rr_graph.h"
#include "check_rr_graph.h"

#include "rr_node.h"
#include "physical_types_util.h"

#include "describe_rr_node.h"

/*********************** Subroutines local to this module *******************/

static bool rr_node_is_global_clb_ipin(RRNodeId inode);
static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode);

static void check_unbuffered_edges(int from_node);
static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node);

static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid);
static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_rr_node& node);
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a mark here. This function need a refactoring. We should use RRNodeId rather than t_rr_node which is now an internal data of RRGraph


static void check_rr_edge(int from_node, int from_edge, int to_node);
static void check_rr_edge(const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data, int from_node, int from_edge, int to_node);

/************************ Subroutine definitions ****************************/

Expand All @@ -39,17 +41,18 @@ class node_edge_sorter {
}
};

void check_rr_graph(const t_graph_type graph_type,
void check_rr_graph(const RRGraphView& rr_graph,
const std::vector<t_physical_tile_type>& types,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const DeviceGrid& grid,
const std::vector<t_physical_tile_type>& types) {
const t_chan_width& chan_width,
const t_graph_type graph_type,
int virtual_clock_network_root_idx) {
e_route_type route_type = DETAILED;
if (graph_type == GRAPH_GLOBAL) {
route_type = GLOBAL;
}

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

auto total_edges_to_node = std::vector<int>(rr_graph.num_nodes());
auto switch_types_from_current_to_node = std::vector<unsigned char>(rr_graph.num_nodes());
const int num_rr_switches = rr_graph.num_rr_switches();
Expand All @@ -66,14 +69,14 @@ void check_rr_graph(const t_graph_type graph_type,
}

// Virtual clock network sink is special, ignore.
if (device_ctx.virtual_clock_network_root_idx == int(inode)) {
if (virtual_clock_network_root_idx == int(inode)) {
continue;
}

t_rr_type rr_type = rr_graph.node_type(rr_node);
int num_edges = rr_graph.num_edges(RRNodeId(inode));

check_rr_node(inode, route_type, device_ctx);
check_rr_node(rr_graph, rr_indexed_data, grid, chan_width, route_type, inode);

/* Check all the connectivity (edges, etc.) information. */
edges.resize(0);
Expand All @@ -89,7 +92,7 @@ void check_rr_graph(const t_graph_type graph_type,
inode, to_node);
}

check_rr_edge(inode, iedge, to_node);
check_rr_edge(rr_graph, grid, rr_indexed_data, inode, iedge, to_node);

edges.emplace_back(to_node, iedge);
total_edges_to_node[to_node]++;
Expand Down Expand Up @@ -181,7 +184,7 @@ void check_rr_graph(const t_graph_type graph_type,
}

/* Slow test could leave commented out most of the time. */
check_unbuffered_edges(inode);
check_unbuffered_edges(rr_graph, inode);

//Check that all config/non-config edges are appropriately organized
for (auto edge : rr_graph.configurable_edges(RRNodeId(inode))) {
Expand All @@ -204,19 +207,19 @@ void check_rr_graph(const t_graph_type graph_type,
* now I check that everything is reachable. */
bool is_fringe_warning_sent = false;

for (const RRNodeId& rr_node : device_ctx.rr_graph.nodes()) {
for (const RRNodeId& rr_node : rr_graph.nodes()) {
size_t inode = (size_t)rr_node;
t_rr_type rr_type = rr_graph.node_type(rr_node);

if (rr_type != SOURCE) {
if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(rr_node)) {
if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(rr_graph, grid, rr_node)) {
/* A global CLB input pin will not have any edges, and neither will *
* a SOURCE or the start of a carry-chain. Anything else is an error.
* For simplicity, carry-chain input pin are entirely ignored in this test
*/
bool is_chain = false;
if (rr_type == IPIN) {
t_physical_tile_type_ptr type = device_ctx.grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type;
t_physical_tile_type_ptr type = grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type;
for (const t_fc_specification& fc_spec : types[type->index].fc_specs) {
if (fc_spec.fc_value == 0 && fc_spec.seg_index == 0) {
is_chain = true;
Expand All @@ -235,8 +238,8 @@ void check_rr_graph(const t_graph_type graph_type,

if (!is_chain && !is_fringe && !is_wire) {
if (rr_graph.node_type(rr_node) == IPIN || rr_graph.node_type(rr_node) == OPIN) {
if (has_adjacent_channel(node, device_ctx.grid)) {
auto block_type = device_ctx.grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type;
if (has_adjacent_channel(rr_graph, grid, node)) {
auto block_type = grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type;
std::string pin_name = block_type_pin_index_to_name(block_type, rr_graph.node_pin_num(rr_node));
/* Print error messages for all the sides that a node may appear */
for (const e_side& node_side : SIDES) {
Expand Down Expand Up @@ -268,16 +271,13 @@ void check_rr_graph(const t_graph_type graph_type,
}
}

static bool rr_node_is_global_clb_ipin(RRNodeId inode) {
static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode) {
/* Returns true if inode refers to a global CLB input pin node. */

int ipin;
t_physical_tile_type_ptr type;

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

type = device_ctx.grid[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)].type;
type = grid[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)].type;

if (rr_graph.node_type(inode) != IPIN)
return (false);
Expand All @@ -287,7 +287,12 @@ static bool rr_node_is_global_clb_ipin(RRNodeId inode) {
return type->is_ignored_pin[ipin];
}

void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& device_ctx) {
void check_rr_node(const RRGraphView& rr_graph,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const DeviceGrid& grid,
const t_chan_width& chan_width,
enum e_route_type route_type,
int inode) {
/* This routine checks that the rr_node is inside the grid and has a valid
* pin number, etc.
*/
Expand All @@ -298,7 +303,6 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
int nodes_per_chan, tracks_per_node, num_edges;
RRIndexedDataId cost_index;
float C, R;
const auto& rr_graph = device_ctx.rr_graph;
RRNodeId rr_node = RRNodeId(inode);

rr_type = rr_graph.node_type(rr_node);
Expand All @@ -311,7 +315,6 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
cost_index = rr_graph.node_cost_index(rr_node);
type = nullptr;

const auto& grid = device_ctx.grid;
if (xlow > xhigh || ylow > yhigh) {
VPR_ERROR(VPR_ERROR_ROUTE,
"in check_rr_node: rr endpoints are (%d,%d) and (%d,%d).\n", xlow, ylow, xhigh, yhigh);
Expand All @@ -327,13 +330,13 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
"in check_rr_node: inode %d (type %d) had a ptc_num of %d.\n", inode, rr_type, ptc_num);
}

if (!cost_index || (size_t)cost_index >= (size_t)device_ctx.rr_indexed_data.size()) {
if (!cost_index || (size_t)cost_index >= (size_t)rr_indexed_data.size()) {
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
"in check_rr_node: node %d cost index (%d) is out of range.\n", inode, cost_index);
}

/* Check that the segment is within the array and such. */
type = device_ctx.grid[xlow][ylow].type;
type = grid[xlow][ylow].type;

switch (rr_type) {
case SOURCE:
Expand Down Expand Up @@ -439,11 +442,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&

case CHANX:
if (route_type == DETAILED) {
nodes_per_chan = device_ctx.chan_width.max;
nodes_per_chan = chan_width.max;
tracks_per_node = 1;
} else {
nodes_per_chan = 1;
tracks_per_node = device_ctx.chan_width.x_list[ylow];
tracks_per_node = chan_width.x_list[ylow];
}

if (ptc_num >= nodes_per_chan) {
Expand All @@ -459,11 +462,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&

case CHANY:
if (route_type == DETAILED) {
nodes_per_chan = device_ctx.chan_width.max;
nodes_per_chan = chan_width.max;
tracks_per_node = 1;
} else {
nodes_per_chan = 1;
tracks_per_node = device_ctx.chan_width.y_list[xlow];
tracks_per_node = chan_width.y_list[xlow];
}

if (ptc_num >= nodes_per_chan) {
Expand Down Expand Up @@ -494,13 +497,13 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
//Don't worry about disconnect PINs which have no adjacent channels (i.e. on the device perimeter)
bool check_for_out_edges = true;
if (rr_type == IPIN || rr_type == OPIN) {
if (!has_adjacent_channel(rr_graph.rr_nodes()[inode], device_ctx.grid)) {
if (!has_adjacent_channel(rr_graph, grid, rr_graph.rr_nodes()[inode])) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a mark, rr_nodes() just expose the internal node storage directly to client function, which should be avoid. I suggest to rework this function later.

/** @brief Return the node-level storage structure for queries from client functions */
inline const t_rr_graph_storage& rr_nodes() const {
return node_storage_;
}

check_for_out_edges = false;
}
}

if (check_for_out_edges) {
std::string info = describe_rr_node(inode);
std::string info = describe_rr_node(rr_graph, grid, rr_indexed_data, inode);
VTR_LOG_WARN("in check_rr_node: %s has no out-going edges.\n", info.c_str());
}
}
Expand Down Expand Up @@ -528,7 +531,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext&
}
}

static void check_unbuffered_edges(int from_node) {
static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node) {
/* This routine checks that all pass transistors in the routing truly are *
* bidirectional. It may be a slow check, so don't use it all the time. */

Expand All @@ -537,9 +540,6 @@ static void check_unbuffered_edges(int from_node) {
short from_switch_type;
bool trans_matched;

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

from_rr_type = rr_graph.node_type(RRNodeId(from_node));
if (from_rr_type != CHANX && from_rr_type != CHANY)
return;
Expand Down Expand Up @@ -584,11 +584,10 @@ static void check_unbuffered_edges(int from_node) {
} /* End for all from_node edges */
}

static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid) {
static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_rr_node& node) {
/* TODO: this function should be reworked later to adapt RRGraphView interface
* once xlow(), ylow(), side() APIs are implemented
*/
const auto& rr_graph = g_vpr_ctx.device().rr_graph;
VTR_ASSERT(rr_graph.node_type(node.id()) == IPIN || rr_graph.node_type(node.id()) == OPIN);

if ((rr_graph.node_xlow(node.id()) == 0 && !rr_graph.is_node_on_specific_side(node.id(), RIGHT)) //left device edge connects only along block's right side
Expand All @@ -601,9 +600,7 @@ static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid)
return true; //All other blocks will be surrounded on all sides by channels
}

static void check_rr_edge(int from_node, int iedge, int to_node) {
auto& device_ctx = g_vpr_ctx.device();
const auto& rr_graph = device_ctx.rr_graph;
static void check_rr_edge(const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data, int from_node, int iedge, int to_node) {

//Check that to to_node's fan-in is correct, given the switch type
int iswitch = rr_graph.edge_switch(RRNodeId(from_node), iedge);
Expand All @@ -617,7 +614,7 @@ static void check_rr_edge(int from_node, int iedge, int to_node) {
std::string msg = "Non-configurable BUFFER type switch must have only one driver. ";
msg += vtr::string_fmt(" Actual fan-in was %d (expected 1).\n", to_fanin);
msg += " Possible cause is complex block output pins connecting to:\n";
msg += " " + describe_rr_node(to_node);
msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, to_node);

VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str());
}
Expand Down
Loading