Skip to content

Converter from rr_nodes to RRGraph object #1048

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

Open
wants to merge 59 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
e826f57
infra: Update Travis Status Icon URL
kmurray Nov 20, 2019
62ede3a
add create rr_graph_obj function which loads rr_nodes to the object
tangxifan Nov 15, 2019
60de1d6
add in/out edge reserve methods for RRGraph object
tangxifan Nov 21, 2019
dc06c98
remove redundant files from util about RRGraph object
tangxifan Nov 21, 2019
d48dc31
fix bugs in reserving in/out_edges for RRGraph object
tangxifan Nov 21, 2019
b0048c0
optimizing memory footprints by removing unused vectors and maps
tangxifan Nov 21, 2019
b814fbf
fix broken code format
tangxifan Nov 21, 2019
1f5f178
further remove the large vector used temporarily when loading RRGraph
tangxifan Nov 21, 2019
7b3a490
vpr: Remove unused INTRA_CLUSTER_EDGE RR node type
kmurray Nov 21, 2019
4f9f90c
change num_non_config in/out edges to short integer, for sake of memo…
tangxifan Nov 22, 2019
7be1bdf
use NdMatrix in fast node lookup in RRGraph object
tangxifan Nov 22, 2019
58ad5b0
replace full vector of edge ids which simple edge range
tangxifan Nov 22, 2019
d2ebba7
replace node id vector with constant and minor bug fixing
tangxifan Nov 22, 2019
b7b78e0
further remove using nodes() and edges() inside RRGraph methods to sa…
tangxifan Nov 22, 2019
922b4bf
move convert rr_graph to be close to build_rr_graph
tangxifan Nov 22, 2019
169cde1
move clear RRGraph object to free_rr_graph()
tangxifan Nov 22, 2019
46abc1d
now node_in/out_edges are arranged in the same vector with delimeters…
tangxifan Nov 22, 2019
bb952ff
minor code format fix
tangxifan Nov 22, 2019
5ee9bb0
vpr: Rename RRGraph node/edge_id_range_ to num_nodes_/num_egdes_
kmurray Nov 22, 2019
b60df75
vpr: Prefer using valid_node_id()/valid_edge_id() in RRGraph
kmurray Nov 22, 2019
375f9ab
vpr: Use std::unordered_set for tracking invalied IDs in RRGraph
kmurray Nov 22, 2019
659192a
vpr: Use lazy iterators to iterate through RRGraph nodes/edges
kmurray Nov 22, 2019
9ad5ca2
vpr: Refactor lazy RRGraph node/edge iterators into a common template…
kmurray Nov 22, 2019
329c69b
vpr: Use forward declaration to move lazy_id_iterator implementation
kmurray Nov 22, 2019
97196e8
vpr: Reduce RRGraph memory usage by merging node edge arrays
kmurray Nov 22, 2019
7898667
vpr: Remove RRGraph::node_num_*edge() data members.
kmurray Nov 22, 2019
2854baa
flow: Pretty print upgraded architectures by default
kmurray Nov 25, 2019
a2c37c9
flow: Automatically run upgrade_arch.py on titan architectures
kmurray Nov 25, 2019
0a8dcf1
flow: Update titan benchmarks version
kmurray Nov 25, 2019
f265da9
flow: Add murax & picosoc Symbiflow benchmarks to nightly regressions
kmurray Nov 25, 2019
11f719a
add malloc_trim to have clean memory stats when building rr_graph
tangxifan Nov 26, 2019
3ac57f5
add create rr_graph_obj function which loads rr_nodes to the object
tangxifan Nov 15, 2019
6896e1b
add in/out edge reserve methods for RRGraph object
tangxifan Nov 21, 2019
b6ad5b0
remove redundant files from util about RRGraph object
tangxifan Nov 21, 2019
a41491b
fix bugs in reserving in/out_edges for RRGraph object
tangxifan Nov 21, 2019
0b5f004
optimizing memory footprints by removing unused vectors and maps
tangxifan Nov 21, 2019
9c1402a
fix broken code format
tangxifan Nov 21, 2019
cdc0df9
further remove the large vector used temporarily when loading RRGraph
tangxifan Nov 21, 2019
9cc9bff
change num_non_config in/out edges to short integer, for sake of memo…
tangxifan Nov 22, 2019
02ed2ad
use NdMatrix in fast node lookup in RRGraph object
tangxifan Nov 22, 2019
679b06d
replace full vector of edge ids which simple edge range
tangxifan Nov 22, 2019
a6f8c49
replace node id vector with constant and minor bug fixing
tangxifan Nov 22, 2019
40cbe19
further remove using nodes() and edges() inside RRGraph methods to sa…
tangxifan Nov 22, 2019
25d6540
move convert rr_graph to be close to build_rr_graph
tangxifan Nov 22, 2019
a96a1f0
move clear RRGraph object to free_rr_graph()
tangxifan Nov 22, 2019
643f21f
now node_in/out_edges are arranged in the same vector with delimeters…
tangxifan Nov 22, 2019
5342a7c
minor code format fix
tangxifan Nov 22, 2019
5e62b39
vpr: Rename RRGraph node/edge_id_range_ to num_nodes_/num_egdes_
kmurray Nov 22, 2019
967d18f
vpr: Prefer using valid_node_id()/valid_edge_id() in RRGraph
kmurray Nov 22, 2019
d042246
vpr: Use std::unordered_set for tracking invalied IDs in RRGraph
kmurray Nov 22, 2019
8f1fa62
vpr: Use lazy iterators to iterate through RRGraph nodes/edges
kmurray Nov 22, 2019
52d696c
vpr: Refactor lazy RRGraph node/edge iterators into a common template…
kmurray Nov 22, 2019
0907cc4
vpr: Use forward declaration to move lazy_id_iterator implementation
kmurray Nov 22, 2019
88cd88c
vpr: Reduce RRGraph memory usage by merging node edge arrays
kmurray Nov 22, 2019
763b22d
vpr: Remove RRGraph::node_num_*edge() data members.
kmurray Nov 22, 2019
0e81632
add malloc_trim to have clean memory stats when building rr_graph
tangxifan Nov 26, 2019
88473d9
move malloc_trim ahead of timer to gain more accurate memory stats
tangxifan Nov 26, 2019
ab912a5
Merge branch 'rr_graph_refactoring' of https://github.com/tangxifan/v…
tangxifan Nov 26, 2019
441f55a
comment out the create_device memory stats to have clean memory stats…
tangxifan Nov 26, 2019
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Verilog to Routing (VTR)
[![Build Status](https://travis-ci.org/verilog-to-routing/vtr-verilog-to-routing.svg?branch=master)](https://travis-ci.org/verilog-to-routing/vtr-verilog-to-routing) [![Documentation Status](https://readthedocs.org/projects/vtr/badge/?version=latest)](http://docs.verilogtorouting.org/en/latest/?badge=latest)
[![Build Status](https://travis-ci.com/verilog-to-routing/vtr-verilog-to-routing.svg?branch=master)](https://travis-ci.org/verilog-to-routing/vtr-verilog-to-routing) [![Documentation Status](https://readthedocs.org/projects/vtr/badge/?version=latest)](http://docs.verilogtorouting.org/en/latest/?badge=latest)

## Introduction
The Verilog-to-Routing (VTR) project is a world-wide collaborative effort to provide a open-source framework for conducting FPGA architecture and CAD research and development.
Expand Down
1 change: 1 addition & 0 deletions libs/libvtrutil/src/vtr_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ template<class T>
class Point {
public: //Constructors
Point(T x_val, T y_val) noexcept;
Point();

public: //Accessors
//Coordinates
Expand Down
10 changes: 10 additions & 0 deletions libs/libvtrutil/src/vtr_geometry.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ Point<T>::Point(T x_val, T y_val) noexcept
//pass
}

template<class T>
Point<T>::Point() {
//pass
}

template<class T>
T Point<T>::x() const {
return x_;
Expand Down Expand Up @@ -74,6 +79,11 @@ Rect<T>::Rect(Point<T> bottom_left_val, Point<T> top_right_val)
//pass
}

template<class T>
Rect<T>::Rect() {
//pass
}

template<class T>
T Rect<T>::xmin() const {
return bottom_left_.x();
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
}

void vpr_create_device(t_vpr_setup& vpr_setup, const t_arch& arch) {
vtr::ScopedStartFinishTimer timer("Create Device");
//vtr::ScopedStartFinishTimer timer("Create Device");
vpr_create_device_grid(vpr_setup, arch);

vpr_setup_clock_networks(vpr_setup, arch);
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/base/vpr_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "router_lookahead.h"
#include "place_macro.h"
#include "compressed_grid.h"
#include "rr_graph_obj.h"

//A Context is collection of state relating to a particular part of VPR
//
Expand Down Expand Up @@ -136,6 +137,9 @@ struct DeviceContext : public Context {
/* chan_width is for x|y-directed channels; i.e. between rows */
t_chan_width chan_width;

/* Object to define routing resources */
RRGraph rr_graph;

/* Structures to define the routing architecture of the FPGA. */
std::vector<t_rr_node> rr_nodes; /* autogenerated in build_rr_graph */

Expand Down
9 changes: 2 additions & 7 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1133,10 +1133,6 @@ struct t_linked_f_pointer {

typedef std::vector<std::vector<std::vector<std::vector<std::vector<int>>>>> t_rr_node_indices; //[0..num_rr_types-1][0..grid_width-1][0..grid_height-1][0..NUM_SIDES-1][0..max_ptc-1]

/* Uncomment lines below to save some memory, at the cost of debugging ease. */
/*enum e_rr_type {SOURCE, SINK, IPIN, OPIN, CHANX, CHANY}; */
/* typedef short t_rr_type */

/* Type of a routing resource node. x-directed channel segment, *
* y-directed channel segment, input pin to a clb to pad, output *
* from a clb or pad (i.e. output pin of a net) and: *
Expand All @@ -1151,12 +1147,11 @@ typedef enum e_rr_type : unsigned char {
OPIN,
CHANX,
CHANY,
INTRA_CLUSTER_EDGE,
NUM_RR_TYPES
} t_rr_type;

constexpr std::array<t_rr_type, NUM_RR_TYPES> RR_TYPES = {{SOURCE, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE}};
constexpr std::array<const char*, NUM_RR_TYPES> rr_node_typename{{"SOURCE", "SINK", "IPIN", "OPIN", "CHANX", "CHANY", "INTRA_CLUSTER_EDGE"}};
constexpr std::array<t_rr_type, NUM_RR_TYPES> RR_TYPES = {{SOURCE, SINK, IPIN, OPIN, CHANX, CHANY}};
constexpr std::array<const char*, NUM_RR_TYPES> rr_node_typename{{"SOURCE", "SINK", "IPIN", "OPIN", "CHANX", "CHANY"}};

/* Basic element used to store the traceback (routing) of each net. *
* index: Array index (ID) of this routing resource node. *
Expand Down
19 changes: 7 additions & 12 deletions vpr/src/device/check_rr_graph_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static bool check_rr_graph_source_nodes(const RRGraph& rr_graph) {
}
}

return invalid_sources;
return !invalid_sources;
}

/***********************************************************************
Expand Down Expand Up @@ -136,7 +136,7 @@ static bool check_rr_graph_sink_nodes(const RRGraph& rr_graph) {
}
}

return invalid_sinks;
return !invalid_sinks;
}

/***********************************************************************
Expand All @@ -153,48 +153,43 @@ static bool check_rr_graph_sink_nodes(const RRGraph& rr_graph) {
* will work properly.
**********************************************************************/
bool check_rr_graph(const RRGraph& rr_graph) {
bool check_flag = true;
size_t num_err = 0;

if (false == check_rr_graph_duplicated_edges(rr_graph)) {
VTR_LOG_WARN("Fail in checking duplicated edges !\n");
check_flag = false;
num_err++;
}

if (false == check_rr_graph_dangling_nodes(rr_graph)) {
VTR_LOG_WARN("Fail in checking dangling nodes !\n");
check_flag = false;
num_err++;
}

if (false == check_rr_graph_source_nodes(rr_graph)) {
VTR_LOG_WARN("Fail in checking source nodes!\n");
check_flag = false;
num_err++;
}

if (false == check_rr_graph_sink_nodes(rr_graph)) {
VTR_LOG_WARN("Fail in checking sink nodes!\n");
check_flag = false;
num_err++;
}

if (false == check_rr_graph_source_nodes(rr_graph)) {
VTR_LOG_WARN("Fail in checking source nodes!\n");
check_flag = false;
num_err++;
}

if (false == check_rr_graph_sink_nodes(rr_graph)) {
VTR_LOG_WARN("Fail in checking sink nodes!\n");
check_flag = false;
num_err++;
}

/* Error out if there is any fatal errors found */
VTR_LOG_WARN("Checked Routing Resource graph with %d errors !\n",
num_err);
if (0 < num_err) {
VTR_LOG_WARN("Checked Routing Resource graph with %d errors !\n",
num_err);
}

return check_flag;
return (0 == num_err);
}
138 changes: 138 additions & 0 deletions vpr/src/device/create_rr_graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* Standard header files required go first */
#include <map>

/* EXTERNAL library header files go second*/
#include "vtr_assert.h"
#include "vtr_time.h"
#include "vtr_memory.h"

/* VPR header files go then */
#include "vpr_types.h"
#include "rr_graph_obj.h"
#include "check_rr_graph_obj.h"
#include "create_rr_graph.h"

/* Finally we include global variables */
#include "globals.h"

/********************************************************************
* TODO: remove when this conversion (from traditional to new data structure)
* is no longer needed
* This function will convert an existing rr_graph in device_ctx to the RRGraph
*object
* This function is used to test our RRGraph if it is acceptable in downstream
*routers
********************************************************************/
void convert_rr_graph(std::vector<t_segment_inf>& vpr_segments) {
/* Release freed memory before start building rr_graph */
vtr::malloc_trim(0);

vtr::ScopedStartFinishTimer timer("Conversion to routing resource graph object");

/* IMPORTANT: to build clock tree,
* vpr added segments to the original arch segments
* This is why to use vpr_segments as an inputs!!!
*/
auto& device_ctx = g_vpr_ctx.mutable_device();

/* The number of switches are in general small,
* reserve switches may not bring significant memory efficiency
* So, we just use create_switch to push_back each time
*/
device_ctx.rr_graph.reserve_switches(device_ctx.rr_switch_inf.size());
// Create the switches
for (size_t iswitch = 0; iswitch < device_ctx.rr_switch_inf.size(); ++iswitch) {
device_ctx.rr_graph.create_switch(device_ctx.rr_switch_inf[iswitch]);
}

/* The number of segments are in general small, reserve segments may not bring
* significant memory efficiency */
device_ctx.rr_graph.reserve_segments(vpr_segments.size());
// Create the segments
for (size_t iseg = 0; iseg < vpr_segments.size(); ++iseg) {
device_ctx.rr_graph.create_segment(vpr_segments[iseg]);
}

/* Reserve list of nodes to be memory efficient */
device_ctx.rr_graph.reserve_nodes((unsigned long)device_ctx.rr_nodes.size());

// Create the nodes
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
auto& node = device_ctx.rr_nodes[inode];
RRNodeId rr_node = device_ctx.rr_graph.create_node(node.type());

device_ctx.rr_graph.set_node_xlow(rr_node, node.xlow());
device_ctx.rr_graph.set_node_ylow(rr_node, node.ylow());
device_ctx.rr_graph.set_node_xhigh(rr_node, node.xhigh());
device_ctx.rr_graph.set_node_yhigh(rr_node, node.yhigh());

device_ctx.rr_graph.set_node_capacity(rr_node, node.capacity());

device_ctx.rr_graph.set_node_ptc_num(rr_node, node.ptc_num());

device_ctx.rr_graph.set_node_cost_index(rr_node, node.cost_index());

if (CHANX == node.type() || CHANY == node.type()) {
device_ctx.rr_graph.set_node_direction(rr_node, node.direction());
}
if (IPIN == node.type() || OPIN == node.type()) {
device_ctx.rr_graph.set_node_side(rr_node, node.side());
}
device_ctx.rr_graph.set_node_R(rr_node, node.R());
device_ctx.rr_graph.set_node_C(rr_node, node.C());

/* Set up segment id */
short irc_data = node.cost_index();
short iseg = device_ctx.rr_indexed_data[irc_data].seg_index;
device_ctx.rr_graph.set_node_segment(rr_node, RRSegmentId(iseg));
}

/* Reserve list of edges to be memory efficient */
unsigned long num_edges_to_reserve = 0;
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
const auto& node = device_ctx.rr_nodes[inode];
num_edges_to_reserve += node.num_edges();
}
device_ctx.rr_graph.reserve_edges(num_edges_to_reserve);

/* Add edges for each node */
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
const auto& node = device_ctx.rr_nodes[inode];
for (int iedge = 0; iedge < node.num_edges(); ++iedge) {
size_t isink_node = node.edge_sink_node(iedge);
int iswitch = node.edge_switch(iedge);

device_ctx.rr_graph.create_edge(RRNodeId(inode),
RRNodeId(isink_node),
RRSwitchId(iswitch));
}
}

/* Ensure that we reserved what we want */
VTR_ASSERT(num_edges_to_reserve == (unsigned long)device_ctx.rr_graph.edges().size());

/* Partition edges to be two class: configurable (1st part) and
* non-configurable (2nd part)
* See how the router will use the edges and determine the strategy
* if we want to partition the edges first or depends on the routing needs
*/
device_ctx.rr_graph.rebuild_node_edges();

/* Essential check for rr_graph, build look-up and */
if (false == device_ctx.rr_graph.validate()) {
/* Error out if built-in validator of rr_graph fails */
vpr_throw(VPR_ERROR_ROUTE,
__FILE__,
__LINE__,
"Fundamental errors occurred when validating rr_graph object!\n");
}

/* Error out if advanced checker of rr_graph fails */
if (false == check_rr_graph(device_ctx.rr_graph)) {
vpr_throw(VPR_ERROR_ROUTE,
__FILE__,
__LINE__,
"Advanced checking rr_graph object fails! Routing may still work "
"but not smooth\n");
}
}
17 changes: 17 additions & 0 deletions vpr/src/device/create_rr_graph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef CREATE_RR_GRAPH_H
#define CREATE_RR_GRAPH_H

/*
* Notes in include header files in a head file
* Only include the neccessary header files
* that is required by the data types in the function/class declarations!
*/
#include "rr_graph_obj.h"

/* IMPORTANT: to build clock tree,
* vpr added segments to the original arch segments
* This is why to use vpr_segments as an inputs!!!
*/
void convert_rr_graph(std::vector<t_segment_inf>& vpr_segments);

#endif
Loading