minor fixing in printing the rr_node stats

This commit is contained in:
tangxifan 2019-06-27 16:34:21 -06:00
parent 8edd85c9fc
commit 15c536e9b4
3 changed files with 102 additions and 92 deletions

View File

@ -38,6 +38,7 @@
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <vector>
#include <algorithm>
@ -407,3 +408,101 @@ short get_track_rr_node_end_track_id(const t_rr_node* track_rr_node) {
return track_rr_node->track_ids.front();
}
/************************************************************************
* Print statistics of a rr_graph
* 1. We print number of nodes by types
* 2. Print the number of edges
************************************************************************/
void print_rr_graph_stats(const t_rr_graph& rr_graph) {
/* Print number of nodes */
vpr_printf(TIO_MESSAGE_INFO, "Statistics on number of RR nodes (by node type): \n");
/* Count the number of nodes */
std::vector<size_t> num_nodes_per_type;
num_nodes_per_type.resize(NUM_RR_TYPES);
num_nodes_per_type.assign(NUM_RR_TYPES, 0);
for (int inode = 0; inode < rr_graph.num_rr_nodes; ++inode) {
num_nodes_per_type[rr_graph.rr_node[inode].type]++;
}
/* Get the largest string size of rr_node_typename */
size_t max_str_typename = 0;
for (int type = 0; type < NUM_RR_TYPES; ++type) {
max_str_typename = std::max(max_str_typename, strlen(rr_node_typename[type]));
}
/* Constant strings */
char* type_str = " Type ";
char* total_str = " Total ";
char* node_str = " No. of nodes ";
char* edge_str = " No. of edges ";
/* Count the number of characters per line:
* we check the string length of each node type
* Then we plus two reserved strings "type" and "total"
*/
size_t num_char_per_line = 0;
for (int type = 0; type < NUM_RR_TYPES; ++type) {
num_char_per_line += 6 + max_str_typename;
}
num_char_per_line += strlen(type_str);
num_char_per_line += strlen(total_str);
/* Print splitter */
for (size_t ichar = 0; ichar < num_char_per_line; ++ichar) {
vpr_printf(TIO_MESSAGE_INFO, "-");
}
vpr_printf(TIO_MESSAGE_INFO, "\n");
/* Print node type */
vpr_printf(TIO_MESSAGE_INFO, "%s", type_str);
for (int type = 0; type < NUM_RR_TYPES; ++type) {
vpr_printf(TIO_MESSAGE_INFO, " %s ", rr_node_typename[type]);
}
vpr_printf(TIO_MESSAGE_INFO, "%s", total_str);
vpr_printf(TIO_MESSAGE_INFO, "\n");
/* Print node numbers */
int total_num_nodes = 0;
vpr_printf(TIO_MESSAGE_INFO, "%s", node_str);
for (int type = 0; type < NUM_RR_TYPES; ++type) {
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_nodes_per_type[type]);
total_num_nodes += num_nodes_per_type[type];
}
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", rr_graph.num_rr_nodes);
vpr_printf(TIO_MESSAGE_INFO, "\n");
/* Check we have the same number as stated in rr_graph */
assert (total_num_nodes == rr_graph.num_rr_nodes);
/* Count the number of edges */
size_t num_edges = 0;
std::vector<size_t> num_edges_per_type;
num_edges_per_type.resize(NUM_RR_TYPES);
num_edges_per_type.assign(NUM_RR_TYPES, 0);
for (int inode = 0; inode < rr_graph.num_rr_nodes; ++inode) {
num_edges_per_type[rr_graph.rr_node[inode].type] += rr_graph.rr_node[inode].num_edges;
}
for (int inode = 0; inode < rr_graph.num_rr_nodes; ++inode) {
num_edges += rr_graph.rr_node[inode].num_edges;
}
/* Print number of edges */
vpr_printf(TIO_MESSAGE_INFO, "%s", edge_str);
for (int type = 0; type < NUM_RR_TYPES; ++type) {
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_edges_per_type[type]);
}
vpr_printf(TIO_MESSAGE_INFO, " %10lu ", num_edges);
vpr_printf(TIO_MESSAGE_INFO, "\n");
/* Print splitter */
for (size_t ichar = 0; ichar < num_char_per_line; ++ichar) {
vpr_printf(TIO_MESSAGE_INFO, "-");
}
vpr_printf(TIO_MESSAGE_INFO, "\n");
return;
}

View File

