def yield_nodes(nodes): with progressbar_utils.ProgressBar(max_value=len(nodes)) as bar: for idx, node in enumerate(nodes): yield node if idx % 1024 == 0: bar.update(idx)
def import_graph_edges(conn, graph, node_mapping): # First yield existing edges print('{} Importing existing edges.'.format(now())) for edge in graph.edges: yield (edge.src_node, edge.sink_node, edge.switch_id, None) # Then yield edges from database. cur = conn.cursor() cur.execute("SELECT count() FROM graph_edge;" "") (num_edges, ) = cur.fetchone() get_tile_name = create_get_tile_name(conn) get_pip_wire_names = create_get_pip_wire_names(conn) switch_name_map = {} print('{} Importing edges from database.'.format(now())) with progressbar_utils.ProgressBar(max_value=num_edges) as bar: for idx, (src_graph_node, dest_graph_node, switch_pkey, phy_tile_pkey, pip_pkey, backward) in enumerate( cur.execute(""" SELECT src_graph_node_pkey, dest_graph_node_pkey, switch_pkey, phy_tile_pkey, pip_in_tile_pkey, backward FROM graph_edge; """)): if src_graph_node not in node_mapping: continue if dest_graph_node not in node_mapping: continue if pip_pkey is not None: tile_name = get_tile_name(phy_tile_pkey) src_net, dest_net = get_pip_wire_names(pip_pkey) if not backward: pip_name = '{}.{}.{}'.format(tile_name, dest_net, src_net) else: pip_name = '{}.{}.{}'.format(tile_name, src_net, dest_net) else: pip_name = None switch_id = get_switch_name(conn, graph, switch_name_map, switch_pkey) src_node = node_mapping[src_graph_node] sink_node = node_mapping[dest_graph_node] if pip_name is not None: yield (src_node, sink_node, switch_id, (('fasm_features', check_feature(pip_name)), )) else: yield (src_node, sink_node, switch_id, ()) if idx % 1024 == 0: bar.update(idx)
def classify_nodes(conn, get_switch_timing): write_cur = conn.cursor() # Nodes are NULL if they they only have either a site pin or 1 pip, but # nothing else. write_cur.execute( """ UPDATE node SET classification = ? WHERE (node.site_wire_pkey IS NULL AND node.number_pips <= 1) OR (node.site_wire_pkey IS NOT NULL AND node.number_pips == 0) ;""", (NodeClassification.NULL.value, )) write_cur.execute( """ UPDATE node SET classification = ? WHERE node.number_pips > 1 and node.site_wire_pkey IS NULL;""", (NodeClassification.CHANNEL.value, )) write_cur.execute( """ UPDATE node SET classification = ? WHERE node.number_pips > 1 and node.site_wire_pkey IS NOT NULL;""", (NodeClassification.EDGES_TO_CHANNEL.value, )) null_nodes = [] edges_to_channel = [] edge_with_mux = [] cur = conn.cursor() cur.execute(""" SELECT count(pkey) FROM node WHERE number_pips == 1 AND site_wire_pkey IS NOT NULL;""") num_nodes = cur.fetchone()[0] with progressbar_utils.ProgressBar(max_value=num_nodes) as bar: bar.update(0) for idx, (node, site_wire_pkey) in enumerate( cur.execute(""" SELECT pkey, site_wire_pkey FROM node WHERE number_pips == 1 AND site_wire_pkey IS NOT NULL;""")): bar.update(idx) write_cur.execute( """ WITH wire_in_node( wire_pkey, phy_tile_pkey, wire_in_tile_pkey ) AS ( SELECT wire.pkey, wire.phy_tile_pkey, wire.wire_in_tile_pkey FROM wire WHERE wire.node_pkey = ? ) SELECT pip_in_tile.pkey, pip_in_tile.src_wire_in_tile_pkey, pip_in_tile.dest_wire_in_tile_pkey, wire_in_node.wire_pkey, wire_in_node.wire_in_tile_pkey, wire_in_node.phy_tile_pkey FROM wire_in_node INNER JOIN pip_in_tile WHERE pip_in_tile.is_pseudo = 0 AND ( pip_in_tile.src_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey OR pip_in_tile.dest_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey) LIMIT 1; """, (node, )) (pip_pkey, src_wire_in_tile_pkey, dest_wire_in_tile_pkey, wire_in_node_pkey, wire_in_tile_pkey, phy_tile_pkey) = write_cur.fetchone() assert write_cur.fetchone() is None, node assert (wire_in_tile_pkey == src_wire_in_tile_pkey or wire_in_tile_pkey == dest_wire_in_tile_pkey), (wire_in_tile_pkey, pip_pkey) if src_wire_in_tile_pkey == wire_in_tile_pkey: other_wire = dest_wire_in_tile_pkey else: other_wire = src_wire_in_tile_pkey write_cur.execute( """ SELECT node_pkey FROM wire WHERE wire_in_tile_pkey = ? AND phy_tile_pkey = ?; """, (other_wire, phy_tile_pkey)) (other_node_pkey, ) = write_cur.fetchone() assert write_cur.fetchone() is None assert other_node_pkey is not None, (other_wire, phy_tile_pkey) write_cur.execute( """ SELECT site_wire_pkey, number_pips FROM node WHERE pkey = ?; """, (other_node_pkey, )) result = write_cur.fetchone() assert result is not None, other_node_pkey other_site_wire_pkey, other_number_pips = result assert write_cur.fetchone() is None if other_site_wire_pkey is not None and other_number_pips == 1: if src_wire_in_tile_pkey == wire_in_tile_pkey: src_wire_pkey = site_wire_pkey dest_wire_pkey = other_site_wire_pkey else: src_wire_pkey = other_site_wire_pkey dest_wire_pkey = site_wire_pkey edge_with_mux.append(((node, other_node_pkey), src_wire_pkey, dest_wire_pkey, pip_pkey)) elif other_site_wire_pkey is None and other_number_pips == 1: null_nodes.append(node) null_nodes.append(other_node_pkey) pass else: edges_to_channel.append(node) for nodes, src_wire_pkey, dest_wire_pkey, pip_pkey in progressbar_utils.progressbar( edge_with_mux): assert len(nodes) == 2 switch_pkey = check_edge_with_mux_timing(conn, get_switch_timing, src_wire_pkey, dest_wire_pkey, pip_pkey) write_cur.execute( """ UPDATE node SET classification = ? WHERE pkey IN (?, ?);""", (NodeClassification.EDGE_WITH_MUX.value, nodes[0], nodes[1])) write_cur.execute( """ INSERT INTO edge_with_mux(src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey, switch_pkey) VALUES (?, ?, ?, ?);""", (src_wire_pkey, dest_wire_pkey, pip_pkey, switch_pkey)) for node in progressbar_utils.progressbar(edges_to_channel): write_cur.execute( """ UPDATE node SET classification = ? WHERE pkey = ?;""", ( NodeClassification.EDGES_TO_CHANNEL.value, node, )) for null_node in progressbar_utils.progressbar(null_nodes): write_cur.execute( """ UPDATE node SET classification = ? WHERE pkey = ?;""", ( NodeClassification.NULL.value, null_node, )) write_cur.execute("CREATE INDEX node_type_index ON node(classification);") write_cur.connection.commit()
def import_graph_edges(conn, graph, extra_features, node_mapping): # First yield existing edges print('{} Importing existing edges.'.format(now())) for edge in graph.edges: yield (edge.src_node, edge.sink_node, edge.switch_id, None) # Then yield edges from database. cur = conn.cursor() cur.execute("SELECT count() FROM graph_edge;" "") (num_edges, ) = cur.fetchone() get_tile_name = create_get_tile_name(conn) get_pip_wire_names = create_get_pip_wire_names(conn) switch_name_map = {} nodes_set = set() print('{} Importing edges from database.'.format(now())) with progressbar_utils.ProgressBar(max_value=num_edges) as bar: for idx, (src_graph_node, dest_graph_node, switch_pkey, phy_tile_pkey, pip_pkey, backward) in enumerate( cur.execute(""" SELECT src_graph_node_pkey, dest_graph_node_pkey, switch_pkey, phy_tile_pkey, pip_in_tile_pkey, backward FROM graph_edge; """)): if src_graph_node not in node_mapping: continue if dest_graph_node not in node_mapping: continue src_node, src_node_type = node_mapping[src_graph_node] sink_node, sink_node_type = node_mapping[dest_graph_node] pin_node_types = [graph2.NodeType.IPIN, graph2.NodeType.OPIN] src_node_is_site_pin = src_node_type in pin_node_types sink_node_is_site_pin = sink_node_type in pin_node_types # It may happen that a same CHAN <-> PIN edge is generated and this is unaccepted # by VPR, as it allows only multiple edges between CHAN nodes. # If a src_node, sink_node CHAN <-> PIN pair has already an edge, no new edge gets # added if src_node_is_site_pin ^ sink_node_is_site_pin: if (src_node, sink_node) in nodes_set: continue else: nodes_set.add((src_node, sink_node)) if pip_pkey is not None: tile_name = get_tile_name(phy_tile_pkey) src_net, dest_net = get_pip_wire_names(pip_pkey) if not backward: pip_name = '{}.{}.{}'.format(tile_name, dest_net, src_net) else: pip_name = '{}.{}.{}'.format(tile_name, src_net, dest_net) else: pip_name = None switch_id = get_switch_name(conn, graph, switch_name_map, switch_pkey) if pip_name is not None: feature = check_feature(extra_features, pip_name) if feature: yield (src_node, sink_node, switch_id, (('fasm_features', feature), )) else: yield (src_node, sink_node, switch_id, ()) else: yield (src_node, sink_node, switch_id, ()) if idx % 1024 == 0: bar.update(idx)
def form_tracks(conn): cur = conn.cursor() cur.execute('SELECT count(pkey) FROM node WHERE classification == ?;', (NodeClassification.CHANNEL.value, )) num_nodes = cur.fetchone()[0] tracks_to_insert = [] with progressbar_utils.ProgressBar(max_value=num_nodes) as bar: bar.update(0) cur2 = conn.cursor() for idx, (node, ) in enumerate( cur.execute( """ SELECT pkey FROM node WHERE classification == ?; """, (NodeClassification.CHANNEL.value, ))): bar.update(idx) unique_pos = set() for wire_pkey, grid_x, grid_y in cur2.execute( """ WITH wires_from_node(wire_pkey, tile_pkey) AS ( SELECT pkey, tile_pkey FROM wire WHERE node_pkey = ? AND tile_pkey IS NOT NULL ) SELECT wires_from_node.wire_pkey, tile.grid_x, tile.grid_y FROM tile INNER JOIN wires_from_node ON tile.pkey = wires_from_node.tile_pkey; """, (node, )): unique_pos.add((grid_x, grid_y)) tracks_to_insert.append(create_track(node, unique_pos)) # Create constant tracks vcc_track_to_insert, gnd_track_to_insert = create_constant_tracks(conn) vcc_idx = len(tracks_to_insert) tracks_to_insert.append(vcc_track_to_insert) gnd_idx = len(tracks_to_insert) tracks_to_insert.append(gnd_track_to_insert) track_pkeys = insert_tracks(conn, tracks_to_insert) vcc_track_pkey = track_pkeys[vcc_idx] gnd_track_pkey = track_pkeys[gnd_idx] write_cur = conn.cursor() write_cur.execute( """ INSERT INTO constant_sources(vcc_track_pkey, gnd_track_pkey) VALUES (?, ?) """, ( vcc_track_pkey, gnd_track_pkey, )) conn.commit() connect_hardpins_to_constant_network(conn, vcc_track_pkey, gnd_track_pkey)