@tscircuit/capacity-autorouter 0.0.183 → 0.0.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1041 -448
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -177,46 +177,6 @@ declare class CapacityMeshEdgeSolver extends BaseSolver {
|
|
|
177
177
|
visualize(): GraphicsObject;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
interface NodePortSegment {
|
|
181
|
-
capacityMeshNodeId: string;
|
|
182
|
-
nodePortSegmentId?: string;
|
|
183
|
-
start: {
|
|
184
|
-
x: number;
|
|
185
|
-
y: number;
|
|
186
|
-
};
|
|
187
|
-
end: {
|
|
188
|
-
x: number;
|
|
189
|
-
y: number;
|
|
190
|
-
};
|
|
191
|
-
availableZ: number[];
|
|
192
|
-
connectionNames: string[];
|
|
193
|
-
rootConnectionNames?: string[];
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Each Node is a square. The capacity paths indicate the nodes the trace will
|
|
198
|
-
* travel through. We want to find the "Port Segment" that each capacity path
|
|
199
|
-
* will take for each node.
|
|
200
|
-
*/
|
|
201
|
-
declare class CapacityEdgeToPortSegmentSolver extends BaseSolver {
|
|
202
|
-
nodes: CapacityMeshNode[];
|
|
203
|
-
edges: CapacityMeshEdge[];
|
|
204
|
-
capacityPaths: CapacityPath[];
|
|
205
|
-
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
206
|
-
nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>;
|
|
207
|
-
unprocessedNodeIds: CapacityMeshNodeId[];
|
|
208
|
-
nodePortSegments: Map<CapacityMeshNodeId, NodePortSegment[]>;
|
|
209
|
-
colorMap: Record<string, string>;
|
|
210
|
-
constructor({ nodes, edges, capacityPaths, colorMap, }: {
|
|
211
|
-
nodes: CapacityMeshNode[];
|
|
212
|
-
edges: CapacityMeshEdge[];
|
|
213
|
-
capacityPaths: CapacityPath[];
|
|
214
|
-
colorMap?: Record<string, string>;
|
|
215
|
-
});
|
|
216
|
-
step(): void;
|
|
217
|
-
visualize(): GraphicsObject;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
180
|
type PortPoint = {
|
|
221
181
|
connectionName: string;
|
|
222
182
|
rootConnectionName?: string;
|
|
@@ -266,69 +226,6 @@ type HighDensityIntraNodeRoute$1 = {
|
|
|
266
226
|
};
|
|
267
227
|
type HighDensityRoute$1 = HighDensityIntraNodeRoute$1;
|
|
268
228
|
|
|
269
|
-
interface SegmentWithAssignedPoints extends NodePortSegment {
|
|
270
|
-
assignedPoints?: {
|
|
271
|
-
connectionName: string;
|
|
272
|
-
rootConnectionName?: string;
|
|
273
|
-
point: {
|
|
274
|
-
x: number;
|
|
275
|
-
y: number;
|
|
276
|
-
z: number;
|
|
277
|
-
};
|
|
278
|
-
}[];
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* CapacitySegmentToPointSolver:
|
|
282
|
-
*
|
|
283
|
-
* In each step, the solver iterates over all unsolved segments (segments
|
|
284
|
-
* without points assigned for each connection). For each segment:
|
|
285
|
-
*
|
|
286
|
-
* - If there is only one connection, it assigns the center as the point.
|
|
287
|
-
* - If there are two connections, it attempts to determine the ordering using
|
|
288
|
-
* other segments within the node. If no ordering can be determined, it does nothing.
|
|
289
|
-
*
|
|
290
|
-
* If an iteration produces no new assignments, the solver picks the segment with
|
|
291
|
-
* the fewest connections and assigns points evenly spaced along the segment,
|
|
292
|
-
* ordering them alphabetically.
|
|
293
|
-
*/
|
|
294
|
-
declare class CapacitySegmentToPointSolver extends BaseSolver {
|
|
295
|
-
unsolvedSegments: SegmentWithAssignedPoints[];
|
|
296
|
-
solvedSegments: (NodePortSegment & {
|
|
297
|
-
assignedPoints: {
|
|
298
|
-
connectionName: string;
|
|
299
|
-
rootConnectionName?: string;
|
|
300
|
-
point: {
|
|
301
|
-
x: number;
|
|
302
|
-
y: number;
|
|
303
|
-
z: number;
|
|
304
|
-
};
|
|
305
|
-
}[];
|
|
306
|
-
})[];
|
|
307
|
-
nodeMap: Record<string, CapacityMeshNode>;
|
|
308
|
-
colorMap: Record<string, string>;
|
|
309
|
-
constructor({ segments, colorMap, nodes, }: {
|
|
310
|
-
segments: NodePortSegment[];
|
|
311
|
-
colorMap?: Record<string, string>;
|
|
312
|
-
/**
|
|
313
|
-
* This isn't used by the algorithm, but allows associating metadata
|
|
314
|
-
* for the result datatype (the center, width, height of the node)
|
|
315
|
-
*/
|
|
316
|
-
nodes: CapacityMeshNode[];
|
|
317
|
-
});
|
|
318
|
-
/**
|
|
319
|
-
* Perform one iteration step.
|
|
320
|
-
*/
|
|
321
|
-
_step(): void;
|
|
322
|
-
/**
|
|
323
|
-
* Return the assigned points for each segment.
|
|
324
|
-
*/
|
|
325
|
-
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
326
|
-
/**
|
|
327
|
-
* Return a GraphicsObject that visualizes the segments with assigned points.
|
|
328
|
-
*/
|
|
329
|
-
visualize(): GraphicsObject;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
229
|
interface HighDensityHyperParameters {
|
|
333
230
|
FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: number;
|
|
334
231
|
FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: number;
|
|
@@ -815,145 +712,6 @@ declare class CapacityNodeTargetMerger extends BaseSolver {
|
|
|
815
712
|
visualize(): GraphicsObject;
|
|
816
713
|
}
|
|
817
714
|
|
|
818
|
-
type NodePortSegmentId = string;
|
|
819
|
-
interface ChangeLayerOperation {
|
|
820
|
-
op: "changeLayer";
|
|
821
|
-
segmentId: string;
|
|
822
|
-
pointIndex: number;
|
|
823
|
-
newLayer: number;
|
|
824
|
-
/** Operation is mutated and oldLayer is added to allow reversal */
|
|
825
|
-
oldLayer?: number;
|
|
826
|
-
cost?: number;
|
|
827
|
-
}
|
|
828
|
-
interface SwitchOperation {
|
|
829
|
-
op: "switch";
|
|
830
|
-
segmentId: string;
|
|
831
|
-
point1Index: number;
|
|
832
|
-
point2Index: number;
|
|
833
|
-
cost?: number;
|
|
834
|
-
}
|
|
835
|
-
interface CombinedOperation {
|
|
836
|
-
op: "combined";
|
|
837
|
-
subOperations: Array<SwitchOperation | ChangeLayerOperation>;
|
|
838
|
-
cost?: number;
|
|
839
|
-
}
|
|
840
|
-
type Operation = ChangeLayerOperation | SwitchOperation | CombinedOperation;
|
|
841
|
-
/**
|
|
842
|
-
* Use simulated annealing to try to improve the placement of points (via
|
|
843
|
-
* swapping with points on the same segment) or changing the layer.
|
|
844
|
-
*
|
|
845
|
-
* We have the following pieces of information:
|
|
846
|
-
* - NodePortSegment with nodePortSegmentId
|
|
847
|
-
* - A "neighbor" NodePortSegmentWithAssignedPoints has one change
|
|
848
|
-
* - A change can be flipping a point to the opposite layer
|
|
849
|
-
* - A change can also be switching the position of two points
|
|
850
|
-
* - We represent the operations used to change from an original scene
|
|
851
|
-
* with a list of operations [SEG1_CL(1, 1), SEG1_SW(1, 2), SEG2_CL(2, 0)]
|
|
852
|
-
* - CN indicates the capacity node to edit
|
|
853
|
-
* - The SW operation "switches" the x/y location of two points
|
|
854
|
-
* - The CL operation changes the layer of the point
|
|
855
|
-
* - When choosing edits to make, we are biased to operate on nodes that have a
|
|
856
|
-
* high cost and biased against operating on nodes we've operated on a lot
|
|
857
|
-
* - Each step, we generate an operation and use the standard simulated
|
|
858
|
-
* annealing function to determine if we should perform the operation
|
|
859
|
-
*/
|
|
860
|
-
declare class CapacitySegmentPointOptimizer extends BaseSolver {
|
|
861
|
-
assignedSegments: SegmentWithAssignedPoints[];
|
|
862
|
-
colorMap: Record<string, string>;
|
|
863
|
-
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
864
|
-
nodeIdToSegmentIds: Map<string, string[]>;
|
|
865
|
-
segmentIdToNodeIds: Map<string, string[]>;
|
|
866
|
-
currentMutatedSegments: Map<NodePortSegmentId, SegmentWithAssignedPoints>;
|
|
867
|
-
allSegmentIds: string[];
|
|
868
|
-
lastAppliedOperation: Operation | null;
|
|
869
|
-
lastCreatedOperation: Operation | null;
|
|
870
|
-
currentNodeCosts: Map<CapacityMeshNodeId, number>;
|
|
871
|
-
lastAcceptedIteration: number;
|
|
872
|
-
currentCost: number;
|
|
873
|
-
randomSeed: number;
|
|
874
|
-
numNodes: number;
|
|
875
|
-
probabilityOfFailure: number;
|
|
876
|
-
nodesThatCantFitVias: Set<CapacityMeshNodeId>;
|
|
877
|
-
mutableSegments: Set<NodePortSegmentId>;
|
|
878
|
-
VIA_DIAMETER: number;
|
|
879
|
-
OBSTACLE_MARGIN: number;
|
|
880
|
-
MAX_OPERATIONS_PER_MUTATION: number;
|
|
881
|
-
MAX_NODE_CHAIN_PER_MUTATION: number;
|
|
882
|
-
NOOP_ITERATIONS_BEFORE_EARLY_STOP: number;
|
|
883
|
-
constructor({ assignedSegments, colorMap, nodes, viaDiameter, }: {
|
|
884
|
-
assignedSegments: NodePortSegment[];
|
|
885
|
-
colorMap?: Record<string, string>;
|
|
886
|
-
/**
|
|
887
|
-
* This isn't used by the algorithm, but allows associating metadata
|
|
888
|
-
* for the result datatype (the center, width, height of the node)
|
|
889
|
-
*/
|
|
890
|
-
nodes: CapacityMeshNode[];
|
|
891
|
-
viaDiameter?: number;
|
|
892
|
-
});
|
|
893
|
-
random(): number;
|
|
894
|
-
/**
|
|
895
|
-
* The cost is the "probability of failure" of the node.
|
|
896
|
-
*/
|
|
897
|
-
computeNodeCost(nodeId: CapacityMeshNodeId): number;
|
|
898
|
-
/**
|
|
899
|
-
* Number of traces that can go through this node if they are completely
|
|
900
|
-
* straight without crossings
|
|
901
|
-
*/
|
|
902
|
-
getUsedTraceCapacity(nodeId: CapacityMeshNodeId): number;
|
|
903
|
-
/**
|
|
904
|
-
* Granular via capacity is a consideration of capacity that includes...
|
|
905
|
-
* - The number of traces
|
|
906
|
-
* - The number of trace crossings (0-2 vias per trace crossing)
|
|
907
|
-
* - Empirically, each crossing typically results in 0.82 vias
|
|
908
|
-
* - e.g. 17 traces would typically have 51 crossings & 42 vias
|
|
909
|
-
* - The number of layer changes (at least 1 via per layer change)
|
|
910
|
-
* - We don't know how a entry/exit being on separated layers effects
|
|
911
|
-
* the capacity/number of vias yet
|
|
912
|
-
*
|
|
913
|
-
* - Generally minimizing the number of crossings is pretty good, if there
|
|
914
|
-
* is no trace crossing you basically don't have any used capacity
|
|
915
|
-
* - If the entry/exit layer is different, you're guaranteed to have at least
|
|
916
|
-
* one via
|
|
917
|
-
*
|
|
918
|
-
* - Total capacity is computed by estimating the number of vias that could
|
|
919
|
-
* be created using the formula (viaFitAcross / 2) ** 1.1
|
|
920
|
-
*/
|
|
921
|
-
getUsedViaCapacity(nodeId: CapacityMeshNodeId): number;
|
|
922
|
-
getRandomWeightedNodeId(): CapacityMeshNodeId;
|
|
923
|
-
getRandomWeightedSegmentId(): string;
|
|
924
|
-
getMutableSegments(): Set<string>;
|
|
925
|
-
isSegmentMutable(segmentId: string): boolean;
|
|
926
|
-
getRandomOperationForSegment(randomSegmentId: string): SwitchOperation | ChangeLayerOperation | null;
|
|
927
|
-
getNodesNearNode(nodeId: CapacityMeshNodeId, hops?: number): CapacityMeshNodeId[];
|
|
928
|
-
getRandomCombinedOperationNearNode(nodeId: CapacityMeshNodeId): CombinedOperation;
|
|
929
|
-
/**
|
|
930
|
-
* A combined operation can perform multiple operations on a single node, this
|
|
931
|
-
* allows it to reach outcomes that may not be beneficial with since
|
|
932
|
-
* operations
|
|
933
|
-
*/
|
|
934
|
-
getRandomCombinedOperationOnSingleNode(max?: number): CombinedOperation;
|
|
935
|
-
getRandomOperation(): Operation;
|
|
936
|
-
/**
|
|
937
|
-
* We compute "overall probability of failure" as our overall cost, then
|
|
938
|
-
* linearize it to make it easier to work with
|
|
939
|
-
*/
|
|
940
|
-
computeCurrentCost(): {
|
|
941
|
-
cost: number;
|
|
942
|
-
nodeCosts: Map<CapacityMeshNodeId, number>;
|
|
943
|
-
probabilityOfFailure: number;
|
|
944
|
-
linearizedCost: number;
|
|
945
|
-
};
|
|
946
|
-
applyOperation(op: Operation): void;
|
|
947
|
-
reverseOperation(op: Operation): void;
|
|
948
|
-
isNewCostAcceptable(oldPf: number, newPf: number): boolean;
|
|
949
|
-
/**
|
|
950
|
-
* FOR OUTPUT: Return the assigned points for each segment.
|
|
951
|
-
*/
|
|
952
|
-
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
953
|
-
_step(): void;
|
|
954
|
-
visualize(): GraphicsObject;
|
|
955
|
-
}
|
|
956
|
-
|
|
957
715
|
/**
|
|
958
716
|
* Converts a net containing many points to connect into an array of point pair
|
|
959
717
|
* connections.
|
|
@@ -1055,20 +813,1043 @@ declare class MultipleHighDensityRouteStitchSolver extends BaseSolver {
|
|
|
1055
813
|
visualize(): GraphicsObject;
|
|
1056
814
|
}
|
|
1057
815
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
816
|
+
declare class StrawSolver extends BaseSolver {
|
|
817
|
+
multiLayerNodes: CapacityMeshNode[];
|
|
818
|
+
strawNodes: CapacityMeshNode[];
|
|
819
|
+
skippedNodes: CapacityMeshNode[];
|
|
820
|
+
unprocessedNodes: CapacityMeshNode[];
|
|
821
|
+
strawSize: number;
|
|
822
|
+
nodeIdCounter: number;
|
|
823
|
+
constructor(params: {
|
|
824
|
+
nodes: CapacityMeshNode[];
|
|
825
|
+
strawSize?: number;
|
|
826
|
+
});
|
|
827
|
+
getCapacityOfMultiLayerNodesWithinBounds(bounds: {
|
|
828
|
+
minX: number;
|
|
829
|
+
maxX: number;
|
|
830
|
+
minY: number;
|
|
831
|
+
maxY: number;
|
|
832
|
+
}): number;
|
|
833
|
+
getSurroundingCapacities(node: CapacityMeshNode): {
|
|
834
|
+
leftSurroundingCapacity: number;
|
|
835
|
+
rightSurroundingCapacity: number;
|
|
836
|
+
topSurroundingCapacity: number;
|
|
837
|
+
bottomSurroundingCapacity: number;
|
|
838
|
+
};
|
|
839
|
+
/**
|
|
840
|
+
* Creates straw nodes from a single-layer node based on surrounding capacities
|
|
841
|
+
*/
|
|
842
|
+
createStrawsForNode(node: CapacityMeshNode): CapacityMeshNode[];
|
|
843
|
+
getResultNodes(): CapacityMeshNode[];
|
|
844
|
+
_step(): void;
|
|
845
|
+
visualize(): GraphicsObject;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Merges same layer nodes into larger nodes. Pre-processing stage necessary
|
|
850
|
+
* for "strawing".
|
|
851
|
+
*/
|
|
852
|
+
declare class SingleLayerNodeMergerSolver extends BaseSolver {
|
|
853
|
+
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
854
|
+
currentBatchNodeIds: CapacityMeshNodeId[];
|
|
855
|
+
absorbedNodeIds: Set<CapacityMeshNodeId>;
|
|
856
|
+
nextBatchNodeIds: CapacityMeshNodeId[];
|
|
857
|
+
batchHadModifications: boolean;
|
|
858
|
+
hasComputedAdjacentNodeIds: boolean;
|
|
859
|
+
newNodes: CapacityMeshNode[];
|
|
860
|
+
constructor(nodes: CapacityMeshNode[]);
|
|
861
|
+
computeAdjacentNodeIdsForFirstBatch(nodes: CapacityMeshNode[]): void;
|
|
862
|
+
getAdjacentSameLayerUnprocessedNodes(rootNode: CapacityMeshNode): CapacityMeshNode[];
|
|
863
|
+
getAdjacentSameLayerUnprocessedNodes2(rootNode: CapacityMeshNode): CapacityMeshNode[];
|
|
864
|
+
_step(): void;
|
|
865
|
+
visualize(): GraphicsObject;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
declare class CapacityMeshEdgeSolver2_NodeTreeOptimization extends CapacityMeshEdgeSolver {
|
|
869
|
+
nodes: CapacityMeshNode[];
|
|
870
|
+
private nodeTree;
|
|
871
|
+
private currentNodeIndex;
|
|
872
|
+
private edgeSet;
|
|
873
|
+
constructor(nodes: CapacityMeshNode[]);
|
|
874
|
+
_step(): void;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
declare class DeadEndSolver extends BaseSolver {
|
|
878
|
+
removedNodeIds: Set<string>;
|
|
879
|
+
private targetNodeIds;
|
|
880
|
+
private leaves;
|
|
881
|
+
private leavesIndex;
|
|
882
|
+
private adjacencyList;
|
|
883
|
+
/** Only used for visualization, dynamically instantiated if necessary */
|
|
884
|
+
nodeMap?: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
885
|
+
private nodes;
|
|
886
|
+
private edges;
|
|
887
|
+
constructor({ nodes, edges, }: {
|
|
888
|
+
nodes: CapacityMeshNode[];
|
|
889
|
+
edges: CapacityMeshEdge[];
|
|
890
|
+
});
|
|
891
|
+
_step(): void;
|
|
892
|
+
visualize(): GraphicsObject;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* A Disjoint Set Union (DSU) or Union-Find data structure.
|
|
897
|
+
* It tracks a collection of disjoint sets and can efficiently merge them.
|
|
898
|
+
*/
|
|
899
|
+
declare class DSU {
|
|
900
|
+
private parent;
|
|
901
|
+
/**
|
|
902
|
+
* Creates a new DSU instance.
|
|
903
|
+
* Each ID is initially in its own set.
|
|
904
|
+
*/
|
|
905
|
+
constructor(ids: string[]);
|
|
906
|
+
/**
|
|
907
|
+
* Finds the representative of the set containing the given ID.
|
|
908
|
+
* Uses path compression.
|
|
909
|
+
*/
|
|
910
|
+
find(id: string): string;
|
|
911
|
+
/**
|
|
912
|
+
* Merges the sets containing the two given IDs.
|
|
913
|
+
*/
|
|
914
|
+
union(id1: string, id2: string): void;
|
|
915
|
+
/**
|
|
916
|
+
* Gets all IDs in the same set as the given ID.
|
|
917
|
+
*/
|
|
918
|
+
getGroup(id: string): string[];
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Extends the base NetToPointPairsSolver with an optimization that utilizes
|
|
923
|
+
* off-board connections to find shorter routing paths.
|
|
924
|
+
*
|
|
925
|
+
* This solver preprocesses all connections to identify points that are
|
|
926
|
+
* electrically connected off-board (via the `isOffBoard` flag). It builds
|
|
927
|
+
* "equivalence groups" of these points using a Disjoint Set Union (DSU)
|
|
928
|
+
* data structure.
|
|
929
|
+
*
|
|
930
|
+
* When the solver processes an on-board connection or a segment from a
|
|
931
|
+
* Minimum Spanning Tree (MST), it checks if either of the connection's
|
|
932
|
+
* endpoints has an off-board equivalent. If so, it calculates the distance
|
|
933
|
+
* to all possible substitutes and chooses the pair that results in the
|
|
934
|
+
* shortest path, potentially rerouting the connection to a more optimal
|
|
935
|
+
* equivalent point.
|
|
936
|
+
*/
|
|
937
|
+
declare class NetToPointPairsSolver2_OffBoardConnection extends NetToPointPairsSolver {
|
|
938
|
+
ogSrj: SimpleRouteJson;
|
|
939
|
+
colorMap: Record<string, string>;
|
|
940
|
+
connectionPointDsu: DSU;
|
|
941
|
+
connectionPointMap: Map<string, ConnectionPoint>;
|
|
942
|
+
constructor(ogSrj: SimpleRouteJson, colorMap?: Record<string, string>);
|
|
943
|
+
_findBestConnectionPointsFromDisjointSets(sourcePoint: ConnectionPoint, targetPoint: ConnectionPoint): {
|
|
944
|
+
pointsToConnect: [ConnectionPoint, ConnectionPoint];
|
|
945
|
+
};
|
|
946
|
+
_step(): void;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
type Phase = "via_removal" | "via_merging" | "path_simplification";
|
|
950
|
+
/**
|
|
951
|
+
* TraceSimplificationSolver consolidates trace optimization by iteratively applying
|
|
952
|
+
* via removal, via merging, and path simplification phases. It reduces redundant vias
|
|
953
|
+
* and simplifies routing paths through configurable iterations.
|
|
954
|
+
*
|
|
955
|
+
* The solver operates in three alternating phases per iteration:
|
|
956
|
+
* 1. "via_removal" - Removes unnecessary vias from routes using UselessViaRemovalSolver
|
|
957
|
+
* 2. "via_merging" - Merges redundant vias on the same net using SameNetViaMergerSolver
|
|
958
|
+
* 3. "path_simplification" - Simplifies routing paths using MultiSimplifiedPathSolver
|
|
959
|
+
*
|
|
960
|
+
* Each iteration consists of all phases executed sequentially.
|
|
961
|
+
*/
|
|
962
|
+
declare class TraceSimplificationSolver extends BaseSolver {
|
|
963
|
+
private simplificationConfig;
|
|
964
|
+
hdRoutes: HighDensityRoute$1[];
|
|
965
|
+
simplificationPipelineLoops: number;
|
|
966
|
+
MAX_SIMPLIFICATION_PIPELINE_LOOPS: number;
|
|
967
|
+
PHASE_ORDER: Phase[];
|
|
968
|
+
currentPhase: Phase;
|
|
969
|
+
/** Callback to extract results from the active sub-solver */
|
|
970
|
+
extractResult: ((solver: BaseSolver) => HighDensityRoute$1[]) | null;
|
|
971
|
+
/** Returns the simplified routes. This is the primary output of the solver. */
|
|
972
|
+
get simplifiedHdRoutes(): HighDensityRoute$1[];
|
|
973
|
+
/**
|
|
974
|
+
* Creates a new TraceSimplificationSolver
|
|
975
|
+
* @param simplificationConfig Configuration object containing:
|
|
976
|
+
* - hdRoutes: Initial high-density routes to simplify
|
|
977
|
+
* - obstacles: Board obstacles to avoid during simplification
|
|
978
|
+
* - connMap: Connectivity map for routing validation
|
|
979
|
+
* - colorMap: Mapping of net names to colors for visualization
|
|
980
|
+
* - outline: Optional board outline boundary
|
|
981
|
+
* - defaultViaDiameter: Default diameter for vias
|
|
982
|
+
* - layerCount: Number of routing layers
|
|
983
|
+
* - iterations: Number of complete simplification iterations (default: 2)
|
|
984
|
+
*/
|
|
985
|
+
constructor(simplificationConfig: {
|
|
986
|
+
hdRoutes: HighDensityRoute$1[];
|
|
987
|
+
obstacles: Obstacle[];
|
|
988
|
+
connMap: ConnectivityMap;
|
|
989
|
+
colorMap: Record<string, string>;
|
|
990
|
+
outline?: Array<{
|
|
991
|
+
x: number;
|
|
992
|
+
y: number;
|
|
993
|
+
}>;
|
|
994
|
+
defaultViaDiameter: number;
|
|
995
|
+
layerCount: number;
|
|
996
|
+
});
|
|
997
|
+
_step(): void;
|
|
998
|
+
visualize(): GraphicsObject;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
interface SegmentPortPoint {
|
|
1002
|
+
segmentPortPointId: string;
|
|
1003
|
+
x: number;
|
|
1004
|
+
y: number;
|
|
1005
|
+
availableZ: number[];
|
|
1006
|
+
nodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
|
|
1007
|
+
edgeId: string;
|
|
1008
|
+
/** The connection name currently using this port point, or null if unused */
|
|
1009
|
+
connectionName: string | null;
|
|
1010
|
+
rootConnectionName?: string;
|
|
1011
|
+
/** XY distance to the centermost port on this Z level (centermost port has distance 0) */
|
|
1012
|
+
distToCentermostPortOnZ: number;
|
|
1013
|
+
}
|
|
1014
|
+
interface SharedEdgeSegment {
|
|
1015
|
+
edgeId: string;
|
|
1016
|
+
nodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
|
|
1017
|
+
start: {
|
|
1018
|
+
x: number;
|
|
1019
|
+
y: number;
|
|
1020
|
+
};
|
|
1021
|
+
end: {
|
|
1022
|
+
x: number;
|
|
1023
|
+
y: number;
|
|
1024
|
+
};
|
|
1025
|
+
availableZ: number[];
|
|
1026
|
+
portPoints: SegmentPortPoint[];
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* AvailableSegmentPointSolver computes port points on shared edges between
|
|
1030
|
+
* capacity mesh nodes. These points can be used for routing traces through
|
|
1031
|
+
* the capacity mesh.
|
|
1032
|
+
*
|
|
1033
|
+
* For each edge shared between two nodes:
|
|
1034
|
+
* 1. Computes the shared edge segment
|
|
1035
|
+
* 2. Determines how many port points can fit based on traceWidth
|
|
1036
|
+
* 3. Creates port points evenly spaced along the segment
|
|
1037
|
+
*
|
|
1038
|
+
* Port points start as unused (connectionName = null) and are assigned
|
|
1039
|
+
* as paths are routed through them.
|
|
1040
|
+
*/
|
|
1041
|
+
declare class AvailableSegmentPointSolver extends BaseSolver {
|
|
1042
|
+
nodes: CapacityMeshNode[];
|
|
1043
|
+
edges: CapacityMeshEdge[];
|
|
1044
|
+
traceWidth: number;
|
|
1045
|
+
obstacleMargin: number;
|
|
1046
|
+
minPortSpacing: number;
|
|
1047
|
+
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1048
|
+
nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>;
|
|
1049
|
+
/** All shared edge segments with their port points */
|
|
1050
|
+
sharedEdgeSegments: SharedEdgeSegment[];
|
|
1051
|
+
/** Map from edgeId to SharedEdgeSegment for quick lookup */
|
|
1052
|
+
edgeSegmentMap: Map<string, SharedEdgeSegment>;
|
|
1053
|
+
/** Map from segmentPortPointId to SegmentPortPoint */
|
|
1054
|
+
portPointMap: Map<string, SegmentPortPoint>;
|
|
1055
|
+
colorMap: Record<string, string>;
|
|
1056
|
+
constructor({ nodes, edges, traceWidth, obstacleMargin, colorMap, }: {
|
|
1057
|
+
nodes: CapacityMeshNode[];
|
|
1058
|
+
edges: CapacityMeshEdge[];
|
|
1059
|
+
traceWidth: number;
|
|
1060
|
+
obstacleMargin?: number;
|
|
1061
|
+
colorMap?: Record<string, string>;
|
|
1062
|
+
});
|
|
1063
|
+
_step(): void;
|
|
1064
|
+
private computeAllSharedEdgeSegments;
|
|
1065
|
+
private computeSharedEdgeSegment;
|
|
1066
|
+
private findOverlappingSegment;
|
|
1067
|
+
/**
|
|
1068
|
+
* Find available port points for traveling between two nodes
|
|
1069
|
+
*/
|
|
1070
|
+
getAvailablePortPointsBetweenNodes(nodeId1: CapacityMeshNodeId, nodeId2: CapacityMeshNodeId): SegmentPortPoint[];
|
|
1071
|
+
/**
|
|
1072
|
+
* Get all port points (both assigned and unassigned) for an edge between nodes
|
|
1073
|
+
*/
|
|
1074
|
+
getPortPointsForEdge(nodeId1: CapacityMeshNodeId, nodeId2: CapacityMeshNodeId): SegmentPortPoint[];
|
|
1075
|
+
/**
|
|
1076
|
+
* Assign a port point to a connection
|
|
1077
|
+
*/
|
|
1078
|
+
assignPortPoint(segmentPortPointId: string, connectionName: string, rootConnectionName?: string): boolean;
|
|
1079
|
+
/**
|
|
1080
|
+
* Release a port point (make it available again)
|
|
1081
|
+
*/
|
|
1082
|
+
releasePortPoint(segmentPortPointId: string): boolean;
|
|
1083
|
+
/**
|
|
1084
|
+
* Get the count of available port points on an edge
|
|
1085
|
+
*/
|
|
1086
|
+
getAvailablePortCountForEdge(nodeId1: CapacityMeshNodeId, nodeId2: CapacityMeshNodeId): number;
|
|
1087
|
+
visualize(): GraphicsObject;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
interface PortPointPathingHyperParameters {
|
|
1091
|
+
SHUFFLE_SEED?: number;
|
|
1092
|
+
CENTER_OFFSET_DIST_PENALTY_FACTOR?: number;
|
|
1093
|
+
CENTER_OFFSET_FOCUS_SHIFT?: number;
|
|
1094
|
+
GREEDY_MULTIPLIER?: number;
|
|
1095
|
+
NODE_PF_FACTOR?: number;
|
|
1096
|
+
RANDOM_COST_MAGNITUDE?: number;
|
|
1097
|
+
MEMORY_PF_FACTOR?: number;
|
|
1098
|
+
BASE_CANDIDATE_COST?: number;
|
|
1099
|
+
REWARD_LOW_TRAVEL_PF_MAGNITUDE?: number;
|
|
1100
|
+
MAX_ITERATIONS_PER_PATH?: number;
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* An input port point without connectionName assigned yet.
|
|
1104
|
+
* These are pre-computed points on node edges where traces can cross.
|
|
1105
|
+
*/
|
|
1106
|
+
interface InputPortPoint {
|
|
1107
|
+
portPointId: string;
|
|
1108
|
+
x: number;
|
|
1109
|
+
y: number;
|
|
1110
|
+
z: number;
|
|
1111
|
+
/** The node IDs that this port point connects (on the shared edge) */
|
|
1112
|
+
connectionNodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
|
|
1113
|
+
/** XY distance to the centermost port on this Z level (centermost port has distance 0) */
|
|
1114
|
+
distToCentermostPortOnZ: number;
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* A node with pre-computed port points (without connectionName assigned).
|
|
1118
|
+
* This is the input format for PortPointPathingSolver.
|
|
1119
|
+
*/
|
|
1120
|
+
interface InputNodeWithPortPoints {
|
|
1121
|
+
capacityMeshNodeId: CapacityMeshNodeId;
|
|
1122
|
+
center: {
|
|
1123
|
+
x: number;
|
|
1124
|
+
y: number;
|
|
1125
|
+
};
|
|
1126
|
+
width: number;
|
|
1127
|
+
height: number;
|
|
1128
|
+
/** Port points on this node's edges (without connectionName) */
|
|
1129
|
+
portPoints: InputPortPoint[];
|
|
1130
|
+
availableZ: number[];
|
|
1131
|
+
/** If true, this node is a target node (contains a connection endpoint) */
|
|
1132
|
+
_containsTarget?: boolean;
|
|
1133
|
+
/** If true, this node contains an obstacle */
|
|
1134
|
+
_containsObstacle?: boolean;
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* A candidate in the A* search. Represents being at a port point,
|
|
1138
|
+
* having entered from a specific node.
|
|
1139
|
+
*/
|
|
1140
|
+
interface PortPointCandidate {
|
|
1141
|
+
prevCandidate: PortPointCandidate | null;
|
|
1142
|
+
/** The port point we're at (null for start/end target points) */
|
|
1143
|
+
portPoint: InputPortPoint | null;
|
|
1144
|
+
/** The node we're currently in (entered via portPoint) */
|
|
1145
|
+
currentNodeId: CapacityMeshNodeId;
|
|
1146
|
+
/** The physical point location (entry point within currentNodeId) */
|
|
1147
|
+
point: {
|
|
1148
|
+
x: number;
|
|
1149
|
+
y: number;
|
|
1150
|
+
};
|
|
1151
|
+
/** The z layer this candidate is on */
|
|
1152
|
+
z: number;
|
|
1153
|
+
f: number;
|
|
1154
|
+
g: number;
|
|
1155
|
+
h: number;
|
|
1156
|
+
}
|
|
1157
|
+
interface ConnectionPathResult {
|
|
1158
|
+
connection: SimpleRouteConnection;
|
|
1159
|
+
/** Start and end node IDs */
|
|
1160
|
+
nodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
|
|
1161
|
+
/** The path of candidates found by the pathing algorithm */
|
|
1162
|
+
path?: PortPointCandidate[];
|
|
1163
|
+
/** Port points used by this connection (with connectionName assigned) */
|
|
1164
|
+
portPoints?: PortPoint[];
|
|
1165
|
+
straightLineDistance: number;
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* PortPointPathingSolver finds paths through the capacity mesh by visiting
|
|
1169
|
+
* pre-computed port points on shared edges. It considers layer information
|
|
1170
|
+
* when routing and uses a Pf-based cost function.
|
|
1171
|
+
*
|
|
1172
|
+
* Improvements in this implementation:
|
|
1173
|
+
* - g is now an *exact* accumulated path cost (incremental delta Pf per node, computed only when a node is "closed")
|
|
1174
|
+
* - node Pf contribution is charged when you *leave* a node (entry+exit known), not when entering the next node
|
|
1175
|
+
* - uses a log-success style cost: cost(pf) = -log(1 - pf), and delta = cost(after) - cost(before)
|
|
1176
|
+
* - caches base node costs and segment delta costs to avoid repeated crossing computations
|
|
1177
|
+
* - computeH uses memoryPf + distance to approximate remaining cost (and can be tuned)
|
|
1178
|
+
* - closes the end node when connecting to the final end target point
|
|
1179
|
+
* - prevents node cycles in a candidate chain (keeps Pf math correct without needing per-node multi-visit tracking)
|
|
1180
|
+
*/
|
|
1181
|
+
declare class PortPointPathingSolver extends BaseSolver {
|
|
1182
|
+
hyperParameters: Partial<PortPointPathingHyperParameters>;
|
|
1183
|
+
simpleRouteJson: SimpleRouteJson;
|
|
1184
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1185
|
+
nodeMap: Map<CapacityMeshNodeId, InputNodeWithPortPoints>;
|
|
1186
|
+
/** Map from nodeId to list of port points accessible from that node */
|
|
1187
|
+
nodePortPointsMap: Map<CapacityMeshNodeId, InputPortPoint[]>;
|
|
1188
|
+
/** Map from portPointId to InputPortPoint */
|
|
1189
|
+
portPointMap: Map<string, InputPortPoint>;
|
|
1190
|
+
connectionsWithResults: ConnectionPathResult[];
|
|
1191
|
+
/** Tracks port points that have been assigned to connections */
|
|
1192
|
+
assignedPortPoints: Map<string, {
|
|
1193
|
+
connectionName: string;
|
|
1194
|
+
rootConnectionName?: string;
|
|
1195
|
+
}>;
|
|
1196
|
+
/** Tracks port points assigned to each node for crossing calculations */
|
|
1197
|
+
nodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>;
|
|
1198
|
+
/** Factor applied to port point reuse penalty */
|
|
1199
|
+
PORT_POINT_REUSE_FACTOR: number;
|
|
1200
|
+
/** Multiplied by Pf delta cost (in -log(1-pf) space) */
|
|
1201
|
+
get NODE_PF_FACTOR(): number;
|
|
1202
|
+
/** Used only in heuristic (h) to "look ahead" into known-congested regions */
|
|
1203
|
+
get MEMORY_PF_FACTOR(): number;
|
|
1204
|
+
get CENTER_OFFSET_FOCUS_SHIFT(): number;
|
|
1205
|
+
/** Used as a *tie-breaker* in f (not part of g) */
|
|
1206
|
+
get RANDOM_COST_MAGNITUDE(): number;
|
|
1207
|
+
/** Optional heuristic reward for stepping into low-memoryPf nodes */
|
|
1208
|
+
get REWARD_LOW_TRAVEL_PF_MAGNITUDE(): number;
|
|
1209
|
+
/** Cost of adding a candidate to the path */
|
|
1210
|
+
get BASE_CANDIDATE_COST(): number;
|
|
1211
|
+
/** Cost penalty for changing layers (used in heuristic) */
|
|
1212
|
+
Z_DIST_COST: number;
|
|
1213
|
+
/** Penalty factor for port points that are far from the center of the segment */
|
|
1214
|
+
get CENTER_OFFSET_DIST_PENALTY_FACTOR(): number;
|
|
1215
|
+
colorMap: Record<string, string>;
|
|
1216
|
+
get GREEDY_MULTIPLIER(): number;
|
|
1217
|
+
MAX_CANDIDATES_IN_MEMORY: number;
|
|
1218
|
+
get MAX_ITERATIONS_PER_PATH(): number;
|
|
1219
|
+
nodeMemoryPfMap: Map<CapacityMeshNodeId, number>;
|
|
1220
|
+
currentConnectionIndex: number;
|
|
1221
|
+
currentPathIterations: number;
|
|
1222
|
+
candidates?: PortPointCandidate[] | null;
|
|
1223
|
+
/** Tracks visited port point IDs to avoid revisiting */
|
|
1224
|
+
visitedPortPoints?: Set<string> | null;
|
|
1225
|
+
connectionNameToGoalNodeIds: Map<string, CapacityMeshNodeId[]>;
|
|
1226
|
+
capacityMeshNodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1227
|
+
/** Heuristic scaling: an estimate of "node pitch" used to estimate remaining hops */
|
|
1228
|
+
avgNodePitch: number;
|
|
1229
|
+
/** Cache of base node cost (cost of node in current committed state) */
|
|
1230
|
+
private baseNodeCostCache;
|
|
1231
|
+
/** Cache of delta cost for a specific node segment (entry->exit) for a specific connection */
|
|
1232
|
+
private segmentDeltaCostCache;
|
|
1233
|
+
constructor({ simpleRouteJson, inputNodes, capacityMeshNodes, colorMap, nodeMemoryPfMap, hyperParameters, }: {
|
|
1234
|
+
simpleRouteJson: SimpleRouteJson;
|
|
1235
|
+
capacityMeshNodes: CapacityMeshNode[];
|
|
1236
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1237
|
+
colorMap?: Record<string, string>;
|
|
1238
|
+
nodeMemoryPfMap?: Map<CapacityMeshNodeId, number>;
|
|
1239
|
+
hyperParameters?: Partial<PortPointPathingHyperParameters>;
|
|
1240
|
+
});
|
|
1241
|
+
private clearCostCaches;
|
|
1242
|
+
private clampPf;
|
|
1243
|
+
/** Convert Pf into an additive "failure cost" */
|
|
1244
|
+
private pfToFailureCost;
|
|
1245
|
+
private round3;
|
|
1246
|
+
private pointKey;
|
|
1247
|
+
/** Base node cost with the currently-committed port points (no candidate additions) */
|
|
1248
|
+
private getBaseNodeFailureCost;
|
|
1249
|
+
/**
|
|
1250
|
+
* Exact delta cost of routing this connection through `nodeId`
|
|
1251
|
+
* for the segment defined by entry->exit.
|
|
1252
|
+
*
|
|
1253
|
+
* This is computed as:
|
|
1254
|
+
* delta = (-log(1-pfAfter)) - (-log(1-pfBefore))
|
|
1255
|
+
* and then scaled by NODE_PF_FACTOR.
|
|
1256
|
+
*/
|
|
1257
|
+
private getNodeDeltaFailureCostForSegment;
|
|
1258
|
+
getConnectionsWithNodes(): {
|
|
1259
|
+
connectionsWithResults: ConnectionPathResult[];
|
|
1260
|
+
connectionNameToGoalNodeIds: Map<string, string[]>;
|
|
1261
|
+
};
|
|
1262
|
+
/**
|
|
1263
|
+
* Build a NodeWithPortPoints structure for crossing calculation.
|
|
1264
|
+
*/
|
|
1265
|
+
buildNodeWithPortPointsForCrossing(node: InputNodeWithPortPoints, additionalPortPoints?: PortPoint[]): NodeWithPortPoints;
|
|
1266
|
+
/**
|
|
1267
|
+
* Compute probability of failure for a node using getIntraNodeCrossings.
|
|
1268
|
+
*/
|
|
1269
|
+
computeNodePf(node: InputNodeWithPortPoints, additionalPortPoints?: PortPoint[]): number;
|
|
1270
|
+
/**
|
|
1271
|
+
* Get penalty for reusing a port point that's already assigned.
|
|
1272
|
+
* No penalty if the port point is assigned to a connection with the same rootConnectionName.
|
|
1273
|
+
*/
|
|
1274
|
+
getPortPointReusePenalty(portPointId: string, rootConnectionName?: string): number;
|
|
1275
|
+
/**
|
|
1276
|
+
* Get the node on the "other side" of a port point from the given node
|
|
1277
|
+
*/
|
|
1278
|
+
getOtherNodeId(portPoint: InputPortPoint, currentNodeId: CapacityMeshNodeId): CapacityMeshNodeId | null;
|
|
1279
|
+
/**
|
|
1280
|
+
* Exact step cost from prevCandidate to exiting current node via `exitPortPoint`.
|
|
1281
|
+
*
|
|
1282
|
+
* IMPORTANT: This charges Pf delta for the node we are *leaving* (prevCandidate.currentNodeId),
|
|
1283
|
+
* because only then we know both entry and exit points inside that node.
|
|
1284
|
+
*/
|
|
1285
|
+
computeG(prevCandidate: PortPointCandidate, exitPortPoint: InputPortPoint, _targetNodeId: CapacityMeshNodeId, connectionName: string, rootConnectionName?: string): number;
|
|
1286
|
+
/**
|
|
1287
|
+
* Final "close" cost when you're already in the end node and you connect to the end target point.
|
|
1288
|
+
* This ensures the last node's segment is accounted for in g.
|
|
1289
|
+
*/
|
|
1290
|
+
private computeGToEndTarget;
|
|
1291
|
+
/**
|
|
1292
|
+
* Heuristic: approximate remaining cost.
|
|
1293
|
+
*
|
|
1294
|
+
* Uses:
|
|
1295
|
+
* - distance to goal
|
|
1296
|
+
* - estimated remaining hops (distance / avgNodePitch)
|
|
1297
|
+
* - memoryPfMap to bias away from historically high Pf regions
|
|
1298
|
+
*/
|
|
1299
|
+
computeH(point: {
|
|
1300
|
+
x: number;
|
|
1301
|
+
y: number;
|
|
1302
|
+
}, currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId, currentZ: number): number;
|
|
1303
|
+
/**
|
|
1304
|
+
* Get available port points to exit from a node, but *do not* return all.
|
|
1305
|
+
*
|
|
1306
|
+
* Rule:
|
|
1307
|
+
* - For each (neighborNodeId, z) group, return the centermost (smallest dist).
|
|
1308
|
+
* - If that centermost port point is already assigned, also return some next-closest
|
|
1309
|
+
* unassigned offsets as backups.
|
|
1310
|
+
*/
|
|
1311
|
+
getAvailableExitPortPointsWithOmissions(nodeId: CapacityMeshNodeId, _endGoalNodeId: CapacityMeshNodeId): InputPortPoint[];
|
|
1312
|
+
canTravelThroughObstacle(node: InputNodeWithPortPoints, connectionName: string): boolean;
|
|
1313
|
+
/**
|
|
1314
|
+
* Check if we've reached the end goal node
|
|
1315
|
+
*/
|
|
1316
|
+
isAtEndGoal(currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId): boolean;
|
|
1317
|
+
getBacktrackedPath(candidate: PortPointCandidate): PortPointCandidate[];
|
|
1318
|
+
/**
|
|
1319
|
+
* Assign port points along a path and record which connections use them.
|
|
1320
|
+
*/
|
|
1321
|
+
assignPortPointsForPath(path: PortPointCandidate[], connectionName: string, rootConnectionName?: string): PortPoint[];
|
|
1322
|
+
/**
|
|
1323
|
+
* Add start/end target points to nodes for crossing calculations.
|
|
1324
|
+
*/
|
|
1325
|
+
addTargetPointsToNodes(path: PortPointCandidate[], connection: SimpleRouteConnection): void;
|
|
1326
|
+
/**
|
|
1327
|
+
* Check if a port point is already in the candidate's path chain.
|
|
1328
|
+
*/
|
|
1329
|
+
isPortPointInPathChain(candidate: PortPointCandidate | null, portPointId: string): boolean;
|
|
1330
|
+
/**
|
|
1331
|
+
* Prevent node cycles in a single candidate chain.
|
|
1332
|
+
* This is important for correctness because we charge node cost as "one segment per node".
|
|
1333
|
+
*/
|
|
1334
|
+
isNodeInPathChain(candidate: PortPointCandidate | null, nodeId: CapacityMeshNodeId): boolean;
|
|
1335
|
+
_step(): void;
|
|
1336
|
+
/**
|
|
1337
|
+
* Get the nodes with port points for the HighDensitySolver
|
|
1338
|
+
*/
|
|
1339
|
+
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
1340
|
+
visualize(): GraphicsObject;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
interface PortPointSectionParams {
|
|
1344
|
+
centerOfSectionCapacityNodeId: CapacityMeshNodeId;
|
|
1345
|
+
expansionDegrees: number;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* A path segment that has been "cut" to fit within a section.
|
|
1349
|
+
* Contains the portion of the path that passes through section nodes,
|
|
1350
|
+
* plus entry/exit information for later reattachment.
|
|
1351
|
+
*/
|
|
1352
|
+
interface SectionPath {
|
|
1353
|
+
/** The connection name this path belongs to */
|
|
1354
|
+
connectionName: string;
|
|
1355
|
+
/** Root connection name if applicable */
|
|
1356
|
+
rootConnectionName?: string;
|
|
1357
|
+
/** The cut path points (only the portion within the section) */
|
|
1358
|
+
points: Array<{
|
|
1359
|
+
x: number;
|
|
1360
|
+
y: number;
|
|
1361
|
+
z: number;
|
|
1362
|
+
nodeId: CapacityMeshNodeId;
|
|
1363
|
+
}>;
|
|
1364
|
+
/** Index in original path where this segment starts */
|
|
1365
|
+
originalStartIndex: number;
|
|
1366
|
+
/** Index in original path where this segment ends */
|
|
1367
|
+
originalEndIndex: number;
|
|
1368
|
+
/** True if path enters from outside the section */
|
|
1369
|
+
hasEntryFromOutside: boolean;
|
|
1370
|
+
/** True if path exits to outside the section */
|
|
1371
|
+
hasExitToOutside: boolean;
|
|
1372
|
+
}
|
|
1373
|
+
interface PortPointSection {
|
|
1374
|
+
/** The center node ID for this section */
|
|
1375
|
+
centerNodeId: CapacityMeshNodeId;
|
|
1376
|
+
/** How many hops from center this section covers */
|
|
1377
|
+
expansionDegrees: number;
|
|
1378
|
+
/** All node IDs included in this section */
|
|
1379
|
+
nodeIds: Set<CapacityMeshNodeId>;
|
|
1380
|
+
/** Input nodes filtered to just those in this section */
|
|
1381
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1382
|
+
/** Capacity mesh nodes filtered to just those in this section */
|
|
1383
|
+
capacityMeshNodes: CapacityMeshNode[];
|
|
1384
|
+
/** Edges that connect nodes within this section */
|
|
1385
|
+
internalEdges: CapacityMeshEdge[];
|
|
1386
|
+
/** Edges that connect section nodes to external nodes (boundary edges) */
|
|
1387
|
+
boundaryEdges: CapacityMeshEdge[];
|
|
1388
|
+
/** Paths that pass through this section, cut to fit within section bounds */
|
|
1389
|
+
sectionPaths: SectionPath[];
|
|
1390
|
+
}
|
|
1391
|
+
interface CreatePortPointSectionInput {
|
|
1392
|
+
/** All input nodes with port points from PortPointPathingSolver */
|
|
1393
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1394
|
+
/** All capacity mesh nodes */
|
|
1395
|
+
capacityMeshNodes: CapacityMeshNode[];
|
|
1396
|
+
/** All capacity mesh edges */
|
|
1397
|
+
capacityMeshEdges: CapacityMeshEdge[];
|
|
1398
|
+
/** Map from node ID to input node for quick lookup */
|
|
1399
|
+
nodeMap: Map<CapacityMeshNodeId, InputNodeWithPortPoints>;
|
|
1400
|
+
/** Connection path results from PortPointPathingSolver */
|
|
1401
|
+
connectionResults?: ConnectionPathResult[];
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
interface MultiSectionPortPointOptimizerParams {
|
|
1405
|
+
simpleRouteJson: SimpleRouteJson;
|
|
1406
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1407
|
+
capacityMeshNodes: CapacityMeshNode[];
|
|
1408
|
+
capacityMeshEdges: CapacityMeshEdge[];
|
|
1409
|
+
colorMap?: Record<string, string>;
|
|
1410
|
+
/** Results from the initial PortPointPathingSolver run */
|
|
1411
|
+
initialConnectionResults: ConnectionPathResult[];
|
|
1412
|
+
/** Assigned port points from initial run */
|
|
1413
|
+
initialAssignedPortPoints: Map<string, {
|
|
1414
|
+
connectionName: string;
|
|
1415
|
+
rootConnectionName?: string;
|
|
1416
|
+
}>;
|
|
1417
|
+
/** Node assigned port points from initial run */
|
|
1418
|
+
initialNodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>;
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* MultiSectionPortPointOptimizer runs local optimization on sections of the
|
|
1422
|
+
* port point graph. It takes the output of PortPointPathingSolver and attempts
|
|
1423
|
+
* to improve routing by re-running the solver on localized sections.
|
|
1424
|
+
*
|
|
1425
|
+
* This phase runs after portPointPathingSolver to refine routes in problematic areas.
|
|
1426
|
+
*/
|
|
1427
|
+
declare class MultiSectionPortPointOptimizer extends BaseSolver {
|
|
1428
|
+
simpleRouteJson: SimpleRouteJson;
|
|
1429
|
+
inputNodes: InputNodeWithPortPoints[];
|
|
1430
|
+
capacityMeshNodes: CapacityMeshNode[];
|
|
1431
|
+
capacityMeshEdges: CapacityMeshEdge[];
|
|
1432
|
+
colorMap: Record<string, string>;
|
|
1433
|
+
nodeMap: Map<CapacityMeshNodeId, InputNodeWithPortPoints>;
|
|
1434
|
+
capacityMeshNodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1435
|
+
/** Current connection results (updated as sections are optimized) */
|
|
1436
|
+
connectionResults: ConnectionPathResult[];
|
|
1437
|
+
/** Current assigned port points */
|
|
1438
|
+
assignedPortPoints: Map<string, {
|
|
1439
|
+
connectionName: string;
|
|
1440
|
+
rootConnectionName?: string;
|
|
1441
|
+
}>;
|
|
1442
|
+
/** Current node assigned port points */
|
|
1443
|
+
nodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>;
|
|
1444
|
+
/** Sections that have been created for optimization */
|
|
1445
|
+
sections: PortPointSection[];
|
|
1446
|
+
/** Section solver currently running */
|
|
1447
|
+
activeSubSolver: PortPointPathingSolver | null;
|
|
1448
|
+
/** Current section being optimized */
|
|
1449
|
+
currentSection: PortPointSection | null;
|
|
1450
|
+
/** Score before optimization (for comparison) */
|
|
1451
|
+
sectionScoreBeforeOptimization: number;
|
|
1452
|
+
/** Node ID of the center of the current section */
|
|
1453
|
+
currentSectionCenterNodeId: CapacityMeshNodeId | null;
|
|
1454
|
+
/** Current index in the optimization schedule */
|
|
1455
|
+
currentScheduleIndex: number;
|
|
1456
|
+
/** Probability of failure for each node */
|
|
1457
|
+
nodePfMap: Map<CapacityMeshNodeId, number>;
|
|
1458
|
+
/** Number of attempts to fix each node */
|
|
1459
|
+
attemptsToFixNode: Map<CapacityMeshNodeId, number>;
|
|
1460
|
+
/** Total number of section optimization attempts made */
|
|
1461
|
+
sectionAttempts: number;
|
|
1462
|
+
/** Maximum number of attempts per node */
|
|
1463
|
+
MAX_ATTEMPTS_PER_NODE: number;
|
|
1464
|
+
/** Maximum total number of section optimization attempts */
|
|
1465
|
+
MAX_SECTION_ATTEMPTS: number;
|
|
1466
|
+
/** Acceptable probability of failure threshold */
|
|
1467
|
+
ACCEPTABLE_PF: number;
|
|
1468
|
+
constructor(params: MultiSectionPortPointOptimizerParams);
|
|
1469
|
+
/**
|
|
1470
|
+
* Compute initial Pf map for all nodes
|
|
1471
|
+
*/
|
|
1472
|
+
computeInitialPfMap(): Map<CapacityMeshNodeId, number>;
|
|
1473
|
+
/**
|
|
1474
|
+
* Compute the score for the ENTIRE board (all nodes with port points).
|
|
1475
|
+
*/
|
|
1476
|
+
computeBoardScore(): number;
|
|
1477
|
+
/**
|
|
1478
|
+
* Recompute Pf for nodes in a section
|
|
1479
|
+
*/
|
|
1480
|
+
recomputePfForNodes(nodeIds: Set<CapacityMeshNodeId>): void;
|
|
1481
|
+
/**
|
|
1482
|
+
* Create input for createPortPointSection from current state
|
|
1483
|
+
*/
|
|
1484
|
+
getCreatePortPointSectionInput(): CreatePortPointSectionInput;
|
|
1485
|
+
/**
|
|
1486
|
+
* Create a section for optimization
|
|
1487
|
+
*/
|
|
1488
|
+
createSection(params: PortPointSectionParams): PortPointSection;
|
|
1489
|
+
/**
|
|
1490
|
+
* Get nodes with port points for a section (for scoring)
|
|
1491
|
+
*/
|
|
1492
|
+
getSectionNodesWithPortPoints(section: PortPointSection): NodeWithPortPoints[];
|
|
1493
|
+
/**
|
|
1494
|
+
* Get nodes with port points for the section (for HighDensitySolver)
|
|
1495
|
+
*/
|
|
1496
|
+
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
1497
|
+
/**
|
|
1498
|
+
* Find the node with the highest probability of failure
|
|
1499
|
+
*/
|
|
1500
|
+
findHighestPfNode(): CapacityMeshNodeId | null;
|
|
1501
|
+
/** Cut path info for tracking during reattachment */
|
|
1502
|
+
currentSectionCutPathInfo: Map<string, {
|
|
1503
|
+
sectionPath: SectionPath;
|
|
1504
|
+
originalConnectionResult: ConnectionPathResult;
|
|
1505
|
+
}>;
|
|
1506
|
+
/**
|
|
1507
|
+
* Create a SimpleRouteJson for just the section's connections.
|
|
1508
|
+
* Includes both fully contained connections AND cut paths (partial connections
|
|
1509
|
+
* that pass through the section).
|
|
1510
|
+
*/
|
|
1511
|
+
createSectionSimpleRouteJson(section: PortPointSection): SimpleRouteJson;
|
|
1512
|
+
/**
|
|
1513
|
+
* Prepare section input nodes for routing cut paths.
|
|
1514
|
+
* Marks nodes containing cut path endpoints as targets so the solver can route to/from them.
|
|
1515
|
+
*/
|
|
1516
|
+
prepareSectionInputNodesForCutPaths(section: PortPointSection): InputNodeWithPortPoints[];
|
|
1517
|
+
getHyperParametersForAttempt(attempt: number): PortPointPathingHyperParameters;
|
|
1518
|
+
/**
|
|
1519
|
+
* Reattach the optimized section results back to the main state.
|
|
1520
|
+
* Handles both fully contained connections AND cut paths.
|
|
1521
|
+
*/
|
|
1522
|
+
reattachSection(_section: PortPointSection, newConnectionResults: ConnectionPathResult[], newAssignedPortPoints: Map<string, {
|
|
1523
|
+
connectionName: string;
|
|
1524
|
+
rootConnectionName?: string;
|
|
1525
|
+
}>, newNodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>): void;
|
|
1526
|
+
_step(): void;
|
|
1527
|
+
visualize(): GraphicsObject;
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
interface CapacityMeshSolverOptions$2 {
|
|
1531
|
+
capacityDepth?: number;
|
|
1532
|
+
targetMinCapacity?: number;
|
|
1533
|
+
cacheProvider?: CacheProvider | null;
|
|
1534
|
+
}
|
|
1535
|
+
type PipelineStep$2<T extends new (...args: any[]) => BaseSolver> = {
|
|
1536
|
+
solverName: string;
|
|
1537
|
+
solverClass: T;
|
|
1538
|
+
getConstructorParams: (instance: AutoroutingPipelineSolver2_PortPointPathing) => ConstructorParameters<T>;
|
|
1539
|
+
onSolved?: (instance: AutoroutingPipelineSolver2_PortPointPathing) => void;
|
|
1540
|
+
};
|
|
1541
|
+
declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
|
|
1542
|
+
srj: SimpleRouteJson;
|
|
1543
|
+
opts: CapacityMeshSolverOptions$2;
|
|
1544
|
+
netToPointPairsSolver?: NetToPointPairsSolver;
|
|
1545
|
+
nodeSolver?: RectDiffSolver;
|
|
1546
|
+
nodeTargetMerger?: CapacityNodeTargetMerger;
|
|
1547
|
+
edgeSolver?: CapacityMeshEdgeSolver;
|
|
1548
|
+
colorMap: Record<string, string>;
|
|
1549
|
+
highDensityRouteSolver?: HighDensitySolver;
|
|
1550
|
+
highDensityStitchSolver?: MultipleHighDensityRouteStitchSolver;
|
|
1551
|
+
singleLayerNodeMerger?: SingleLayerNodeMergerSolver;
|
|
1552
|
+
strawSolver?: StrawSolver;
|
|
1553
|
+
deadEndSolver?: DeadEndSolver;
|
|
1554
|
+
traceSimplificationSolver?: TraceSimplificationSolver;
|
|
1555
|
+
availableSegmentPointSolver?: AvailableSegmentPointSolver;
|
|
1556
|
+
portPointPathingSolver?: PortPointPathingSolver;
|
|
1557
|
+
multiSectionPortPointOptimizer?: MultiSectionPortPointOptimizer;
|
|
1558
|
+
viaDiameter: number;
|
|
1559
|
+
minTraceWidth: number;
|
|
1560
|
+
startTimeOfPhase: Record<string, number>;
|
|
1561
|
+
endTimeOfPhase: Record<string, number>;
|
|
1562
|
+
timeSpentOnPhase: Record<string, number>;
|
|
1563
|
+
activeSubSolver?: BaseSolver | null;
|
|
1564
|
+
connMap: ConnectivityMap;
|
|
1565
|
+
srjWithPointPairs?: SimpleRouteJson;
|
|
1566
|
+
capacityNodes: CapacityMeshNode[] | null;
|
|
1567
|
+
capacityEdges: CapacityMeshEdge[] | null;
|
|
1568
|
+
cacheProvider: CacheProvider | null;
|
|
1569
|
+
pipelineDef: (PipelineStep$2<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$2<typeof RectDiffSolver> | PipelineStep$2<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$2<typeof AvailableSegmentPointSolver> | PipelineStep$2<typeof PortPointPathingSolver> | PipelineStep$2<typeof MultiSectionPortPointOptimizer> | PipelineStep$2<typeof HighDensitySolver> | PipelineStep$2<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$2<typeof TraceSimplificationSolver>)[];
|
|
1570
|
+
constructor(srj: SimpleRouteJson, opts?: CapacityMeshSolverOptions$2);
|
|
1571
|
+
currentPipelineStepIndex: number;
|
|
1572
|
+
_step(): void;
|
|
1573
|
+
solveUntilPhase(phase: string): void;
|
|
1574
|
+
getCurrentPhase(): string;
|
|
1575
|
+
visualize(): GraphicsObject;
|
|
1576
|
+
/**
|
|
1577
|
+
* A lightweight version of the visualize method that can be used to stream
|
|
1578
|
+
* progress
|
|
1579
|
+
*
|
|
1580
|
+
* We return the most relevant graphic for the stage:
|
|
1581
|
+
* 1. netToPointPairs output
|
|
1582
|
+
* 2. Capacity Planning Output
|
|
1583
|
+
* 3. High Density Route Solver Output, max 200 lines
|
|
1584
|
+
*/
|
|
1585
|
+
preview(): GraphicsObject;
|
|
1586
|
+
_getOutputHdRoutes(): HighDensityRoute$1[];
|
|
1587
|
+
/**
|
|
1588
|
+
* Returns the SimpleRouteJson with routes converted to SimplifiedPcbTraces
|
|
1589
|
+
*/
|
|
1590
|
+
getOutputSimplifiedPcbTraces(): SimplifiedPcbTraces;
|
|
1591
|
+
getOutputSimpleRouteJson(): SimpleRouteJson;
|
|
1592
|
+
}
|
|
1593
|
+
/** @deprecated Use AutoroutingPipelineSolver instead */
|
|
1594
|
+
declare const CapacityMeshSolver: typeof AutoroutingPipelineSolver2_PortPointPathing;
|
|
1595
|
+
type CapacityMeshSolver = AutoroutingPipelineSolver2_PortPointPathing;
|
|
1596
|
+
|
|
1597
|
+
interface NodePortSegment {
|
|
1598
|
+
capacityMeshNodeId: string;
|
|
1599
|
+
nodePortSegmentId?: string;
|
|
1600
|
+
start: {
|
|
1601
|
+
x: number;
|
|
1602
|
+
y: number;
|
|
1603
|
+
};
|
|
1604
|
+
end: {
|
|
1605
|
+
x: number;
|
|
1606
|
+
y: number;
|
|
1607
|
+
};
|
|
1608
|
+
availableZ: number[];
|
|
1609
|
+
connectionNames: string[];
|
|
1610
|
+
rootConnectionNames?: string[];
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
/**
|
|
1614
|
+
* Each Node is a square. The capacity paths indicate the nodes the trace will
|
|
1615
|
+
* travel through. We want to find the "Port Segment" that each capacity path
|
|
1616
|
+
* will take for each node.
|
|
1617
|
+
*/
|
|
1618
|
+
declare class CapacityEdgeToPortSegmentSolver extends BaseSolver {
|
|
1619
|
+
nodes: CapacityMeshNode[];
|
|
1620
|
+
edges: CapacityMeshEdge[];
|
|
1621
|
+
capacityPaths: CapacityPath[];
|
|
1622
|
+
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1623
|
+
nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>;
|
|
1624
|
+
unprocessedNodeIds: CapacityMeshNodeId[];
|
|
1625
|
+
nodePortSegments: Map<CapacityMeshNodeId, NodePortSegment[]>;
|
|
1626
|
+
colorMap: Record<string, string>;
|
|
1627
|
+
constructor({ nodes, edges, capacityPaths, colorMap, }: {
|
|
1628
|
+
nodes: CapacityMeshNode[];
|
|
1629
|
+
edges: CapacityMeshEdge[];
|
|
1630
|
+
capacityPaths: CapacityPath[];
|
|
1631
|
+
colorMap?: Record<string, string>;
|
|
1632
|
+
});
|
|
1633
|
+
step(): void;
|
|
1634
|
+
visualize(): GraphicsObject;
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
interface SegmentWithAssignedPoints extends NodePortSegment {
|
|
1638
|
+
assignedPoints?: {
|
|
1639
|
+
connectionName: string;
|
|
1640
|
+
rootConnectionName?: string;
|
|
1641
|
+
point: {
|
|
1642
|
+
x: number;
|
|
1643
|
+
y: number;
|
|
1644
|
+
z: number;
|
|
1645
|
+
};
|
|
1646
|
+
}[];
|
|
1647
|
+
}
|
|
1648
|
+
/**
|
|
1649
|
+
* CapacitySegmentToPointSolver:
|
|
1650
|
+
*
|
|
1651
|
+
* In each step, the solver iterates over all unsolved segments (segments
|
|
1652
|
+
* without points assigned for each connection). For each segment:
|
|
1653
|
+
*
|
|
1654
|
+
* - If there is only one connection, it assigns the center as the point.
|
|
1655
|
+
* - If there are two connections, it attempts to determine the ordering using
|
|
1656
|
+
* other segments within the node. If no ordering can be determined, it does nothing.
|
|
1657
|
+
*
|
|
1658
|
+
* If an iteration produces no new assignments, the solver picks the segment with
|
|
1659
|
+
* the fewest connections and assigns points evenly spaced along the segment,
|
|
1660
|
+
* ordering them alphabetically.
|
|
1661
|
+
*/
|
|
1662
|
+
declare class CapacitySegmentToPointSolver extends BaseSolver {
|
|
1663
|
+
unsolvedSegments: SegmentWithAssignedPoints[];
|
|
1664
|
+
solvedSegments: (NodePortSegment & {
|
|
1665
|
+
assignedPoints: {
|
|
1666
|
+
connectionName: string;
|
|
1667
|
+
rootConnectionName?: string;
|
|
1668
|
+
point: {
|
|
1669
|
+
x: number;
|
|
1670
|
+
y: number;
|
|
1671
|
+
z: number;
|
|
1672
|
+
};
|
|
1673
|
+
}[];
|
|
1674
|
+
})[];
|
|
1675
|
+
nodeMap: Record<string, CapacityMeshNode>;
|
|
1676
|
+
colorMap: Record<string, string>;
|
|
1677
|
+
constructor({ segments, colorMap, nodes, }: {
|
|
1678
|
+
segments: NodePortSegment[];
|
|
1679
|
+
colorMap?: Record<string, string>;
|
|
1680
|
+
/**
|
|
1681
|
+
* This isn't used by the algorithm, but allows associating metadata
|
|
1682
|
+
* for the result datatype (the center, width, height of the node)
|
|
1683
|
+
*/
|
|
1684
|
+
nodes: CapacityMeshNode[];
|
|
1685
|
+
});
|
|
1686
|
+
/**
|
|
1687
|
+
* Perform one iteration step.
|
|
1688
|
+
*/
|
|
1689
|
+
_step(): void;
|
|
1690
|
+
/**
|
|
1691
|
+
* Return the assigned points for each segment.
|
|
1692
|
+
*/
|
|
1693
|
+
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
1694
|
+
/**
|
|
1695
|
+
* Return a GraphicsObject that visualizes the segments with assigned points.
|
|
1696
|
+
*/
|
|
1697
|
+
visualize(): GraphicsObject;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
type NodePortSegmentId = string;
|
|
1701
|
+
interface ChangeLayerOperation {
|
|
1702
|
+
op: "changeLayer";
|
|
1703
|
+
segmentId: string;
|
|
1704
|
+
pointIndex: number;
|
|
1705
|
+
newLayer: number;
|
|
1706
|
+
/** Operation is mutated and oldLayer is added to allow reversal */
|
|
1707
|
+
oldLayer?: number;
|
|
1708
|
+
cost?: number;
|
|
1709
|
+
}
|
|
1710
|
+
interface SwitchOperation {
|
|
1711
|
+
op: "switch";
|
|
1712
|
+
segmentId: string;
|
|
1713
|
+
point1Index: number;
|
|
1714
|
+
point2Index: number;
|
|
1715
|
+
cost?: number;
|
|
1716
|
+
}
|
|
1717
|
+
interface CombinedOperation {
|
|
1718
|
+
op: "combined";
|
|
1719
|
+
subOperations: Array<SwitchOperation | ChangeLayerOperation>;
|
|
1720
|
+
cost?: number;
|
|
1721
|
+
}
|
|
1722
|
+
type Operation = ChangeLayerOperation | SwitchOperation | CombinedOperation;
|
|
1723
|
+
/**
|
|
1724
|
+
* Use simulated annealing to try to improve the placement of points (via
|
|
1725
|
+
* swapping with points on the same segment) or changing the layer.
|
|
1726
|
+
*
|
|
1727
|
+
* We have the following pieces of information:
|
|
1728
|
+
* - NodePortSegment with nodePortSegmentId
|
|
1729
|
+
* - A "neighbor" NodePortSegmentWithAssignedPoints has one change
|
|
1730
|
+
* - A change can be flipping a point to the opposite layer
|
|
1731
|
+
* - A change can also be switching the position of two points
|
|
1732
|
+
* - We represent the operations used to change from an original scene
|
|
1733
|
+
* with a list of operations [SEG1_CL(1, 1), SEG1_SW(1, 2), SEG2_CL(2, 0)]
|
|
1734
|
+
* - CN indicates the capacity node to edit
|
|
1735
|
+
* - The SW operation "switches" the x/y location of two points
|
|
1736
|
+
* - The CL operation changes the layer of the point
|
|
1737
|
+
* - When choosing edits to make, we are biased to operate on nodes that have a
|
|
1738
|
+
* high cost and biased against operating on nodes we've operated on a lot
|
|
1739
|
+
* - Each step, we generate an operation and use the standard simulated
|
|
1740
|
+
* annealing function to determine if we should perform the operation
|
|
1741
|
+
*/
|
|
1742
|
+
declare class CapacitySegmentPointOptimizer extends BaseSolver {
|
|
1743
|
+
assignedSegments: SegmentWithAssignedPoints[];
|
|
1744
|
+
colorMap: Record<string, string>;
|
|
1745
|
+
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1746
|
+
nodeIdToSegmentIds: Map<string, string[]>;
|
|
1747
|
+
segmentIdToNodeIds: Map<string, string[]>;
|
|
1748
|
+
currentMutatedSegments: Map<NodePortSegmentId, SegmentWithAssignedPoints>;
|
|
1749
|
+
allSegmentIds: string[];
|
|
1750
|
+
lastAppliedOperation: Operation | null;
|
|
1751
|
+
lastCreatedOperation: Operation | null;
|
|
1752
|
+
currentNodeCosts: Map<CapacityMeshNodeId, number>;
|
|
1753
|
+
lastAcceptedIteration: number;
|
|
1754
|
+
currentCost: number;
|
|
1755
|
+
randomSeed: number;
|
|
1756
|
+
numNodes: number;
|
|
1757
|
+
probabilityOfFailure: number;
|
|
1758
|
+
nodesThatCantFitVias: Set<CapacityMeshNodeId>;
|
|
1759
|
+
mutableSegments: Set<NodePortSegmentId>;
|
|
1760
|
+
VIA_DIAMETER: number;
|
|
1761
|
+
OBSTACLE_MARGIN: number;
|
|
1762
|
+
MAX_OPERATIONS_PER_MUTATION: number;
|
|
1763
|
+
MAX_NODE_CHAIN_PER_MUTATION: number;
|
|
1764
|
+
NOOP_ITERATIONS_BEFORE_EARLY_STOP: number;
|
|
1765
|
+
constructor({ assignedSegments, colorMap, nodes, viaDiameter, }: {
|
|
1766
|
+
assignedSegments: NodePortSegment[];
|
|
1767
|
+
colorMap?: Record<string, string>;
|
|
1768
|
+
/**
|
|
1769
|
+
* This isn't used by the algorithm, but allows associating metadata
|
|
1770
|
+
* for the result datatype (the center, width, height of the node)
|
|
1771
|
+
*/
|
|
1772
|
+
nodes: CapacityMeshNode[];
|
|
1773
|
+
viaDiameter?: number;
|
|
1774
|
+
});
|
|
1775
|
+
random(): number;
|
|
1776
|
+
/**
|
|
1777
|
+
* The cost is the "probability of failure" of the node.
|
|
1778
|
+
*/
|
|
1779
|
+
computeNodeCost(nodeId: CapacityMeshNodeId): number;
|
|
1780
|
+
/**
|
|
1781
|
+
* Number of traces that can go through this node if they are completely
|
|
1782
|
+
* straight without crossings
|
|
1783
|
+
*/
|
|
1784
|
+
getUsedTraceCapacity(nodeId: CapacityMeshNodeId): number;
|
|
1785
|
+
/**
|
|
1786
|
+
* Granular via capacity is a consideration of capacity that includes...
|
|
1787
|
+
* - The number of traces
|
|
1788
|
+
* - The number of trace crossings (0-2 vias per trace crossing)
|
|
1789
|
+
* - Empirically, each crossing typically results in 0.82 vias
|
|
1790
|
+
* - e.g. 17 traces would typically have 51 crossings & 42 vias
|
|
1791
|
+
* - The number of layer changes (at least 1 via per layer change)
|
|
1792
|
+
* - We don't know how a entry/exit being on separated layers effects
|
|
1793
|
+
* the capacity/number of vias yet
|
|
1794
|
+
*
|
|
1795
|
+
* - Generally minimizing the number of crossings is pretty good, if there
|
|
1796
|
+
* is no trace crossing you basically don't have any used capacity
|
|
1797
|
+
* - If the entry/exit layer is different, you're guaranteed to have at least
|
|
1798
|
+
* one via
|
|
1799
|
+
*
|
|
1800
|
+
* - Total capacity is computed by estimating the number of vias that could
|
|
1801
|
+
* be created using the formula (viaFitAcross / 2) ** 1.1
|
|
1802
|
+
*/
|
|
1803
|
+
getUsedViaCapacity(nodeId: CapacityMeshNodeId): number;
|
|
1804
|
+
getRandomWeightedNodeId(): CapacityMeshNodeId;
|
|
1805
|
+
getRandomWeightedSegmentId(): string;
|
|
1806
|
+
getMutableSegments(): Set<string>;
|
|
1807
|
+
isSegmentMutable(segmentId: string): boolean;
|
|
1808
|
+
getRandomOperationForSegment(randomSegmentId: string): SwitchOperation | ChangeLayerOperation | null;
|
|
1809
|
+
getNodesNearNode(nodeId: CapacityMeshNodeId, hops?: number): CapacityMeshNodeId[];
|
|
1810
|
+
getRandomCombinedOperationNearNode(nodeId: CapacityMeshNodeId): CombinedOperation;
|
|
1811
|
+
/**
|
|
1812
|
+
* A combined operation can perform multiple operations on a single node, this
|
|
1813
|
+
* allows it to reach outcomes that may not be beneficial with since
|
|
1814
|
+
* operations
|
|
1815
|
+
*/
|
|
1816
|
+
getRandomCombinedOperationOnSingleNode(max?: number): CombinedOperation;
|
|
1817
|
+
getRandomOperation(): Operation;
|
|
1818
|
+
/**
|
|
1819
|
+
* We compute "overall probability of failure" as our overall cost, then
|
|
1820
|
+
* linearize it to make it easier to work with
|
|
1821
|
+
*/
|
|
1822
|
+
computeCurrentCost(): {
|
|
1823
|
+
cost: number;
|
|
1824
|
+
nodeCosts: Map<CapacityMeshNodeId, number>;
|
|
1825
|
+
probabilityOfFailure: number;
|
|
1826
|
+
linearizedCost: number;
|
|
1827
|
+
};
|
|
1828
|
+
applyOperation(op: Operation): void;
|
|
1829
|
+
reverseOperation(op: Operation): void;
|
|
1830
|
+
isNewCostAcceptable(oldPf: number, newPf: number): boolean;
|
|
1831
|
+
/**
|
|
1832
|
+
* FOR OUTPUT: Return the assigned points for each segment.
|
|
1833
|
+
*/
|
|
1834
|
+
getNodesWithPortPoints(): NodeWithPortPoints[];
|
|
1835
|
+
_step(): void;
|
|
1836
|
+
visualize(): GraphicsObject;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
type SegmentPointId = string;
|
|
1840
|
+
type SegmentId = string;
|
|
1841
|
+
interface BaseUnravelIssue {
|
|
1842
|
+
probabilityOfFailure: number;
|
|
1843
|
+
}
|
|
1844
|
+
interface UnravelTransitionViaIssue extends BaseUnravelIssue {
|
|
1845
|
+
type: "transition_via";
|
|
1846
|
+
capacityMeshNodeId: CapacityMeshNodeId;
|
|
1847
|
+
segmentPoints: SegmentPointId[];
|
|
1848
|
+
}
|
|
1849
|
+
interface UnravelSameLayerCrossingIssue extends BaseUnravelIssue {
|
|
1850
|
+
type: "same_layer_crossing";
|
|
1851
|
+
capacityMeshNodeId: CapacityMeshNodeId;
|
|
1852
|
+
crossingLine1: [SegmentPointId, SegmentPointId];
|
|
1072
1853
|
crossingLine2: [SegmentPointId, SegmentPointId];
|
|
1073
1854
|
}
|
|
1074
1855
|
interface UnravelSingleTransitionCrossingIssue extends BaseUnravelIssue {
|
|
@@ -1602,191 +2383,6 @@ declare class CapacityPathingMultiSectionSolver extends BaseSolver {
|
|
|
1602
2383
|
visualize(): graphics_debug.GraphicsObject;
|
|
1603
2384
|
}
|
|
1604
2385
|
|
|
1605
|
-
declare class StrawSolver extends BaseSolver {
|
|
1606
|
-
multiLayerNodes: CapacityMeshNode[];
|
|
1607
|
-
strawNodes: CapacityMeshNode[];
|
|
1608
|
-
skippedNodes: CapacityMeshNode[];
|
|
1609
|
-
unprocessedNodes: CapacityMeshNode[];
|
|
1610
|
-
strawSize: number;
|
|
1611
|
-
nodeIdCounter: number;
|
|
1612
|
-
constructor(params: {
|
|
1613
|
-
nodes: CapacityMeshNode[];
|
|
1614
|
-
strawSize?: number;
|
|
1615
|
-
});
|
|
1616
|
-
getCapacityOfMultiLayerNodesWithinBounds(bounds: {
|
|
1617
|
-
minX: number;
|
|
1618
|
-
maxX: number;
|
|
1619
|
-
minY: number;
|
|
1620
|
-
maxY: number;
|
|
1621
|
-
}): number;
|
|
1622
|
-
getSurroundingCapacities(node: CapacityMeshNode): {
|
|
1623
|
-
leftSurroundingCapacity: number;
|
|
1624
|
-
rightSurroundingCapacity: number;
|
|
1625
|
-
topSurroundingCapacity: number;
|
|
1626
|
-
bottomSurroundingCapacity: number;
|
|
1627
|
-
};
|
|
1628
|
-
/**
|
|
1629
|
-
* Creates straw nodes from a single-layer node based on surrounding capacities
|
|
1630
|
-
*/
|
|
1631
|
-
createStrawsForNode(node: CapacityMeshNode): CapacityMeshNode[];
|
|
1632
|
-
getResultNodes(): CapacityMeshNode[];
|
|
1633
|
-
_step(): void;
|
|
1634
|
-
visualize(): GraphicsObject;
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
/**
|
|
1638
|
-
* Merges same layer nodes into larger nodes. Pre-processing stage necessary
|
|
1639
|
-
* for "strawing".
|
|
1640
|
-
*/
|
|
1641
|
-
declare class SingleLayerNodeMergerSolver extends BaseSolver {
|
|
1642
|
-
nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1643
|
-
currentBatchNodeIds: CapacityMeshNodeId[];
|
|
1644
|
-
absorbedNodeIds: Set<CapacityMeshNodeId>;
|
|
1645
|
-
nextBatchNodeIds: CapacityMeshNodeId[];
|
|
1646
|
-
batchHadModifications: boolean;
|
|
1647
|
-
hasComputedAdjacentNodeIds: boolean;
|
|
1648
|
-
newNodes: CapacityMeshNode[];
|
|
1649
|
-
constructor(nodes: CapacityMeshNode[]);
|
|
1650
|
-
computeAdjacentNodeIdsForFirstBatch(nodes: CapacityMeshNode[]): void;
|
|
1651
|
-
getAdjacentSameLayerUnprocessedNodes(rootNode: CapacityMeshNode): CapacityMeshNode[];
|
|
1652
|
-
getAdjacentSameLayerUnprocessedNodes2(rootNode: CapacityMeshNode): CapacityMeshNode[];
|
|
1653
|
-
_step(): void;
|
|
1654
|
-
visualize(): GraphicsObject;
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
declare class CapacityMeshEdgeSolver2_NodeTreeOptimization extends CapacityMeshEdgeSolver {
|
|
1658
|
-
nodes: CapacityMeshNode[];
|
|
1659
|
-
private nodeTree;
|
|
1660
|
-
private currentNodeIndex;
|
|
1661
|
-
private edgeSet;
|
|
1662
|
-
constructor(nodes: CapacityMeshNode[]);
|
|
1663
|
-
_step(): void;
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
declare class DeadEndSolver extends BaseSolver {
|
|
1667
|
-
removedNodeIds: Set<string>;
|
|
1668
|
-
private targetNodeIds;
|
|
1669
|
-
private leaves;
|
|
1670
|
-
private leavesIndex;
|
|
1671
|
-
private adjacencyList;
|
|
1672
|
-
/** Only used for visualization, dynamically instantiated if necessary */
|
|
1673
|
-
nodeMap?: Map<CapacityMeshNodeId, CapacityMeshNode>;
|
|
1674
|
-
private nodes;
|
|
1675
|
-
private edges;
|
|
1676
|
-
constructor({ nodes, edges, }: {
|
|
1677
|
-
nodes: CapacityMeshNode[];
|
|
1678
|
-
edges: CapacityMeshEdge[];
|
|
1679
|
-
});
|
|
1680
|
-
_step(): void;
|
|
1681
|
-
visualize(): GraphicsObject;
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
/**
|
|
1685
|
-
* A Disjoint Set Union (DSU) or Union-Find data structure.
|
|
1686
|
-
* It tracks a collection of disjoint sets and can efficiently merge them.
|
|
1687
|
-
*/
|
|
1688
|
-
declare class DSU {
|
|
1689
|
-
private parent;
|
|
1690
|
-
/**
|
|
1691
|
-
* Creates a new DSU instance.
|
|
1692
|
-
* Each ID is initially in its own set.
|
|
1693
|
-
*/
|
|
1694
|
-
constructor(ids: string[]);
|
|
1695
|
-
/**
|
|
1696
|
-
* Finds the representative of the set containing the given ID.
|
|
1697
|
-
* Uses path compression.
|
|
1698
|
-
*/
|
|
1699
|
-
find(id: string): string;
|
|
1700
|
-
/**
|
|
1701
|
-
* Merges the sets containing the two given IDs.
|
|
1702
|
-
*/
|
|
1703
|
-
union(id1: string, id2: string): void;
|
|
1704
|
-
/**
|
|
1705
|
-
* Gets all IDs in the same set as the given ID.
|
|
1706
|
-
*/
|
|
1707
|
-
getGroup(id: string): string[];
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
/**
|
|
1711
|
-
* Extends the base NetToPointPairsSolver with an optimization that utilizes
|
|
1712
|
-
* off-board connections to find shorter routing paths.
|
|
1713
|
-
*
|
|
1714
|
-
* This solver preprocesses all connections to identify points that are
|
|
1715
|
-
* electrically connected off-board (via the `isOffBoard` flag). It builds
|
|
1716
|
-
* "equivalence groups" of these points using a Disjoint Set Union (DSU)
|
|
1717
|
-
* data structure.
|
|
1718
|
-
*
|
|
1719
|
-
* When the solver processes an on-board connection or a segment from a
|
|
1720
|
-
* Minimum Spanning Tree (MST), it checks if either of the connection's
|
|
1721
|
-
* endpoints has an off-board equivalent. If so, it calculates the distance
|
|
1722
|
-
* to all possible substitutes and chooses the pair that results in the
|
|
1723
|
-
* shortest path, potentially rerouting the connection to a more optimal
|
|
1724
|
-
* equivalent point.
|
|
1725
|
-
*/
|
|
1726
|
-
declare class NetToPointPairsSolver2_OffBoardConnection extends NetToPointPairsSolver {
|
|
1727
|
-
ogSrj: SimpleRouteJson;
|
|
1728
|
-
colorMap: Record<string, string>;
|
|
1729
|
-
connectionPointDsu: DSU;
|
|
1730
|
-
connectionPointMap: Map<string, ConnectionPoint>;
|
|
1731
|
-
constructor(ogSrj: SimpleRouteJson, colorMap?: Record<string, string>);
|
|
1732
|
-
_findBestConnectionPointsFromDisjointSets(sourcePoint: ConnectionPoint, targetPoint: ConnectionPoint): {
|
|
1733
|
-
pointsToConnect: [ConnectionPoint, ConnectionPoint];
|
|
1734
|
-
};
|
|
1735
|
-
_step(): void;
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
type Phase = "via_removal" | "via_merging" | "path_simplification";
|
|
1739
|
-
/**
|
|
1740
|
-
* TraceSimplificationSolver consolidates trace optimization by iteratively applying
|
|
1741
|
-
* via removal, via merging, and path simplification phases. It reduces redundant vias
|
|
1742
|
-
* and simplifies routing paths through configurable iterations.
|
|
1743
|
-
*
|
|
1744
|
-
* The solver operates in three alternating phases per iteration:
|
|
1745
|
-
* 1. "via_removal" - Removes unnecessary vias from routes using UselessViaRemovalSolver
|
|
1746
|
-
* 2. "via_merging" - Merges redundant vias on the same net using SameNetViaMergerSolver
|
|
1747
|
-
* 3. "path_simplification" - Simplifies routing paths using MultiSimplifiedPathSolver
|
|
1748
|
-
*
|
|
1749
|
-
* Each iteration consists of all phases executed sequentially.
|
|
1750
|
-
*/
|
|
1751
|
-
declare class TraceSimplificationSolver extends BaseSolver {
|
|
1752
|
-
private simplificationConfig;
|
|
1753
|
-
hdRoutes: HighDensityRoute$1[];
|
|
1754
|
-
simplificationPipelineLoops: number;
|
|
1755
|
-
MAX_SIMPLIFICATION_PIPELINE_LOOPS: number;
|
|
1756
|
-
PHASE_ORDER: Phase[];
|
|
1757
|
-
currentPhase: Phase;
|
|
1758
|
-
/** Callback to extract results from the active sub-solver */
|
|
1759
|
-
extractResult: ((solver: BaseSolver) => HighDensityRoute$1[]) | null;
|
|
1760
|
-
/** Returns the simplified routes. This is the primary output of the solver. */
|
|
1761
|
-
get simplifiedHdRoutes(): HighDensityRoute$1[];
|
|
1762
|
-
/**
|
|
1763
|
-
* Creates a new TraceSimplificationSolver
|
|
1764
|
-
* @param simplificationConfig Configuration object containing:
|
|
1765
|
-
* - hdRoutes: Initial high-density routes to simplify
|
|
1766
|
-
* - obstacles: Board obstacles to avoid during simplification
|
|
1767
|
-
* - connMap: Connectivity map for routing validation
|
|
1768
|
-
* - colorMap: Mapping of net names to colors for visualization
|
|
1769
|
-
* - outline: Optional board outline boundary
|
|
1770
|
-
* - defaultViaDiameter: Default diameter for vias
|
|
1771
|
-
* - layerCount: Number of routing layers
|
|
1772
|
-
* - iterations: Number of complete simplification iterations (default: 2)
|
|
1773
|
-
*/
|
|
1774
|
-
constructor(simplificationConfig: {
|
|
1775
|
-
hdRoutes: HighDensityRoute$1[];
|
|
1776
|
-
obstacles: Obstacle[];
|
|
1777
|
-
connMap: ConnectivityMap;
|
|
1778
|
-
colorMap: Record<string, string>;
|
|
1779
|
-
outline?: Array<{
|
|
1780
|
-
x: number;
|
|
1781
|
-
y: number;
|
|
1782
|
-
}>;
|
|
1783
|
-
defaultViaDiameter: number;
|
|
1784
|
-
layerCount: number;
|
|
1785
|
-
});
|
|
1786
|
-
_step(): void;
|
|
1787
|
-
visualize(): GraphicsObject;
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
2386
|
interface CapacityMeshSolverOptions$1 {
|
|
1791
2387
|
capacityDepth?: number;
|
|
1792
2388
|
targetMinCapacity?: number;
|
|
@@ -1795,10 +2391,10 @@ interface CapacityMeshSolverOptions$1 {
|
|
|
1795
2391
|
type PipelineStep$1<T extends new (...args: any[]) => BaseSolver> = {
|
|
1796
2392
|
solverName: string;
|
|
1797
2393
|
solverClass: T;
|
|
1798
|
-
getConstructorParams: (instance:
|
|
1799
|
-
onSolved?: (instance:
|
|
2394
|
+
getConstructorParams: (instance: AutoroutingPipeline1_OriginalUnravel) => ConstructorParameters<T>;
|
|
2395
|
+
onSolved?: (instance: AutoroutingPipeline1_OriginalUnravel) => void;
|
|
1800
2396
|
};
|
|
1801
|
-
declare class
|
|
2397
|
+
declare class AutoroutingPipeline1_OriginalUnravel extends BaseSolver {
|
|
1802
2398
|
srj: SimpleRouteJson;
|
|
1803
2399
|
opts: CapacityMeshSolverOptions$1;
|
|
1804
2400
|
netToPointPairsSolver?: NetToPointPairsSolver;
|
|
@@ -1853,9 +2449,6 @@ declare class AutoroutingPipelineSolver extends BaseSolver {
|
|
|
1853
2449
|
getOutputSimplifiedPcbTraces(): SimplifiedPcbTraces;
|
|
1854
2450
|
getOutputSimpleRouteJson(): SimpleRouteJson;
|
|
1855
2451
|
}
|
|
1856
|
-
/** @deprecated Use AutoroutingPipelineSolver instead */
|
|
1857
|
-
declare const CapacityMeshSolver: typeof AutoroutingPipelineSolver;
|
|
1858
|
-
type CapacityMeshSolver = AutoroutingPipelineSolver;
|
|
1859
2452
|
|
|
1860
2453
|
/**
|
|
1861
2454
|
* Calculate the capacity of a node based on its width
|
|
@@ -2685,4 +3278,4 @@ declare const convertSrjToGraphicsObject: (srj: SimpleRouteJson) => {
|
|
|
2685
3278
|
points: Point$3[];
|
|
2686
3279
|
};
|
|
2687
3280
|
|
|
2688
|
-
export { AssignableViaAutoroutingPipelineSolver, AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };
|
|
3281
|
+
export { AssignableViaAutoroutingPipelineSolver, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver2_PortPointPathing as AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };
|