- Python 100%
| examples | ||
| inire | ||
| .gitignore | ||
| .python-version | ||
| DOCS.md | ||
| LICENSE.md | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
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:
# Using uv
uv sync
# Using pip
pip install numpy scipy shapely rtree matplotlib
Quick Start
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. Generates01_simple_route.png.examples/02_congestion_resolution.py: Multi-net routing resolving bottlenecks using Negotiated Congestion. Generates02_congestion_resolution.png.examples/03_locked_paths.py: Incremental workflow usinglock_net()to route around previously fixed paths. Generates03_locked_paths.png.examples/04_sbends_and_radii.py: Complex paths using parametric S-bends and multiple bend radii. Generates04_sbends_and_radii.png.examples/05_orientation_stress.py: Stress test for various port orientation combinations (U-turns, opposite directions). Generates05_orientation_stress.png.
Run an example:
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:
- Straights: Variable-length segments.
- 90° Bends: Fixed-radius PDK cells.
- 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.