add advanced check codes for lb_rr_graph
This commit is contained in:
parent
ed5d83178f
commit
d8ab5536e1
|
@ -10,6 +10,7 @@
|
|||
#include "pb_type_utils.h"
|
||||
|
||||
#include "build_physical_lb_rr_graph.h"
|
||||
#include "check_lb_rr_graph.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
@ -399,6 +400,9 @@ void build_physical_lb_rr_graphs(const DeviceContext& device_ctx,
|
|||
if (false == lb_rr_graph.validate()) {
|
||||
exit(1);
|
||||
}
|
||||
if (false == check_lb_rr_graph(lb_rr_graph)) {
|
||||
exit(1);
|
||||
}
|
||||
VTR_LOGV(verbose,
|
||||
"Check routing resource graph for logical tile passed\n");
|
||||
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
#include <map>
|
||||
|
||||
#include "vtr_log.h"
|
||||
|
||||
#include "lb_rr_graph_utils.h"
|
||||
#include "check_lb_rr_graph.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/***********************************************************************
|
||||
* This function aims at checking any duplicated edges (with same EdgeId)
|
||||
* of a given node.
|
||||
* We will walkthrough the input edges of a node and see if there is any duplication
|
||||
**********************************************************************/
|
||||
static bool check_lb_rr_graph_node_duplicated_edges(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& node) {
|
||||
bool no_duplication = true;
|
||||
|
||||
/* Create a map for each input edge */
|
||||
std::map<const t_mode*, std::map<LbRREdgeId, size_t>> edge_counter;
|
||||
|
||||
/* Check each input edges */
|
||||
for (const auto edge : lb_rr_graph.node_in_edges(node)) {
|
||||
if (nullptr == lb_rr_graph.edge_mode(edge)) {
|
||||
continue;
|
||||
}
|
||||
auto result = edge_counter[lb_rr_graph.edge_mode(edge)].insert(std::pair<LbRREdgeId, size_t>(edge, 1));
|
||||
if (false == result.second) {
|
||||
result.first->second++;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& edge_mode : edge_counter) {
|
||||
for (auto& elem : edge_mode.second) {
|
||||
if (elem.second > 1) {
|
||||
/* Reach here it means we find some duplicated edges and report errors */
|
||||
/* Print a warning! */
|
||||
VTR_LOG_WARN("Node %d has duplicated input edges (id = %d)!\n",
|
||||
size_t(node), size_t(elem.first));
|
||||
print_lb_rr_node(lb_rr_graph, node);
|
||||
no_duplication = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return no_duplication;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Check the whole Routing Resource Graph
|
||||
* identify and report any duplicated edges between two nodes
|
||||
**********************************************************************/
|
||||
static bool check_lb_rr_graph_duplicated_edges(const LbRRGraph& lb_rr_graph) {
|
||||
bool no_duplication = true;
|
||||
/* For each node:
|
||||
* Search input edges, see there are two edges with same id or address
|
||||
*/
|
||||
for (const auto& node : lb_rr_graph.nodes()) {
|
||||
if (false == check_lb_rr_graph_node_duplicated_edges(lb_rr_graph, node)) {
|
||||
no_duplication = false;
|
||||
}
|
||||
}
|
||||
|
||||
return no_duplication;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Identify and report any dangling node (nodes without any fan-in or fan-out)
|
||||
* in the LbRRGraph
|
||||
**********************************************************************/
|
||||
static bool check_lb_rr_graph_dangling_nodes(const LbRRGraph& lb_rr_graph) {
|
||||
bool no_dangling = true;
|
||||
/* For each node:
|
||||
* check if the number of input edges and output edges are both 0
|
||||
* If so, this is a dangling nodes and report
|
||||
*/
|
||||
for (auto node : lb_rr_graph.nodes()) {
|
||||
if ((0 == lb_rr_graph.node_in_edges(node).size())
|
||||
&& (0 == lb_rr_graph.node_out_edges(node).size())) {
|
||||
/* Print a warning! */
|
||||
VTR_LOG_WARN("Node %s is dangling (zero fan-in and zero fan-out)!\n",
|
||||
node);
|
||||
VTR_LOG_WARN("Node details for debugging:\n");
|
||||
print_lb_rr_node(lb_rr_graph, node);
|
||||
no_dangling = false;
|
||||
}
|
||||
}
|
||||
|
||||
return no_dangling;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* check if all the source nodes are in the right condition:
|
||||
* 1. zero fan-in and non-zero fanout
|
||||
**********************************************************************/
|
||||
static bool check_lb_rr_graph_source_nodes(const LbRRGraph& lb_rr_graph) {
|
||||
bool invalid_sources = false;
|
||||
/* For each node:
|
||||
* check if the number of input edges and output edges are both 0
|
||||
* If so, this is a dangling nodes and report
|
||||
*/
|
||||
for (auto node : lb_rr_graph.nodes()) {
|
||||
/* Pass nodes whose types are not LB_SOURCE */
|
||||
if (LB_SOURCE != lb_rr_graph.node_type(node)) {
|
||||
continue;
|
||||
}
|
||||
if ((0 != lb_rr_graph.node_in_edges(node).size())
|
||||
|| (0 == lb_rr_graph.node_out_edges(node).size())) {
|
||||
/* Print a warning! */
|
||||
VTR_LOG_WARN("Source node %d is invalid (should have zero fan-in and non-zero fan-out)!\n",
|
||||
size_t(node));
|
||||
VTR_LOG_WARN("Node details for debugging:\n");
|
||||
print_lb_rr_node(lb_rr_graph, node);
|
||||
invalid_sources = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !invalid_sources;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* check if all the sink nodes are in the right condition:
|
||||
* 1. non-zero fan-in and zero fanout
|
||||
**********************************************************************/
|
||||
static bool check_lb_rr_graph_sink_nodes(const LbRRGraph& lb_rr_graph) {
|
||||
bool invalid_sinks = false;
|
||||
/* For each node:
|
||||
* check if the number of input edges and output edges are both 0
|
||||
* If so, this is a dangling nodes and report
|
||||
*/
|
||||
for (auto node : lb_rr_graph.nodes()) {
|
||||
/* Pass nodes whose types are not LB_SINK */
|
||||
if (LB_SINK != lb_rr_graph.node_type(node)) {
|
||||
continue;
|
||||
}
|
||||
if ((0 == lb_rr_graph.node_in_edges(node).size())
|
||||
|| (0 != lb_rr_graph.node_out_edges(node).size())) {
|
||||
/* Print a warning! */
|
||||
VTR_LOG_WARN("Sink node %s is invalid (should have non-zero fan-in and zero fan-out)!\n",
|
||||
node);
|
||||
VTR_LOG_WARN("Node details for debugging:\n");
|
||||
print_lb_rr_node(lb_rr_graph, node);
|
||||
invalid_sinks = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !invalid_sinks;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* This is an advanced checker for LbRRGraph object
|
||||
* Note that the checker try to report as many problems as it can.
|
||||
* The problems may cause routing efficiency or even failures, depending
|
||||
* on routing algorithms.
|
||||
* It is strongly suggested to run this sanitizer before conducting
|
||||
* routing algorithms
|
||||
*
|
||||
* For those who will develop customized lb_rr_graphs and routers:
|
||||
* On the other hand, it is suggested that developers to create their
|
||||
* own checking function for the lb_rr_graph, to guarantee their routers
|
||||
* will work properly.
|
||||
**********************************************************************/
|
||||
bool check_lb_rr_graph(const LbRRGraph& lb_rr_graph) {
|
||||
size_t num_err = 0;
|
||||
|
||||
if (false == check_lb_rr_graph_duplicated_edges(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking duplicated edges !\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (false == check_lb_rr_graph_dangling_nodes(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking dangling nodes !\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (false == check_lb_rr_graph_source_nodes(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking source nodes!\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (false == check_lb_rr_graph_sink_nodes(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking sink nodes!\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (false == check_lb_rr_graph_source_nodes(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking source nodes!\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
if (false == check_lb_rr_graph_sink_nodes(lb_rr_graph)) {
|
||||
VTR_LOG_WARN("Fail in checking sink nodes!\n");
|
||||
num_err++;
|
||||
}
|
||||
|
||||
/* Error out if there is any fatal errors found */
|
||||
if (0 < num_err) {
|
||||
VTR_LOG_WARN("Checked Logical tile Routing Resource graph with %d errors !\n",
|
||||
num_err);
|
||||
}
|
||||
|
||||
return (0 == num_err);
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef CHECK_LB_RR_GRAPH_H
|
||||
#define CHECK_LB_RR_GRAPH_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "lb_rr_graph.h"
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
bool check_lb_rr_graph(const LbRRGraph& rr_graph);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -57,4 +57,17 @@ std::string describe_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
|||
return description;
|
||||
}
|
||||
|
||||
/* This function aims to print basic information about a node */
|
||||
void print_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& node) {
|
||||
VTR_LOG("Node id: %d\n", size_t(node));
|
||||
VTR_LOG("Node type: %s\n", lb_rr_type_str[lb_rr_graph.node_type(node)]);
|
||||
VTR_LOG("Node capacity: %d\n", lb_rr_graph.node_capacity(node));
|
||||
VTR_LOG("Node pb_graph_pin: %s\n", lb_rr_graph.node_pb_graph_pin(node)->to_string().c_str());
|
||||
VTR_LOG("Node intrinsic_cost: %f\n", lb_rr_graph.node_intrinsic_cost(node));
|
||||
VTR_LOG("Node num in_edges: %ld\n", lb_rr_graph.node_in_edges(node).size());
|
||||
VTR_LOG("Node num out_edges: %ld\n", lb_rr_graph.node_out_edges(node).size());
|
||||
}
|
||||
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -17,6 +17,9 @@ namespace openfpga {
|
|||
std::string describe_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& inode);
|
||||
|
||||
void print_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& node);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue