blob: aca50d8717f6d80d02155e793ad7d19f63338410 [file] [log] [blame]
#!/usr/bin/env python3
import argparse
import re
from lib.rr_graph import graph
def inaccessible_node_ids(forward_connections, node_id, target_node_ids):
"""
Takes a mapping of forward connectionso from nodes, a starting `node_id` and
a set of all the target node ids for which we want to check routability.
Returns a set of all the target node ids that are not accessible from `node_id`.
"""
layer = [node_id]
visited = set()
layer_index = 0
while layer:
layer_index += 1
new_layer = set()
for this_node_id in layer:
new_layer |= forward_connections[this_node_id]
new_layer -= visited
visited |= new_layer
layer = new_layer
return target_node_ids - visited
def routing_graph_to_dictionary(routing_graph):
edge_map = routing_graph._ids_map(graph.RoutingEdge)
edges_by_node = routing_graph.edges_for_allnodes()
dict_graph = {}
for node in routing_graph._xml_parent(graph.RoutingNode):
node_id = int(node.get('id'))
dest_ids = set()
for edge_id in edges_by_node[node_id]:
edge = edge_map[edge_id]
if int(edge.get('src_node')) == node_id:
dest_ids.add(int(edge.get('sink_node')))
dict_graph[node_id] = dest_ids
return dict_graph
def filter_nodes(all_node_ids, g, f):
node_map = g.routing._ids_map(graph.RoutingNode)
f = re.compile(f)
node_ids = set()
for nid in all_node_ids:
node = node_map[nid]
n = graph.RoutingGraphPrinter.node(node, g.block_grid)
if f.search(n):
print("Filtering out ", n)
continue
node_ids.add(nid)
return node_ids
def inaccessible_sink_node_ids_by_source_node_id(g, filter=""):
"""
Returns a dictionary that maps source node ids to sets of sink node ids
which are inaccessible to them.
If a source node id can access all sink nodes it is not present in the
returned dictionary.
"""
routing_graph = g.routing
# First convert the graph to a dictionary.
cyclic_graph = routing_graph_to_dictionary(routing_graph)
all_source_node_ids = set(
[
int(node.get('id'))
for node in routing_graph._xml_parent(graph.RoutingNode)
if node.get('type') == 'SOURCE'
]
)
source_node_ids = filter_nodes(all_source_node_ids, g, filter)
all_sink_node_ids = set(
[
int(node.get('id'))
for node in routing_graph._xml_parent(graph.RoutingNode)
if node.get('type') == 'SINK'
]
)
sink_node_ids = filter_nodes(all_sink_node_ids, g, filter)
inaccessible_by_source_node = {}
total = len(source_node_ids)
for index, source_node_id in enumerate(source_node_ids):
inaccessible_ids = inaccessible_node_ids(
cyclic_graph, source_node_id, target_node_ids=sink_node_ids
)
if inaccessible_ids:
inaccessible_by_source_node[source_node_id] = inaccessible_ids
if index % 100 == 0:
print('Checked {}/{} source nodes'.format(index, total))
return inaccessible_by_source_node
def check_graph(rr_graph_file, filter):
'''
Check that the rr_graph has connections from all SOURCE nodes to all SINK nodes.
'''
print('Loading the routing graph file')
g = graph.Graph(rr_graph_file, verbose=True, clear_fabric=False)
routing_graph = g.routing
print('Checking if all source nodes connect to all sink nodes.')
inaccessible_nodes = inaccessible_sink_node_ids_by_source_node_id(
g, filter
)
if inaccessible_nodes:
print('FAIL')
node_map = routing_graph._ids_map(graph.RoutingNode)
for source_id, sink_ids in inaccessible_nodes.items():
source_node = graph.RoutingGraphPrinter.node(
node_map[source_id], g.block_grid
)
sink_nodes = [
graph.RoutingGraphPrinter.node(node_map[i], g.block_grid)
for i in sink_ids
]
print('Node {} does not connect to nodes:.'.format(source_node))
for n in sink_nodes:
print(' ', n)
print()
import pdb
pdb.set_trace()
else:
print('SUCCESS')
def main():
parser = argparse.ArgumentParser()
parser.add_argument('rr_graph_file', type=str)
parser.add_argument('filter', type=str)
args = parser.parse_args()
check_graph(args.rr_graph_file, args.filter)
if __name__ == '__main__':
main()