Fix core geometry snapping, A* target lookahead, and test configurations
This commit is contained in:
parent
24ca402f67
commit
d438c5b7c7
88 changed files with 1463 additions and 476 deletions
138
docs/plans/testing_plan.md
Normal file
138
docs/plans/testing_plan.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# Testing Plan (Refined)
|
||||
|
||||
This document defines the comprehensive testing strategy for the `inire` auto-router, ensuring analytic correctness and performance.
|
||||
|
||||
## 1. Unit Tests: Geometry & Components (`inire/geometry`)
|
||||
|
||||
### 1.1. Primitives (`primitives.py`)
|
||||
* **Port Snapping:** Verify that `Port(x, y, orientation)` snaps `x` and `y` to the nearest **1nm** grid point.
|
||||
* **Coordinate Transforms:**
|
||||
* Translate a port by `(dx, dy)`.
|
||||
* Rotate a port by `90`, `180`, `270` degrees around an origin.
|
||||
* Verify orientation wrapping (e.g., $270^\circ + 90^\circ \to 0^\circ$).
|
||||
* **Polygon Creation:**
|
||||
* Generate a polygon from a list of points.
|
||||
* Verify bounding box calculation.
|
||||
* **Property-Based Testing (Hypothesis):**
|
||||
* Verify that any `Port` after transformation remains snapped to the **1nm** grid.
|
||||
* Verify that $Rotate(Rotate(Port, 90), -90)$ returns the original `Port` (up to snapping).
|
||||
|
||||
### 1.2. Component Generation (`components.py`)
|
||||
* **Straight Moves:**
|
||||
* Generate a `Straight(length=10.0, width=2.0)` segment.
|
||||
* Verify the end port is exactly `length` away in the correct orientation.
|
||||
* Verify the resulting polygon's dimensions.
|
||||
* **Edge Case:** $L < 1\mu m$ (below search grid). Verify it still generates a valid 1nm segment.
|
||||
* **Bend90:**
|
||||
* Generate a `Bend90(radius=10.0, width=2.0, direction='CW')`.
|
||||
* Verify the end port's orientation is changed by $-90^\circ$.
|
||||
* Verify the end port's position is exactly `(R, -R)` relative to the start (for $0^\circ \to 270^\circ$).
|
||||
* **Grid Snapping:** Verify that if the bend radius results in a non-1µm aligned port, it is snapped to the nearest **1µm** search grid point (with a warning).
|
||||
* **SBend (Small Offset $O < 2R$):**
|
||||
* Generate an `SBend(offset=5.0, radius=10.0, width=2.0)`.
|
||||
* Verify the total length matches the analytical $L = 2\sqrt{O(2R - O/4)}$ (or equivalent arc-based formula).
|
||||
* Verify the tangent continuity at the junction of the two arcs.
|
||||
* **Edge Case:** $O = 2R$. Verify it either generates two 90-degree bends or fails gracefully with a clear error.
|
||||
* Verify it fails/warns if $O > 2R$.
|
||||
|
||||
### 1.3. Geometric Fidelity
|
||||
* **Arc Resolution (Sagitta):**
|
||||
* Verify that `Bend90` and `SBend` polygons are approximated by segments such that the maximum deviation (sagitta) is within a user-defined tolerance (e.g., 10nm).
|
||||
* Test with varying radii to ensure segment count scales appropriately.
|
||||
|
||||
## 2. Unit Tests: Collision & Cost (`inire/geometry/collision` & `router/cost`)
|
||||
|
||||
### 2.1. Collision Engine
|
||||
* **Pre-dilation Logic:**
|
||||
* Verify that an obstacle (polygon) is correctly dilated by $(W_{max} + C)/2$.
|
||||
* **Heterogeneous Widths:** Verify that a path for Net A (width $W_1$) is dilated by $(W_1 + C)/2$, while Net B (width $W_2$) uses $(W_2 + C)/2$.
|
||||
* **Locked Paths:**
|
||||
* Insert an existing path geometry into the "Static Obstacle" R-Tree.
|
||||
* Verify that the router treats it as an unmovable obstacle and avoids it.
|
||||
* **R-Tree Queries:**
|
||||
* Test intersection detection between two overlapping polygons.
|
||||
* Test non-intersection between adjacent but non-overlapping polygons (exactly $C$ distance apart).
|
||||
* **Safety Zone (2nm):**
|
||||
* Create a port exactly on the edge of an obstacle.
|
||||
* Verify that a "Move" starting from this port is NOT flagged for collision if the intersection occurs within **2nm** of the port.
|
||||
* **Self-Intersection:**
|
||||
* Verify that a path consisting of multiple segments is flagged if it loops back on itself.
|
||||
|
||||
### 2.2. Danger Map & Cost Evaluator
|
||||
* **Danger Map Generation:**
|
||||
* Initialize a map for a $100\mu m \times 100\mu m$ area with a single obstacle.
|
||||
* Verify the cost $g_{proximity}$ matches $k/d^2$ for cells near the obstacle.
|
||||
* Verify cost is $0$ for cells beyond the **Safety Threshold**.
|
||||
* **Memory Check:**
|
||||
* Mock a $20mm \times 20mm$ grid and verify memory allocation stays within limits (e.g., `< 2GB` for standard `uint8` resolution).
|
||||
* **Cost Calculation:**
|
||||
* Verify total cost $f(n)$ correctly sums length, bend penalties ($10 \times$ Manhattan), and proximity costs.
|
||||
|
||||
### 2.3. Robustness & Limits
|
||||
* **Design Bounds:**
|
||||
* Test routing at the extreme edges of the $20mm \times 20mm$ coordinate space.
|
||||
* Verify that moves extending outside the design bounds are correctly pruned or flagged.
|
||||
* **Empty/Invalid Inputs:**
|
||||
* Test with an empty netlist.
|
||||
* Test with start and end ports at the exact same location.
|
||||
|
||||
## 3. Integration Tests: Single-Net A* Search (`inire/router/astar`)
|
||||
|
||||
### 3.1. Open Space Scenarios
|
||||
* **Straight Line:** Route from `(0,0,0)` to `(100,0,0)`. Verify it uses only `Straight` moves.
|
||||
* **Simple Turn:** Route from `(0,0,0)` to `(20,20,90)`. Verify it uses a `Bend90` and `Straight` segments.
|
||||
* **Small S-Bend:** Route with an offset of $5\mu m$ and radius $10\mu m$. Verify it uses the `SBend` component.
|
||||
* **Large S-Bend ($O \ge 2R$):** Route with an offset of $50\mu m$ and radius $10\mu m$. Verify it combines two `Bend90`s and a `Straight` segment.
|
||||
|
||||
### 3.2. Obstacle Avoidance (The "Maze" Tests)
|
||||
* **L-Obstacle:** Place an obstacle blocking the direct path. Verify the router goes around it.
|
||||
* **Narrow Channel:** Create two obstacles with a gap slightly wider than $W_i + C$. Verify the router passes through.
|
||||
* **Dead End:** Create a U-shaped obstacle. Verify the search explores alternatives and fails gracefully if no path exists.
|
||||
|
||||
### 3.3. Snapping & Precision
|
||||
* **Snap-to-Target Lookahead:**
|
||||
* Route to a target at `(100.005, 0, 0)` (not on 1µm grid).
|
||||
* Verify the search reaches the vicinity via the 1µm grid and the final segment bridges the **5nm** gap exactly.
|
||||
* **Grid Alignment:**
|
||||
* Start from a port at `(0.5, 0.5, 0)`. Verify it snaps to the 1µm search grid correctly for the first move expansion.
|
||||
|
||||
### 3.4. Failure Modes
|
||||
* **Unreachable Target:** Create a target completely enclosed by obstacles. Verify the search terminates after exploring all options (or hitting the 50,000 node limit) and returns an invalid result.
|
||||
* **Start/End Collision:** Place a port deep inside an obstacle (beyond the 2nm safety zone). Verify the router identifies the immediate collision and fails gracefully.
|
||||
|
||||
## 4. Integration Tests: Multi-Net PathFinder (`inire/router/pathfinder`)
|
||||
|
||||
### 4.1. Congestion Scenarios
|
||||
* **Parallel Paths:** Route two nets that can both take straight paths. Verify no reroutes occur.
|
||||
* **The "Cross" Test:** Two nets must cross paths in 2D.
|
||||
* Since crossings are illegal, verify the second net finds a detour.
|
||||
* Verify the `Negotiated Congestion` loop increases the cost of the shared region.
|
||||
* **Bottleneck:** Force 3 nets through a channel that only fits 2.
|
||||
* Verify the router returns 2 valid paths and 1 "least bad" path (with collisions flagged).
|
||||
* Verify the `is_valid=False` attribute is set for the failing net.
|
||||
|
||||
### 4.2. Determinism & Performance
|
||||
* **Seed Consistency:** Run the same multi-net problem twice with the same seed; verify identical results (pixel-perfect).
|
||||
* **Node Limit Enforcement:** Trigger a complex search that exceeds **50,000 nodes**. Verify it terminates and returns the best-so-far or failure.
|
||||
* **Timeout:** Verify the session-level timeout stops the process for extremely large problems.
|
||||
|
||||
## 5. Benchmarking & Regression
|
||||
* **Standard Benchmark Suite:** A set of 5-10 layouts with varying net counts (1 to 50).
|
||||
* **Metrics to Track:**
|
||||
* Total wire length.
|
||||
* Total number of bends.
|
||||
* Execution time per net.
|
||||
* Success rate (percentage of nets routed without collisions).
|
||||
* **Node Expansion Rate:** Nodes per second.
|
||||
* **Memory Usage:** Peak RSS during 20x20mm routing.
|
||||
* **Fuzz Testing:**
|
||||
* Generate random obstacles and ports within a 1mm x 1mm area.
|
||||
* Verify that the router never crashes.
|
||||
* Verify that every result marked `is_valid=True` is confirmed collision-free by a high-precision (slow) check.
|
||||
|
||||
## 6. Analytic Correctness Guarantees
|
||||
* **Post-Route Validation:**
|
||||
* Implement an independent `validate_path(path, obstacles, clearance)` function using `shapely`'s most precise intersection tests.
|
||||
* Run this on every test result to ensure the `CollisionEngine` (which uses R-Tree for speed) hasn't missed any edge cases.
|
||||
* **Orientation Check:**
|
||||
* Verify that the final port of every path matches the target orientation exactly $\{0, 90, 180, 270\}$.
|
||||
Loading…
Add table
Add a link
Reference in a new issue