fix examples

This commit is contained in:
Jan Petykiewicz 2026-03-30 21:22:20 -07:00
commit e11132b51d
20 changed files with 406 additions and 101 deletions

View file

@ -3,7 +3,7 @@ from inire.utils.visualization import plot_routing_results
def main() -> None:
print("Running Example 03: Locked Routes...")
print("Running Example 03: Locked Paths...")
bounds = (0, -50, 100, 50)
options = RoutingOptions(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Before After
Before After

View file

@ -11,6 +11,8 @@ def _route_scenario(
bend_collision_type: str,
netlist: dict[str, tuple[Port, Port]],
widths: dict[str, float],
*,
bend_clip_margin: float | None = None,
) -> dict[str, RoutingResult]:
problem = RoutingProblem(
bounds=bounds,
@ -21,6 +23,7 @@ def _route_scenario(
search=SearchOptions(
bend_radii=(10.0,),
bend_collision_type=bend_collision_type,
bend_clip_margin=bend_clip_margin,
),
objective=ObjectiveWeights(
bend_penalty=50.0,
@ -49,7 +52,14 @@ def main() -> None:
print("Routing Scenario 2 (BBox)...")
res_bbox = _route_scenario(bounds, obstacles, "bbox", netlist_bbox, {"bbox_model": 2.0})
print("Routing Scenario 3 (Clipped BBox)...")
res_clipped = _route_scenario(bounds, obstacles, "clipped_bbox", netlist_clipped, {"clipped_model": 2.0})
res_clipped = _route_scenario(
bounds,
obstacles,
"clipped_bbox",
netlist_clipped,
{"clipped_model": 2.0},
bend_clip_margin=1.0,
)
all_results = {**res_arc, **res_bbox, **res_clipped}
all_netlists = {**netlist_arc, **netlist_bbox, **netlist_clipped}

View file

@ -3,17 +3,12 @@ import time
from shapely.geometry import box
from inire import (
CongestionOptions,
DiagnosticsOptions,
NetSpec,
ObjectiveWeights,
Port,
RoutingOptions,
RoutingProblem,
RoutingResult,
SearchOptions,
route,
)
from inire.router._stack import build_routing_stack
from inire.utils.visualization import plot_expanded_nodes, plot_routing_results
@ -45,12 +40,15 @@ def main() -> None:
static_obstacles=tuple(obstacles),
clearance=6.0,
)
from inire import CongestionOptions, DiagnosticsOptions, ObjectiveWeights, RoutingOptions, SearchOptions
options = RoutingOptions(
search=SearchOptions(
node_limit=2_000_000,
bend_radii=(50.0,),
sbend_radii=(50.0,),
greedy_h_weight=1.5,
bend_clip_margin=10.0,
),
objective=ObjectiveWeights(
unit_length_cost=0.1,
@ -61,48 +59,59 @@ def main() -> None:
max_iterations=15,
base_penalty=100.0,
multiplier=1.4,
net_order="shortest",
shuffle_nets=True,
seed=42,
),
diagnostics=DiagnosticsOptions(capture_expanded=True),
)
stack = build_routing_stack(problem, options)
evaluator = stack.evaluator
finder = stack.finder
metrics = finder.metrics
iteration_stats: list[dict[str, int]] = []
def iteration_callback(iteration: int, current_results: dict[str, RoutingResult]) -> None:
successes = sum(1 for result in current_results.values() if result.is_valid)
total_collisions = sum(result.collisions for result in current_results.values())
total_nodes = metrics.nodes_expanded
print(f" Iteration {iteration} finished. Successes: {successes}/{len(netlist)}, Collisions: {total_collisions}")
new_greedy = max(1.1, 1.5 - ((iteration + 1) / 10.0) * 0.4)
evaluator.greedy_h_weight = new_greedy
print(f" Adaptive Greedy Weight for Next Iteration: {new_greedy:.3f}")
iteration_stats.append(
{
"Iteration": iteration,
"Success": successes,
"Congestion": total_collisions,
"Nodes": total_nodes,
}
)
metrics.reset_per_route()
print(f"Routing {len(netlist)} nets through 200um bottleneck...")
start_time = time.perf_counter()
run = route(problem, options=options, iteration_callback=iteration_callback)
results = finder.route_all(iteration_callback=iteration_callback)
end_time = time.perf_counter()
print(f"Routing took {end_time - start_time:.4f}s")
print("\n--- Iteration Summary ---")
print(f"{'Iter':<5} | {'Success':<8} | {'Congest':<8}")
print("-" * 30)
print(f"{'Iter':<5} | {'Success':<8} | {'Congest':<8} | {'Nodes':<10}")
print("-" * 43)
for stats in iteration_stats:
print(f"{stats['Iteration']:<5} | {stats['Success']:<8} | {stats['Congestion']:<8}")
print(f"{stats['Iteration']:<5} | {stats['Success']:<8} | {stats['Congestion']:<8} | {stats['Nodes']:<10}")
success_count = sum(1 for result in run.results_by_net.values() if result.is_valid)
success_count = sum(1 for result in results.values() if result.is_valid)
print(f"\nFinal: Routed {success_count}/{len(netlist)} nets successfully.")
for net_id, result in run.results_by_net.items():
for net_id, result in results.items():
if not result.is_valid:
print(f" FAILED: {net_id}, collisions={result.collisions}")
else:
print(f" {net_id}: SUCCESS")
fig, ax = plot_routing_results(run.results_by_net, list(obstacles), bounds, netlist=netlist)
plot_expanded_nodes(list(run.expanded_nodes), ax=ax)
fig, ax = plot_routing_results(results, list(obstacles), bounds, netlist=netlist)
plot_expanded_nodes(list(finder.accumulated_expanded_nodes), ax=ax)
fig.savefig("examples/07_large_scale_routing.png")
print("Saved plot to examples/07_large_scale_routing.png")

View file

@ -1,50 +1,65 @@
from shapely.geometry import Polygon
from inire import CongestionOptions, NetSpec, ObjectiveWeights, RoutingOptions, RoutingProblem, RoutingResult, SearchOptions, route
from inire import CongestionOptions, NetSpec, RoutingOptions, RoutingProblem, SearchOptions
from inire.geometry.collision import RoutingWorld
from inire.geometry.primitives import Port
from inire.router._astar_types import AStarContext, AStarMetrics
from inire.router._router import PathFinder
from inire.router.cost import CostEvaluator
from inire.router.danger_map import DangerMap
from inire.utils.visualization import plot_routing_results
def _run_request(
bounds: tuple[float, float, float, float],
bend_collision_type: object,
net_id: str,
start: Port,
target: Port,
) -> dict[str, RoutingResult]:
problem = RoutingProblem(
bounds=bounds,
nets=(NetSpec(net_id, start, target, width=2.0),),
)
options = RoutingOptions(
search=SearchOptions(
bend_radii=(10.0,),
bend_collision_type=bend_collision_type,
sbend_radii=(),
),
objective=ObjectiveWeights(
bend_penalty=50.0,
sbend_penalty=150.0,
),
congestion=CongestionOptions(use_tiered_strategy=False),
)
return route(problem, options=options).results_by_net
def main() -> None:
print("Running Example 08: Custom Bend Geometry...")
bounds = (0, 0, 150, 150)
engine = RoutingWorld(clearance=2.0)
danger_map = DangerMap(bounds=bounds)
danger_map.precompute([])
evaluator = CostEvaluator(engine, danger_map, bend_penalty=50.0, sbend_penalty=150.0)
metrics = AStarMetrics()
start = Port(20, 20, 0)
target = Port(100, 100, 90)
print("Routing with standard arc...")
results_std = _run_request(bounds, "arc", "custom_bend", start, target)
results_std = PathFinder(
AStarContext(
evaluator,
RoutingProblem(
bounds=bounds,
nets=(NetSpec("custom_bend", start, target, width=2.0),),
),
RoutingOptions(
search=SearchOptions(bend_radii=(10.0,), sbend_radii=()),
congestion=CongestionOptions(max_iterations=1),
),
),
metrics=metrics,
).route_all()
custom_poly = Polygon([(0, -11), (11, -11), (11, 0), (9, 0), (9, -9), (0, -9)])
custom_poly = Polygon([(-10, -10), (10, -10), (10, 10), (-10, 10)])
print("Routing with custom bend geometry...")
results_custom = _run_request(bounds, custom_poly, "custom_model", start, target)
print("Routing with custom collision model...")
results_custom = PathFinder(
AStarContext(
evaluator,
RoutingProblem(
bounds=bounds,
nets=(NetSpec("custom_model", start, target, width=2.0),),
),
RoutingOptions(
search=SearchOptions(
bend_radii=(10.0,),
bend_collision_type=custom_poly,
sbend_radii=(),
),
congestion=CongestionOptions(max_iterations=1, use_tiered_strategy=False),
),
),
metrics=AStarMetrics(),
use_tiered_strategy=False,
).route_all()
all_results = {**results_std, **results_custom}
fig, _ax = plot_routing_results(

View file

@ -26,7 +26,7 @@ def main() -> None:
bend_penalty=50.0,
sbend_penalty=150.0,
),
congestion=CongestionOptions(warm_start_enabled=False),
congestion=CongestionOptions(warm_start_enabled=False, max_iterations=1),
)
print("Routing with a deliberately tiny node budget (should return a partial path)...")

View file

@ -18,9 +18,9 @@ Demonstrates the Negotiated Congestion algorithm handling multiple intersecting
`inire` supports multiple collision models for bends, allowing a trade-off between search speed and geometric accuracy:
* **Arc**: High-fidelity geometry (Highest accuracy).
* **BBox**: Simple axis-aligned bounding box (Fastest search).
* **Clipped BBox**: A balanced 8-point conservative polygonal approximation of the arc (Optimal performance).
* **Clipped BBox**: A balanced model that clips the corners of the AABB to better fit the arc (Optimal performance).
Example 08 also demonstrates a custom polygonal bend geometry. Custom polygons are defined in bend-local coordinates around the bend center, mirrored for CW bends, and rotated with the bend orientation before being placed. The example uses a 6-point Manhattan 90-degree bend with the same width as the normal waveguide, and that polygon now serves as both the routed geometry and the search-time collision shape.
Example 08 also demonstrates a custom polygonal bend geometry. It uses a centered `20x20` box as a custom bend collision model.
![Custom Bend Geometry](08_custom_bend_geometry.png)