def import_tracks(conn, alive_tracks, node_mapping, graph, segment_id): c2 = conn.cursor() for (graph_node_pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc) in c2.execute(""" SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc FROM graph_node WHERE track_pkey IS NOT NULL;"""): if track_pkey not in alive_tracks: continue node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: direction = 'X' x_low = max(x_low, 1) elif node_type == graph2.NodeType.CHANY: direction = 'Y' y_low = max(y_low, 1) else: assert False, node_type track = tracks.Track( direction=direction, x_low=x_low, x_high=x_high, y_low=y_low, y_high=y_high, ) assert graph_node_pkey not in node_mapping node_mapping[graph_node_pkey] = graph.add_track(track=track, segment_id=segment_id, ptc=ptc)
def get_track_model(conn, track_pkey): assert track_pkey is not None track_list = [] track_nodes = [] c2 = conn.cursor() graph_node_pkey = {} for idx, (pkey, graph_node_type, x_low, x_high, y_low, y_high) in enumerate( c2.execute( """ SELECT pkey, graph_node_type, x_low, x_high, y_low, y_high FROM graph_node WHERE track_pkey = ?""", (track_pkey, ))): node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: direction = 'X' elif node_type == graph2.NodeType.CHANY: direction = 'Y' graph_node_pkey[pkey] = idx track_nodes.append(pkey) track_list.append( tracks.Track(direction=direction, x_low=x_low, x_high=x_high, y_low=y_low, y_high=y_high)) track_connections = set() for src_graph_node_pkey, dest_graph_node_pkey in c2.execute( """ SELECT src_graph_node_pkey, dest_graph_node_pkey FROM graph_edge WHERE track_pkey = ?""", (track_pkey, )): src_idx = graph_node_pkey[src_graph_node_pkey] dest_idx = graph_node_pkey[dest_graph_node_pkey] track_connections.add(tuple(sorted((src_idx, dest_idx)))) tracks_model = tracks.Tracks(track_list, list(track_connections)) return tracks_model, track_nodes
def import_dummy_tracks(conn, graph, segment_id): cur = conn.cursor() num_dummy = 0 for (graph_node_pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc) in cur.execute( """ SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc FROM graph_node WHERE (graph_node_type = ? or graph_node_type = ?) and capacity = 0;""", (graph2.NodeType.CHANX.value, graph2.NodeType.CHANY.value)): node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: direction = 'X' x_low = x_low elif node_type == graph2.NodeType.CHANY: direction = 'Y' y_low = y_low else: assert False, node_type track = tracks.Track( direction=direction, x_low=x_low, x_high=x_high, y_low=y_low, y_high=y_high, ) graph.add_track(track=track, segment_id=segment_id, capacity=0, ptc=ptc) num_dummy += 1 return num_dummy
def build_channels(conn, pool, active_tracks): c = conn.cursor() xs = [] ys = [] x_tracks = {} y_tracks = {} for pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high in c.execute( """ SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high FROM graph_node WHERE track_pkey IS NOT NULL;"""): if track_pkey not in active_tracks: continue x_low = max(x_low, 1) y_low = max(y_low, 1) xs.append(x_low) xs.append(x_high) ys.append(y_low) ys.append(y_high) node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: assert y_low == y_high if y_low not in x_tracks: x_tracks[y_low] = [] x_tracks[y_low].append((x_low, x_high, pkey)) elif node_type == graph2.NodeType.CHANY: assert x_low == x_high if x_low not in y_tracks: y_tracks[x_low] = [] y_tracks[x_low].append((y_low, y_high, pkey)) else: assert False, node_type x_list = [] y_list = [] x_channel_models = {} y_channel_models = {} for y in x_tracks: x_channel_models[y] = pool.apply_async(graph2.process_track, (x_tracks[y], )) for x in y_tracks: y_channel_models[x] = pool.apply_async(graph2.process_track, (y_tracks[x], )) c.execute("""BEGIN EXCLUSIVE TRANSACTION;""") for y in progressbar.progressbar(range(max(x_tracks) + 1)): if y in x_tracks: x_channel_models[y] = x_channel_models[y].get() x_list.append(len(x_channel_models[y].trees)) for idx, tree in enumerate(x_channel_models[y].trees): for i in tree: c.execute('UPDATE graph_node SET ptc = ? WHERE pkey = ?;', (idx, i[2])) else: x_list.append(0) for x in progressbar.progressbar(range(max(y_tracks) + 1)): if x in y_tracks: y_channel_models[x] = y_channel_models[x].get() y_list.append(len(y_channel_models[x].trees)) for idx, tree in enumerate(y_channel_models[x].trees): for i in tree: c.execute('UPDATE graph_node SET ptc = ? WHERE pkey = ?;', (idx, i[2])) else: y_list.append(0) x_min = min(xs) y_min = min(ys) x_max = max(xs) y_max = max(ys) num_padding = 0 capacity = 0 for chan, channel_model in x_channel_models.items(): for ptc, start, end in channel_model.fill_empty(x_min, x_max): assert ptc < x_list[chan] num_padding += 1 c.execute( """ INSERT INTO graph_node( graph_node_type, x_low, x_high, y_low, y_high, capacity, ptc ) VALUES (?, ?, ?, ?, ?, ?, ?); """, (graph2.NodeType.CHANX.value, start, end, chan, chan, capacity, ptc)) for chan, channel_model in y_channel_models.items(): for ptc, start, end in channel_model.fill_empty(y_min, y_max): assert ptc < y_list[chan] num_padding += 1 c.execute( """ INSERT INTO graph_node( graph_node_type, x_low, x_high, y_low, y_high, capacity, ptc ) VALUES (?, ?, ?, ?, ?, ?, ?); """, (graph2.NodeType.CHANY.value, chan, chan, start, end, capacity, ptc)) print('Number padding nodes {}'.format(num_padding)) c.execute( """ INSERT INTO channel(chan_width_max, x_min, x_max, y_min, y_max) VALUES (?, ?, ?, ?, ?);""", (max(max(x_list), max(y_list)), x_min, x_max, y_min, y_max)) for idx, info in enumerate(x_list): c.execute(""" INSERT INTO x_list(idx, info) VALUES (?, ?);""", (idx, info)) for idx, info in enumerate(y_list): c.execute(""" INSERT INTO y_list(idx, info) VALUES (?, ?);""", (idx, info)) c.execute("""COMMIT TRANSACTION;""")
def find_connector(wire_pkey, node_pkey): """ Finds Connector for a wire and node in the database. Args: wire_pkey (int): Primary key into wire table of target wire node_pkey (int): Primary key into node table of parent node of specified wire. Returns: None if wire is disconnected, otherwise returns Connector objet. """ # Find all graph_nodes for this node. c.execute( """ SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high FROM graph_node WHERE node_pkey = ?;""", (node_pkey, )) graph_nodes = c.fetchall() # If there are no graph nodes, this wire is likely disconnected. if len(graph_nodes) == 0: return # If this is a track (e.g. track_pkey is not NULL), then verify # all graph_nodes for the specified node belong to the same track, # and then retrieved and return the connector for the track. track_pkey = graph_nodes[0][1] if track_pkey is not None: for node in graph_nodes: assert node[1] == track_pkey return Connector(tracks=get_track_model(conn, track_pkey)) # This is not a track, so it must be a site pin. Make sure the # graph_nodes share a type and verify that it is in fact a site pin. node_type = graph2.NodeType(graph_nodes[0][2]) for node in graph_nodes: assert node_type == graph2.NodeType(node[2]) assert node_type in [graph2.NodeType.IPIN, graph2.NodeType.OPIN] if node_type == graph2.NodeType.IPIN: site_pin_direction = SitePinDirection.IN elif node_type == graph2.NodeType.OPIN: site_pin_direction = SitePinDirection.OUT else: assert False, node_type # Build the edge_map (map of edge direction to graph node). c.execute( """ SELECT top_graph_node_pkey, bottom_graph_node_pkey, left_graph_node_pkey, right_graph_node_pkey FROM wire WHERE node_pkey = ?;""", (node_pkey, )) all_graph_node_pkeys = c.fetchall() graph_node_pkeys = None for keys in all_graph_node_pkeys: if any(keys): assert graph_node_pkeys is None graph_node_pkeys = keys # This wire may not have an connections, if so return now. if graph_node_pkeys is None: return edge_map = {} for edge, graph_node in zip( ( tracks.Direction.TOP, tracks.Direction.BOTTOM, tracks.Direction.LEFT, tracks.Direction.RIGHT, ), graph_node_pkeys, ): if graph_node is not None: edge_map[edge] = graph_node assert len(edge_map) == len(graph_nodes), (edge_map, graph_node_pkeys, graph_nodes) # Make sure that all graph nodes for this wire are in the edge_map # and at the same grid coordinate. x = graph_nodes[0][3] y = graph_nodes[0][5] for pkey, _, _, x_low, x_high, y_low, y_high in graph_nodes: assert x == x_low, (wire_pkey, node_pkey, x, x_low, x_high) assert x == x_high, (wire_pkey, node_pkey, x, x_low, x_high) assert y == y_low, (wire_pkey, node_pkey, y, y_low, y_high) assert y == y_high, (wire_pkey, node_pkey, y, y_low, y_high) assert pkey in edge_map.values(), (pkey, edge_map) return Connector(pins=Pins( edge_map=edge_map, x=x, y=y, site_pin_direction=site_pin_direction, ))
def import_tracks(conn, alive_tracks, node_mapping, graph, default_segment_id): cur = conn.cursor() cur2 = conn.cursor() for (graph_node_pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc, capacitance, resistance) in cur.execute(""" SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high, ptc, capacitance, resistance FROM graph_node WHERE track_pkey IS NOT NULL;"""): if track_pkey not in alive_tracks: continue cur2.execute( """ SELECT name FROM segment WHERE pkey = ( SELECT segment_pkey FROM track WHERE pkey = ? )""", (track_pkey, )) result = cur2.fetchone() if result is not None: segment_name = result[0] segment_id = graph.get_segment_id_from_name(segment_name) else: segment_id = default_segment_id node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: direction = 'X' x_low = max(x_low, 1) elif node_type == graph2.NodeType.CHANY: direction = 'Y' y_low = max(y_low, 1) else: assert False, node_type canonical_loc = None cur2.execute( """ SELECT grid_x, grid_y FROM phy_tile WHERE pkey = ( SELECT canon_phy_tile_pkey FROM track WHERE pkey = ? )""", (track_pkey, )) result = cur2.fetchone() if result: canonical_loc = graph2.CanonicalLoc(x=result[0], y=result[1]) track = tracks.Track( direction=direction, x_low=x_low, x_high=x_high, y_low=y_low, y_high=y_high, ) assert graph_node_pkey not in node_mapping node_mapping[graph_node_pkey] = graph.add_track( track=track, segment_id=segment_id, ptc=ptc, timing=graph2.NodeTiming( r=resistance, c=capacitance, ), canonical_loc=canonical_loc)
def build_channels(conn, pool, active_tracks): write_cur = conn.cursor() xs = [] ys = [] x_tracks = {} y_tracks = {} for pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high in write_cur.execute( """ SELECT pkey, track_pkey, graph_node_type, x_low, x_high, y_low, y_high FROM graph_node WHERE track_pkey IS NOT NULL;"""): if track_pkey not in active_tracks: continue xs.append(x_low) xs.append(x_high) ys.append(y_low) ys.append(y_high) node_type = graph2.NodeType(graph_node_type) if node_type == graph2.NodeType.CHANX: assert y_low == y_high, (pkey, track_pkey) if y_low not in x_tracks: x_tracks[y_low] = [] x_tracks[y_low].append((x_low, x_high, pkey)) elif node_type == graph2.NodeType.CHANY: assert x_low == x_high, (pkey, track_pkey) if x_low not in y_tracks: y_tracks[x_low] = [] y_tracks[x_low].append((y_low, y_high, pkey)) else: assert False, node_type x_list = [] y_list = [] x_channel_models = {} y_channel_models = {} for y in x_tracks: x_channel_models[y] = pool.apply_async(graph2.process_track, (x_tracks[y], )) for x in y_tracks: y_channel_models[x] = pool.apply_async(graph2.process_track, (y_tracks[x], )) write_cur.execute("""BEGIN EXCLUSIVE TRANSACTION;""") for y in progressbar_utils.progressbar(range(max(x_tracks) + 1)): if y in x_tracks: x_channel_models[y] = x_channel_models[y].get() x_list.append(len(x_channel_models[y].trees)) for idx, tree in enumerate(x_channel_models[y].trees): for i in tree: write_cur.execute( 'UPDATE graph_node SET ptc = ? WHERE pkey = ?;', (idx, i[2])) else: x_list.append(0) for x in progressbar_utils.progressbar(range(max(y_tracks) + 1)): if x in y_tracks: y_channel_models[x] = y_channel_models[x].get() y_list.append(len(y_channel_models[x].trees)) for idx, tree in enumerate(y_channel_models[x].trees): for i in tree: write_cur.execute( 'UPDATE graph_node SET ptc = ? WHERE pkey = ?;', (idx, i[2])) else: y_list.append(0) x_min = min(xs) y_min = min(ys) x_max = max(xs) y_max = max(ys) write_cur.execute( """ INSERT INTO channel(chan_width_max, x_min, x_max, y_min, y_max) VALUES (?, ?, ?, ?, ?);""", (max(max(x_list), max(y_list)), x_min, x_max, y_min, y_max)) for idx, info in enumerate(x_list): write_cur.execute( """ INSERT INTO x_list(idx, info) VALUES (?, ?);""", (idx, info)) for idx, info in enumerate(y_list): write_cur.execute( """ INSERT INTO y_list(idx, info) VALUES (?, ?);""", (idx, info)) write_cur.execute("""COMMIT TRANSACTION;""")