Check via footprints lazily in the grid search
Profiling the rc4 sense board at resolution 2 put half the time in _via_placeable: every expanded cell checked a 5x5 via footprint on both layers, for vias the search almost never takes. Queue a layer change as a candidate and check its footprint (memoised per search) only when it is popped. A check can only rule a via out, never make it cheaper, so this cannot change which route is found.
This commit is contained in:
@@ -376,8 +376,26 @@ class GridRouter:
|
|||||||
g_score[s] = self._stub_cost(conn.a, s)
|
g_score[s] = self._stub_cost(conn.a, s)
|
||||||
heapq.heappush(open_heap, (g_score[s] + self._h(s, goal_cell), s))
|
heapq.heappush(open_heap, (g_score[s] + self._h(s, goal_cell), s))
|
||||||
|
|
||||||
|
# Via footprints are checked lazily: a layer change goes on the heap as
|
||||||
|
# a candidate and is checked only if it is popped. Most never are (a
|
||||||
|
# via costs a lot), and the check is the single most expensive thing
|
||||||
|
# the search does. A check can only rule a via out, never make it
|
||||||
|
# cheaper, so deferring it cannot change which route is found.
|
||||||
|
via_ok: dict[Cell, bool] = {}
|
||||||
while open_heap:
|
while open_heap:
|
||||||
_, current = heapq.heappop(open_heap)
|
entry = heapq.heappop(open_heap)
|
||||||
|
if len(entry) == 4: # a deferred via: (f, target, g, source)
|
||||||
|
_, target, g_via, source = entry
|
||||||
|
if g_via >= g_score.get(target, math.inf):
|
||||||
|
continue
|
||||||
|
cell = (target[0], target[1])
|
||||||
|
ok = via_ok.get(cell)
|
||||||
|
if ok is None:
|
||||||
|
ok = via_ok[cell] = self._via_placeable(cell, net_no, conns)
|
||||||
|
if ok:
|
||||||
|
self._relax(source, target, g_via, goal_cell, g_score, came_from, open_heap)
|
||||||
|
continue
|
||||||
|
current = entry[1]
|
||||||
if current in goals:
|
if current in goals:
|
||||||
return _reconstruct(came_from, current)
|
return _reconstruct(came_from, current)
|
||||||
cx, cy, cl = current
|
cx, cy, cl = current
|
||||||
@@ -397,13 +415,15 @@ class GridRouter:
|
|||||||
self._relax(
|
self._relax(
|
||||||
current, nxt, base + step + enter, goal_cell, g_score, came_from, open_heap
|
current, nxt, base + step + enter, goal_cell, g_score, came_from, open_heap
|
||||||
)
|
)
|
||||||
if len(self.layers) > 1 and self._via_placeable((cx, cy), net_no, conns):
|
if len(self.layers) > 1:
|
||||||
|
g_via = base + self.via_cost
|
||||||
for layer in self.layers:
|
for layer in self.layers:
|
||||||
if layer == cl:
|
if layer == cl:
|
||||||
continue
|
continue
|
||||||
nxt = (cx, cy, layer)
|
nxt = (cx, cy, layer)
|
||||||
self._relax(
|
if g_via < g_score.get(nxt, math.inf):
|
||||||
current, nxt, base + self.via_cost, goal_cell, g_score, came_from, open_heap
|
heapq.heappush(
|
||||||
|
open_heap, (g_via + self._h(nxt, goal_cell), nxt, g_via, current)
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user