@ -41,5 +41,7 @@ DeviceCoordinator get_track_rr_node_end_coordinator(const t_rr_node* track_rr_no
short get_track_rr_node_end_track_id(const t_rr_node* track_rr_node);
void print_rr_graph_stats(const t_rr_graph& rr_graph);
#endif

View File

@ -186,14 +186,6 @@ std::vector<size_t> estimate_num_rr_nodes_per_type(const DeviceCoordinator& devi
}
}
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu SOURCE nodes.\n", num_rr_nodes_per_type[SOURCE]);
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu SINK nodes.\n", num_rr_nodes_per_type[SINK] );
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu OPIN nodes.\n", num_rr_nodes_per_type[OPIN] );
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu IPIN nodes.\n", num_rr_nodes_per_type[IPIN] );
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu CHANX nodes.\n", num_rr_nodes_per_type[CHANY] );
vpr_printf(TIO_MESSAGE_INFO, "Estimate %lu CHANY nodes.\n", num_rr_nodes_per_type[CHANY] );
return num_rr_nodes_per_type;
}
@ -869,75 +861,6 @@ void clear_rr_graph_driver_switch(const t_rr_graph* rr_graph) {
return;
}
/************************************************************************
* Sort the edges of rr_nodes by node type and ptc_num
* 1. node type priority: (follow the index of t_rr_type
* SOURCE, SINK, IPIN, OPIN, CHANX, CHANY, INTRA_CLUSTER_EDGE, NUM_RR_TYPES
* 2. node ptc_num (feature number): from low to high
* The ptc_num only matters when two nodes have the same type
***********************************************************************/
static
void sort_rr_graph_edges(t_rr_graph* rr_graph) {
for (int inode = 0; inode < rr_graph->num_rr_nodes; ++inode) {
/* Create a copy of the edges and switches of this node */
std::vector<int> sorted_edges;
std::vector<short> sorted_switches;
/* Ensure a clean start */
sorted_edges.clear();
sorted_switches.clear();
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
for (int iedge = 0; iedge < rr_graph->rr_node[inode].num_edges; ++iedge) {
/* For blank edges: directly push_back */
if (0 == sorted_edges.size()) {
sorted_edges.push_back(rr_graph->rr_node[inode].edges[iedge]);
sorted_switches.push_back(rr_graph->rr_node[inode].switches[iedge]);
continue;
}
/* Start sorting since the edges are not empty */
size_t insert_pos = sorted_edges.size(); /* the pos to insert. By default, it is the last element */
size_t i_to_node = rr_graph->rr_node[inode].edges[iedge]; /* node_id of the edge connects to */
for (size_t jedge = 0; jedge < sorted_edges.size(); ++jedge) {
size_t j_to_node = sorted_edges[jedge];
/* Sort by node_type and ptc_num */
if (rr_graph->rr_node[i_to_node].type < rr_graph->rr_node[j_to_node].type) {
/* iedge should be ahead of jedge */
insert_pos = jedge;
break; /* least type should stay in the front of the vector */
} else if (rr_graph->rr_node[i_to_node].type == rr_graph->rr_node[j_to_node].type) {
/* Special as track_ids vary, we consider the last track_ids for those node has the same type as inode */
if (rr_graph->rr_node[i_to_node].type == rr_graph->rr_node[inode].type) {
if (get_track_rr_node_end_track_id(&(rr_graph->rr_node[i_to_node]))
< get_track_rr_node_end_track_id(&(rr_graph->rr_node[j_to_node])) ) {
insert_pos = jedge;
break; /* least type should stay in the front of the vector */
}
} else if (rr_graph->rr_node[i_to_node].ptc_num < rr_graph->rr_node[j_to_node].ptc_num) {
/* Now a lower ptc_num will win */
insert_pos = jedge;
break; /* least type should stay in the front of the vector */
}
}
}
/* We find the position, inserted to the vector */
sorted_edges.insert(sorted_edges.begin() + insert_pos, i_to_node);
sorted_switches.insert(sorted_switches.begin() + insert_pos, rr_graph->rr_node[inode].switches[iedge]);
}
/* Overwrite the edges and switches with sorted numbers */
for (size_t iedge = 0; iedge < sorted_edges.size(); ++iedge) {
rr_graph->rr_node[inode].edges[iedge] = sorted_edges[iedge];
}
for (size_t iedge = 0; iedge < sorted_switches.size(); ++iedge) {
rr_graph->rr_node[inode].switches[iedge] = sorted_switches[iedge];
}
}
return;
}
/************************************************************************
* Main function of this file
* Builder for a detailed uni-directional tileable rr_graph
@ -1111,21 +1034,7 @@ void build_tileable_unidir_rr_graph(INP const int L_num_types,
build_rr_graph_direct_connections(&rr_graph, device_size, grids, delayless_switch,
num_directs, directs, clb_to_clb_directs);
/************************************************************************
* 6.3 Sort the edges of rr_nodes by node type and ptc_num
* During the edge construction, edges are out of orders,
* which are not easy to build tileable routing architecture
* This step can be skipped when you do not use FPGA X2P
***********************************************************************/
//sort_rr_graph_edges(&rr_graph);
size_t num_edges = 0;
for (int inode = 0; inode < rr_graph.num_rr_nodes; ++inode) {
num_edges += rr_graph.rr_node[inode].num_edges;
}
vpr_printf(TIO_MESSAGE_INFO,
"%lu edges of RR graph built.\n",
num_edges);
print_rr_graph_stats(rr_graph);
/* Clear driver switches of the rr_graph */
clear_rr_graph_driver_switch(&rr_graph);