Skip to content

Commit

Permalink
add create rr_graph_obj function which loads rr_nodes to the object
Browse files Browse the repository at this point in the history
  • Loading branch information
tangxifan committed Nov 20, 2019
1 parent 619e721 commit e0a212a
Show file tree
Hide file tree
Showing 11 changed files with 407 additions and 20 deletions.
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
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
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);
}
149 changes: 149 additions & 0 deletions vpr/src/device/create_rr_graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* Standard header files required go first */
#include <map>

/* EXTERNAL library header files go second*/
#include "vtr_assert.h"
#include "vtr_time.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) {
vtr::ScopedStartFinishTimer timer("Build 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();

/* make sure we have a clean empty rr_graph */
device_ctx.rr_graph.clear();

/* 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(device_ctx.rr_nodes.size());

// Create the nodes
std::map<int, RRNodeId> old_to_new_rr_node;
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));

VTR_ASSERT(!old_to_new_rr_node.count(inode));
old_to_new_rr_node[inode] = rr_node;
}

/* Reserve list of edges to be memory efficient */
{
int 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);
}

// Create the edges
std::map<std::pair<int, int>, RREdgeId> old_to_new_rr_edge; // Key:
// {inode,iedge}
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) {
int isink_node = node.edge_sink_node(iedge);
int iswitch = node.edge_switch(iedge);

VTR_ASSERT(old_to_new_rr_node.count(inode));
VTR_ASSERT(old_to_new_rr_node.count(isink_node));

RREdgeId rr_edge = device_ctx.rr_graph.create_edge(old_to_new_rr_node[inode],
old_to_new_rr_node[isink_node],
RRSwitchId(iswitch));

auto key = std::make_pair(inode, iedge);
VTR_ASSERT(!old_to_new_rr_edge.count(key));
old_to_new_rr_edge[key] = rr_edge;
}
}

/* 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.partition_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
14 changes: 6 additions & 8 deletions vpr/src/device/rr_graph_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,6 @@ bool RRGraph::validate_edge_sink_nodes() const {
* Warnings are thrown if optional checking fails
*/
bool RRGraph::validate() const {
bool check_flag = true;
size_t num_err = 0;

initialize_fast_node_lookup();
Expand All @@ -724,34 +723,32 @@ bool RRGraph::validate() const {
*/
if (false == validate_sizes()) {
VTR_LOG_WARN("Fail in validating node- and edge-related vector sizes!\n");
check_flag = false;
num_err++;
}

/* Fundamental check */
if (false == validate_nodes_edges()) {
VTR_LOG_WARN("Fail in validating edges connected to each node!\n");
check_flag = false;
num_err++;
}

if (false == validate_node_segments()) {
VTR_LOG_WARN("Fail in validating segment IDs of nodes !\n");
check_flag = false;
num_err++;
}

if (false == validate_edge_switches()) {
VTR_LOG_WARN("Fail in validating switch IDs of edges !\n");
check_flag = false;
num_err++;
}

/* Error out if there is any fatal errors found */
VTR_LOG_ERROR("Routing Resource graph is not valid due to %d fatal errors !\n",
num_err);
if (0 < num_err) {
VTR_LOG_ERROR("Routing Resource graph is not valid due to %d fatal errors !\n",
num_err);
}

return check_flag;
return (0 == num_err);
}

bool RRGraph::is_dirty() const {
Expand Down Expand Up @@ -827,6 +824,7 @@ RRNodeId RRGraph::create_node(const t_rr_type& type) {
node_sides_.push_back(NUM_SIDES);
node_Rs_.push_back(0.);
node_Cs_.push_back(0.);
node_segments_.push_back(RRSegmentId::INVALID());

node_in_edges_.emplace_back(); //Initially empty
node_out_edges_.emplace_back(); //Initially empty
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/route/rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "rr_graph_reader.h"
#include "router_lookahead_map.h"
#include "rr_graph_clock.h"
#include "create_rr_graph.h"

#include "rr_types.h"

Expand Down Expand Up @@ -375,6 +376,9 @@ void create_rr_graph(const t_graph_type graph_type,

print_rr_graph_stats();

/* Create rr_graph object: load rr_nodes to the object */
convert_rr_graph(segment_inf);

//Write out rr graph file if needed
if (!det_routing_arch->write_rr_graph_filename.empty()) {
write_rr_graph(det_routing_arch->write_rr_graph_filename.c_str(), segment_inf);
Expand Down
30 changes: 30 additions & 0 deletions vpr/src/util/rr_graph_obj_util.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/****************************************************************************
* This file include most-utilized functions that manipulate on the
* RRGraph object
***************************************************************************/
#include <tuple>
#include "rr_graph_obj_util.h"

/****************************************************************************
* Find the switches interconnecting two nodes
* Return a vector of switch ids
***************************************************************************/
std::vector<RRSwitchId> find_rr_graph_switches(const RRGraph& rr_graph,
const RRNodeId& from_node,
const RRNodeId& to_node) {
std::vector<RRSwitchId> switches;
std::vector<RREdgeId> edges = rr_graph.find_edges(from_node, to_node);
if (true == edges.empty()) {
/* edge is open, we return an empty vector of switches */
return switches;
}

/* Reach here, edge list is not empty, find switch id one by one
* and update the switch list
*/
for (auto edge : edges) {
switches.push_back(rr_graph.edge_switch(edge));
}

return switches;
}
Loading

0 comments on commit e0a212a

Please sign in to comment.