Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/bun-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Setup bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version: 1.3.1

- name: Install dependencies
run: bun install
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ export class OverlapAvoidanceStepSolver extends BaseSolver {

private detourCountByLabel: Record<string, number> = {}
private readonly PADDING_BUFFER = 0.1
private readonly MAX_ATTEMPTS_PER_OVERLAP = 25
private overlapAttemptCounts: Record<string, number> = {}

public override activeSubSolver: SingleOverlapSolver | null = null
private overlapQueue: Overlap[] = []
private recentlyFailed: Set<string> = new Set()
private currentOverlapId: string | null = null

private getOverlapId(overlap: Overlap) {
return `${overlap.trace.mspPairId}-${overlap.label.globalConnNetId}`
}

constructor(solverInput: OverlapCollectionSolverInput) {
super()
Expand All @@ -61,10 +68,14 @@ export class OverlapAvoidanceStepSolver extends BaseSolver {
}
this.activeSubSolver = null
this.recentlyFailed.clear()
this.currentOverlapId = null
} else if (this.activeSubSolver.failed) {
const overlapId = `${this.activeSubSolver.initialTrace.mspPairId}-${this.activeSubSolver.label.globalConnNetId}`
const overlapId =
this.currentOverlapId ??
`${this.activeSubSolver.initialTrace.mspPairId}-${this.activeSubSolver.label.globalConnNetId}`
this.recentlyFailed.add(overlapId)
this.activeSubSolver = null
this.currentOverlapId = null
}
return
}
Expand All @@ -80,13 +91,19 @@ export class OverlapAvoidanceStepSolver extends BaseSolver {
return o.trace.globalConnNetId !== o.label.globalConnNetId
})

if (overlaps.length === 0) {
const viableOverlaps = overlaps.filter((o) => {
const overlapId = this.getOverlapId(o)
const attempts = this.overlapAttemptCounts[overlapId] ?? 0
return attempts < this.MAX_ATTEMPTS_PER_OVERLAP
})

if (viableOverlaps.length === 0) {
this.solved = true
return
}

const nonFailedOverlaps = overlaps.filter((o) => {
const overlapId = `${o.trace.mspPairId}-${o.label.globalConnNetId}`
const nonFailedOverlaps = viableOverlaps.filter((o) => {
const overlapId = this.getOverlapId(o)
return !this.recentlyFailed.has(overlapId)
})

Expand All @@ -100,6 +117,10 @@ export class OverlapAvoidanceStepSolver extends BaseSolver {
const nextOverlap = this.overlapQueue.shift()

if (nextOverlap) {
const overlapId = this.getOverlapId(nextOverlap)
const attemptCount = this.overlapAttemptCounts[overlapId] ?? 0
this.overlapAttemptCounts[overlapId] = attemptCount + 1
this.currentOverlapId = overlapId
const traceToFix = this.allTraces.find(
(t) => t.mspPairId === nextOverlap.trace.mspPairId,
)
Expand Down
168 changes: 168 additions & 0 deletions tests/assets/repro32-castellated-pinout.schematicTraceSolverInput.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
{
"chips": [
{
"chipId": "schematic_component_0",
"center": {
"x": 0,
"y": 0
},
"width": 0.4,
"height": 2.5999999999999996,
"pins": [
{
"pinId": "P.1",
"x": -0.6000000000000001,
"y": 1.0999999999999999
},
{
"pinId": "P.2",
"x": -0.6000000000000001,
"y": 0.8999999999999999
},
{
"pinId": "P.3",
"x": -0.6000000000000001,
"y": 0.6999999999999998
},
{
"pinId": "P.4",
"x": -0.6000000000000001,
"y": 0.4999999999999998
},
{
"pinId": "P.5",
"x": -0.6000000000000001,
"y": 0.2999999999999998
},
{
"pinId": "P.6",
"x": -0.6000000000000001,
"y": 0.09999999999999987
},
{
"pinId": "P.7",
"x": -0.6000000000000001,
"y": -0.10000000000000009
},
{
"pinId": "P.8",
"x": -0.6000000000000001,
"y": -0.30000000000000004
},
{
"pinId": "P.9",
"x": -0.6000000000000001,
"y": -0.5
},
{
"pinId": "P.10",
"x": -0.6000000000000001,
"y": -0.7
},
{
"pinId": "P.11",
"x": -0.6000000000000001,
"y": -0.8999999999999999
},
{
"pinId": "P.12",
"x": -0.6000000000000001,
"y": -1.0999999999999999
},
{
"pinId": "P.13",
"x": 0.6000000000000001,
"y": -1.0999999999999999
},
{
"pinId": "P.14",
"x": 0.6000000000000001,
"y": -0.8999999999999999
},
{
"pinId": "P.15",
"x": 0.6000000000000001,
"y": -0.6999999999999998
},
{
"pinId": "P.16",
"x": 0.6000000000000001,
"y": -0.4999999999999998
},
{
"pinId": "P.17",
"x": 0.6000000000000001,
"y": -0.2999999999999998
},
{
"pinId": "P.18",
"x": 0.6000000000000001,
"y": -0.09999999999999987
},
{
"pinId": "P.19",
"x": 0.6000000000000001,
"y": 0.10000000000000009
},
{
"pinId": "P.20",
"x": 0.6000000000000001,
"y": 0.30000000000000004
},
{
"pinId": "P.21",
"x": 0.6000000000000001,
"y": 0.5
},
{
"pinId": "P.22",
"x": 0.6000000000000001,
"y": 0.7
},
{
"pinId": "P.23",
"x": 0.6000000000000001,
"y": 0.8999999999999999
},
{
"pinId": "P.24",
"x": 0.6000000000000001,
"y": 1.0999999999999999
}
]
}
],
"directConnections": [
{
"pinIds": ["P.1", "P.18"],
"netId": "P.pin1 to P.pin18"
},
{
"pinIds": ["P.2", "P.17"],
"netId": "P.pin2 to P.pin17"
},
{
"pinIds": ["P.3", "P.16"],
"netId": "P.pin3 to P.pin16"
},
{
"pinIds": ["P.4", "P.15"],
"netId": "P.pin4 to P.pin15"
},
{
"pinIds": ["P.5", "P.14"],
"netId": "P.pin5 to P.pin14"
},
{
"pinIds": ["P.6", "P.13"],
"netId": "P.pin6 to P.pin13"
},
{
"pinIds": ["P.7", "P.19"],
"netId": "P.pin7 to P.pin19"
}
],
"netConnections": [],
"availableNetLabelOrientations": {},
"maxMspPairDistance": 2.4
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { readFileSync } from "fs"
import { test, expect } from "bun:test"
import { SchematicTracePipelineSolver } from "lib/index"
import type { InputProblem } from "lib/types/InputProblem"

const fixturePath = new URL(
"../../assets/repro32-castellated-pinout.schematicTraceSolverInput.json",
import.meta.url,
)

const inputProblem = JSON.parse(
readFileSync(fixturePath, "utf-8"),
) as InputProblem

test("pipeline completes for castellated pinout with limited overlap retries", () => {
const solver = new SchematicTracePipelineSolver(inputProblem)
solver.solve()

expect(solver.failed).toBeFalse()
expect(solver.solved).toBeTrue()
})