# inire: Auto-Routing for Photonic and RF Integrated Circuits `inire` is a high-performance auto-router designed specifically for the physical constraints of photonic and RF integrated circuits. It utilizes a Hybrid State-Lattice A* search combined with "Negotiated Congestion" (PathFinder) to route multiple nets while maintaining strict geometric fidelity and clearance. ## Key Features * **Hybrid State-Lattice Search**: Routes using discrete 90° bends and parametric S-bends, ensuring manufacturing-stable paths. * **Negotiated Congestion**: Iteratively resolves multi-net bottlenecks by inflating costs in high-traffic regions. * **Analytic Correctness**: Every move is verified against an R-Tree spatial index of obstacles and other paths. * **1nm Precision**: All coordinates and ports are snapped to a 1nm manufacturing grid. * **Safety & Proximity**: Incorporates a "Danger Map" (pre-computed distance transform) to maintain optimal spacing and reduce crosstalk. * **Locked Paths**: Supports treating existing geometries as fixed obstacles for incremental routing sessions. ## Installation `inire` requires Python 3.11+. You can install the dependencies using `uv` (recommended) or `pip`: ```bash # Using uv uv sync # Using pip pip install numpy scipy shapely rtree matplotlib ``` ## Quick Start ```python from inire.geometry.primitives import Port from inire.geometry.collision import CollisionEngine from inire.router.danger_map import DangerMap from inire.router.cost import CostEvaluator from inire.router.astar import AStarRouter from inire.router.pathfinder import PathFinder # 1. Setup Environment engine = CollisionEngine(clearance=2.0) danger_map = DangerMap(bounds=(0, 0, 1000, 1000)) danger_map.precompute([]) # Add polygons here for obstacles # 2. Configure Router evaluator = CostEvaluator( collision_engine=engine, danger_map=danger_map, greedy_h_weight=1.2 ) router = AStarRouter( cost_evaluator=evaluator, bend_penalty=10.0 ) pf = PathFinder( router=router, cost_evaluator=evaluator ) # 3. Define Netlist netlist = { "net1": (Port(0, 0, 0), Port(100, 50, 0)), } # 4. Route results = pf.route_all(netlist, {"net1": 2.0}) if results["net1"].is_valid: print("Successfully routed net1!") ``` ## Usage Examples Check the `examples/` directory for ready-to-run scripts demonstrating core features: * **`examples/01_simple_route.py`**: Basic single-net routing with visualization. Generates `01_simple_route.png`. * **`examples/02_congestion_resolution.py`**: Multi-net routing resolving bottlenecks using Negotiated Congestion. Generates `02_congestion_resolution.png`. * **`examples/03_locked_paths.py`**: Incremental workflow using `lock_net()` to route around previously fixed paths. Generates `03_locked_paths.png`. * **`examples/04_sbends_and_radii.py`**: Complex paths using parametric S-bends and multiple bend radii. Generates `04_sbends_and_radii.png`. * **`examples/05_orientation_stress.py`**: Stress test for various port orientation combinations (U-turns, opposite directions). Generates `05_orientation_stress.png`. Run an example: ```bash python3 examples/01_simple_route.py ``` ## Architecture `inire` operates on a **State-Lattice** defined by $(x, y, \theta)$. From any state, the router expands via three primary "Move" types: 1. **Straights**: Variable-length segments. 2. **90° Bends**: Fixed-radius PDK cells. 3. **Parametric S-Bends**: Procedural arcs for bridging small lateral offsets ($O < 2R$). For multi-net problems, the **PathFinder** loop handles rip-up and reroute logic, ensuring that paths find the globally optimal configuration without crossings. ## Configuration `inire` is highly tunable. Every major component (Router, CostEvaluator, PathFinder) accepts explicit named arguments in its constructor to control expansion rules, cost weights, and convergence limits. See `DOCS.md` for a full parameter reference. ## License This project is licensed under the GNU Affero General Public License v3. See `LICENSE.md` for details.