@tscircuit/matchpack 0.0.17 → 0.0.19
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 +2 -0
- package/dist/index.js +87 -68
- package/package.json +16 -14
package/dist/index.d.ts
CHANGED
|
@@ -238,7 +238,9 @@ declare class PartitionPackingSolver extends BaseSolver {
|
|
|
238
238
|
finalLayout: OutputLayout | null;
|
|
239
239
|
packSolver2: PackSolver2 | null;
|
|
240
240
|
constructor(input: PartitionPackingSolverInput);
|
|
241
|
+
private partitionHasFixedChip;
|
|
241
242
|
_step(): void;
|
|
243
|
+
private buildConnectivityMap;
|
|
242
244
|
private organizePackedPartitions;
|
|
243
245
|
private createPackInput;
|
|
244
246
|
private applyPackingResult;
|
package/dist/index.js
CHANGED
|
@@ -95,6 +95,10 @@ function getRotatedDimensions(width, height, rotation) {
|
|
|
95
95
|
}
|
|
96
96
|
return { width, height };
|
|
97
97
|
}
|
|
98
|
+
function getChipLabelFontSize(width, height) {
|
|
99
|
+
const smallerDimension = Math.min(width, height);
|
|
100
|
+
return Math.min(0.35, Math.max(0.08, smallerDimension * 0.22));
|
|
101
|
+
}
|
|
98
102
|
function visualizeInputProblem(inputProblem, basicLayout) {
|
|
99
103
|
const inputViz = {
|
|
100
104
|
points: [],
|
|
@@ -138,9 +142,16 @@ function visualizeInputProblem(inputProblem, basicLayout) {
|
|
|
138
142
|
center: { x: chipCenterX, y: chipCenterY },
|
|
139
143
|
width: rotatedDims.width,
|
|
140
144
|
height: rotatedDims.height,
|
|
141
|
-
label: chipId
|
|
145
|
+
label: chipId,
|
|
146
|
+
fill: "rgba(59, 130, 246, 0.12)",
|
|
147
|
+
stroke: "none"
|
|
148
|
+
});
|
|
149
|
+
inputViz.texts.push({
|
|
150
|
+
x: chipCenterX,
|
|
151
|
+
y: chipCenterY,
|
|
152
|
+
text: chipId,
|
|
153
|
+
fontSize: getChipLabelFontSize(rotatedDims.width, rotatedDims.height)
|
|
142
154
|
});
|
|
143
|
-
inputViz.texts.push({ x: chipCenterX, y: chipCenterY, text: chipId });
|
|
144
155
|
for (const pin of chipPins) {
|
|
145
156
|
const rotatedOffset = rotatePoint(
|
|
146
157
|
pin.offset,
|
|
@@ -823,9 +834,12 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
|
|
|
823
834
|
}
|
|
824
835
|
_step() {
|
|
825
836
|
if (!this.activeSubSolver) {
|
|
826
|
-
const
|
|
837
|
+
const pinToNetworkMap = createFilteredNetworkMapping({
|
|
838
|
+
inputProblem: this.partitionInputProblem,
|
|
839
|
+
pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
|
|
840
|
+
}).pinToNetworkMap;
|
|
841
|
+
const packInput = this.createPackInput(pinToNetworkMap);
|
|
827
842
|
this.activeSubSolver = new PackSolver2(packInput);
|
|
828
|
-
this.activeSubSolver = this.activeSubSolver;
|
|
829
843
|
}
|
|
830
844
|
this.activeSubSolver.step();
|
|
831
845
|
if (this.activeSubSolver.failed) {
|
|
@@ -841,11 +855,7 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
|
|
|
841
855
|
this.activeSubSolver = null;
|
|
842
856
|
}
|
|
843
857
|
}
|
|
844
|
-
createPackInput() {
|
|
845
|
-
const pinToNetworkMap = createFilteredNetworkMapping({
|
|
846
|
-
inputProblem: this.partitionInputProblem,
|
|
847
|
-
pinIdToStronglyConnectedPins: this.pinIdToStronglyConnectedPins
|
|
848
|
-
}).pinToNetworkMap;
|
|
858
|
+
createPackInput(pinToNetworkMap) {
|
|
849
859
|
const packComponents = Object.entries(
|
|
850
860
|
this.partitionInputProblem.chipMap
|
|
851
861
|
).map(([chipId, chip]) => {
|
|
@@ -860,7 +870,6 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
|
|
|
860
870
|
type: "rect",
|
|
861
871
|
offset: { x: pin.offset.x, y: pin.offset.y },
|
|
862
872
|
size: { x: PIN_SIZE, y: PIN_SIZE }
|
|
863
|
-
// Small size for pins
|
|
864
873
|
});
|
|
865
874
|
}
|
|
866
875
|
const padsBoundingBox = getPadsBoundingBox(pads);
|
|
@@ -878,10 +887,16 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
|
|
|
878
887
|
y: Math.max(padsBoundingBoxSize.y, chip.size.y)
|
|
879
888
|
}
|
|
880
889
|
});
|
|
890
|
+
const fixedRotation = chip.availableRotations?.[0] ?? 0;
|
|
881
891
|
return {
|
|
882
892
|
componentId: chipId,
|
|
883
893
|
pads,
|
|
884
|
-
availableRotationDegrees: chip.availableRotations
|
|
894
|
+
availableRotationDegrees: chip.availableRotations ?? [0, 90, 180, 270],
|
|
895
|
+
...chip.fixedPosition && {
|
|
896
|
+
isStatic: true,
|
|
897
|
+
center: chip.fixedPosition,
|
|
898
|
+
ccwRotationOffset: fixedRotation
|
|
899
|
+
}
|
|
885
900
|
};
|
|
886
901
|
});
|
|
887
902
|
let minGap = this.partitionInputProblem.chipGap;
|
|
@@ -902,7 +917,7 @@ var SingleInnerPartitionPackingSolver = class extends BaseSolver {
|
|
|
902
917
|
chipPlacements[chipId] = {
|
|
903
918
|
x: packedComponent.center.x,
|
|
904
919
|
y: packedComponent.center.y,
|
|
905
|
-
ccwRotationDegrees: packedComponent.
|
|
920
|
+
ccwRotationDegrees: packedComponent.ccwRotationDegrees ?? packedComponent.ccwRotationOffset ?? 0
|
|
906
921
|
};
|
|
907
922
|
}
|
|
908
923
|
return {
|
|
@@ -1007,13 +1022,17 @@ var PartitionPackingSolver = class extends BaseSolver {
|
|
|
1007
1022
|
this.packedPartitions = input.packedPartitions;
|
|
1008
1023
|
this.inputProblem = input.inputProblem;
|
|
1009
1024
|
}
|
|
1025
|
+
partitionHasFixedChip(partitionIndex) {
|
|
1026
|
+
const packedPartition = this.packedPartitions[partitionIndex];
|
|
1027
|
+
if (!packedPartition) return false;
|
|
1028
|
+
return Object.values(packedPartition.inputProblem.chipMap).some(
|
|
1029
|
+
(chip) => chip.fixedPosition !== void 0
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1010
1032
|
_step() {
|
|
1011
1033
|
try {
|
|
1012
1034
|
if (this.packedPartitions.length === 0) {
|
|
1013
|
-
this.finalLayout = {
|
|
1014
|
-
chipPlacements: {},
|
|
1015
|
-
groupPlacements: {}
|
|
1016
|
-
};
|
|
1035
|
+
this.finalLayout = { chipPlacements: {}, groupPlacements: {} };
|
|
1017
1036
|
this.solved = true;
|
|
1018
1037
|
return;
|
|
1019
1038
|
}
|
|
@@ -1048,6 +1067,35 @@ var PartitionPackingSolver = class extends BaseSolver {
|
|
|
1048
1067
|
this.error = `Failed to pack partitions: ${error}`;
|
|
1049
1068
|
}
|
|
1050
1069
|
}
|
|
1070
|
+
buildConnectivityMap() {
|
|
1071
|
+
const pinToNetworkMap = /* @__PURE__ */ new Map();
|
|
1072
|
+
for (const packedPartition of this.packedPartitions) {
|
|
1073
|
+
for (const [connKey, connected] of Object.entries(
|
|
1074
|
+
packedPartition.inputProblem.netConnMap
|
|
1075
|
+
)) {
|
|
1076
|
+
if (!connected) continue;
|
|
1077
|
+
const [pinId, netId] = connKey.split("-");
|
|
1078
|
+
if (pinId && netId) pinToNetworkMap.set(pinId, netId);
|
|
1079
|
+
}
|
|
1080
|
+
for (const [connKey, connected] of Object.entries(
|
|
1081
|
+
packedPartition.inputProblem.pinStrongConnMap
|
|
1082
|
+
)) {
|
|
1083
|
+
if (!connected) continue;
|
|
1084
|
+
const pins = connKey.split("-");
|
|
1085
|
+
if (pins.length === 2 && pins[0] && pins[1]) {
|
|
1086
|
+
const existingNet = pinToNetworkMap.get(pins[0]) || pinToNetworkMap.get(pins[1]);
|
|
1087
|
+
if (existingNet) {
|
|
1088
|
+
pinToNetworkMap.set(pins[0], existingNet);
|
|
1089
|
+
pinToNetworkMap.set(pins[1], existingNet);
|
|
1090
|
+
} else {
|
|
1091
|
+
pinToNetworkMap.set(pins[0], connKey);
|
|
1092
|
+
pinToNetworkMap.set(pins[1], connKey);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return pinToNetworkMap;
|
|
1098
|
+
}
|
|
1051
1099
|
organizePackedPartitions() {
|
|
1052
1100
|
const partitionGroups = [];
|
|
1053
1101
|
for (let i = 0; i < this.packedPartitions.length; i++) {
|
|
@@ -1078,47 +1126,20 @@ var PartitionPackingSolver = class extends BaseSolver {
|
|
|
1078
1126
|
minY = Math.min(minY, chipMinY);
|
|
1079
1127
|
maxY = Math.max(maxY, chipMaxY);
|
|
1080
1128
|
}
|
|
1081
|
-
const bounds = { minX, maxX, minY, maxY };
|
|
1082
1129
|
partitionGroups.push({
|
|
1083
1130
|
partitionIndex: i,
|
|
1084
1131
|
chipIds: partitionChipIds,
|
|
1085
|
-
bounds
|
|
1132
|
+
bounds: { minX, maxX, minY, maxY }
|
|
1086
1133
|
});
|
|
1087
1134
|
}
|
|
1088
1135
|
}
|
|
1089
1136
|
return partitionGroups;
|
|
1090
1137
|
}
|
|
1091
|
-
createPackInput(
|
|
1092
|
-
const pinToNetworkMap =
|
|
1093
|
-
|
|
1094
|
-
for (const [connKey, connected] of Object.entries(
|
|
1095
|
-
packedPartition.inputProblem.netConnMap
|
|
1096
|
-
)) {
|
|
1097
|
-
if (!connected) continue;
|
|
1098
|
-
const [pinId, netId] = connKey.split("-");
|
|
1099
|
-
if (pinId && netId) {
|
|
1100
|
-
pinToNetworkMap.set(pinId, netId);
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
for (const [connKey, connected] of Object.entries(
|
|
1104
|
-
packedPartition.inputProblem.pinStrongConnMap
|
|
1105
|
-
)) {
|
|
1106
|
-
if (!connected) continue;
|
|
1107
|
-
const pins = connKey.split("-");
|
|
1108
|
-
if (pins.length === 2 && pins[0] && pins[1]) {
|
|
1109
|
-
const existingNet = pinToNetworkMap.get(pins[0]) || pinToNetworkMap.get(pins[1]);
|
|
1110
|
-
if (existingNet) {
|
|
1111
|
-
pinToNetworkMap.set(pins[0], existingNet);
|
|
1112
|
-
pinToNetworkMap.set(pins[1], existingNet);
|
|
1113
|
-
} else {
|
|
1114
|
-
pinToNetworkMap.set(pins[0], connKey);
|
|
1115
|
-
pinToNetworkMap.set(pins[1], connKey);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
const packComponents = partitionGroups.map((group) => {
|
|
1138
|
+
createPackInput(groups) {
|
|
1139
|
+
const pinToNetworkMap = this.buildConnectivityMap();
|
|
1140
|
+
const packComponents = groups.map((group) => {
|
|
1121
1141
|
const packedPartition = this.packedPartitions[group.partitionIndex];
|
|
1142
|
+
const isFixed = this.partitionHasFixedChip(group.partitionIndex);
|
|
1122
1143
|
const partitionWidth = group.bounds.maxX - group.bounds.minX;
|
|
1123
1144
|
const partitionHeight = group.bounds.maxY - group.bounds.minY;
|
|
1124
1145
|
const centerX = (group.bounds.minX + group.bounds.maxX) / 2;
|
|
@@ -1136,37 +1157,32 @@ var PartitionPackingSolver = class extends BaseSolver {
|
|
|
1136
1157
|
}
|
|
1137
1158
|
];
|
|
1138
1159
|
const addedNetworks = /* @__PURE__ */ new Set();
|
|
1139
|
-
const pinPositions = /* @__PURE__ */ new Map();
|
|
1140
1160
|
for (const chipId of group.chipIds) {
|
|
1141
1161
|
const chipPlacement = packedPartition.layout.chipPlacements[chipId];
|
|
1142
1162
|
const chip = packedPartition.inputProblem.chipMap[chipId];
|
|
1143
1163
|
for (const pinId of chip.pins) {
|
|
1144
1164
|
const chipPin = packedPartition.inputProblem.chipPinMap[pinId];
|
|
1145
1165
|
if (!chipPin) continue;
|
|
1146
|
-
let
|
|
1147
|
-
const
|
|
1148
|
-
if (
|
|
1149
|
-
|
|
1150
|
-
} else if (
|
|
1151
|
-
|
|
1152
|
-
} else if (
|
|
1153
|
-
|
|
1166
|
+
let rotatedPinOffset = { x: chipPin.offset.x, y: chipPin.offset.y };
|
|
1167
|
+
const chipRotationDeg = chipPlacement.ccwRotationDegrees ?? 0;
|
|
1168
|
+
if (chipRotationDeg === 90) {
|
|
1169
|
+
rotatedPinOffset = { x: -chipPin.offset.y, y: chipPin.offset.x };
|
|
1170
|
+
} else if (chipRotationDeg === 180) {
|
|
1171
|
+
rotatedPinOffset = { x: -chipPin.offset.x, y: -chipPin.offset.y };
|
|
1172
|
+
} else if (chipRotationDeg === 270) {
|
|
1173
|
+
rotatedPinOffset = { x: chipPin.offset.y, y: -chipPin.offset.x };
|
|
1154
1174
|
}
|
|
1155
|
-
const absolutePinX = chipPlacement.x +
|
|
1156
|
-
const absolutePinY = chipPlacement.y +
|
|
1157
|
-
|
|
1158
|
-
const networkId = pinToNetworkMap.get(pinId) || `${pinId}_disconnected`;
|
|
1175
|
+
const absolutePinX = chipPlacement.x + rotatedPinOffset.x;
|
|
1176
|
+
const absolutePinY = chipPlacement.y + rotatedPinOffset.y;
|
|
1177
|
+
const networkId = pinToNetworkMap.get(pinId) ?? `${pinId}_disconnected`;
|
|
1159
1178
|
if (!addedNetworks.has(networkId)) {
|
|
1160
1179
|
addedNetworks.add(networkId);
|
|
1161
|
-
const padOffsetX = absolutePinX - centerX;
|
|
1162
|
-
const padOffsetY = absolutePinY - centerY;
|
|
1163
1180
|
pads.push({
|
|
1164
1181
|
padId: `${group.partitionIndex}_pin_${pinId}`,
|
|
1165
1182
|
networkId,
|
|
1166
1183
|
type: "rect",
|
|
1167
|
-
offset: { x:
|
|
1184
|
+
offset: { x: absolutePinX - centerX, y: absolutePinY - centerY },
|
|
1168
1185
|
size: { x: 0.01, y: 0.01 }
|
|
1169
|
-
// Small pin pad
|
|
1170
1186
|
});
|
|
1171
1187
|
}
|
|
1172
1188
|
}
|
|
@@ -1174,14 +1190,17 @@ var PartitionPackingSolver = class extends BaseSolver {
|
|
|
1174
1190
|
return {
|
|
1175
1191
|
componentId: `partition_${group.partitionIndex}`,
|
|
1176
1192
|
pads,
|
|
1177
|
-
availableRotationDegrees: [0]
|
|
1178
|
-
|
|
1193
|
+
availableRotationDegrees: [0],
|
|
1194
|
+
...isFixed && {
|
|
1195
|
+
isStatic: true,
|
|
1196
|
+
center: { x: centerX, y: centerY },
|
|
1197
|
+
ccwRotationOffset: 0
|
|
1198
|
+
}
|
|
1179
1199
|
};
|
|
1180
1200
|
});
|
|
1181
1201
|
return {
|
|
1182
1202
|
components: packComponents,
|
|
1183
1203
|
minGap: this.inputProblem.partitionGap,
|
|
1184
|
-
// Use partitionGap from input problem
|
|
1185
1204
|
packOrderStrategy: "largest_to_smallest",
|
|
1186
1205
|
packPlacementStrategy: "minimum_sum_squared_distance_to_network"
|
|
1187
1206
|
};
|
package/package.json
CHANGED
|
@@ -2,33 +2,35 @@
|
|
|
2
2
|
"name": "@tscircuit/matchpack",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.19",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
8
8
|
],
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "cosmos",
|
|
11
|
+
"test": "bun test",
|
|
11
12
|
"build": "tsup-node --format esm --dts --clean ./lib/index.ts",
|
|
12
13
|
"format": "biome format --write .",
|
|
13
14
|
"format:check": "biome format .",
|
|
14
15
|
"build:site": "cosmos-export"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"@biomejs/biome": "^2.
|
|
18
|
+
"@biomejs/biome": "^2.4.16",
|
|
18
19
|
"@react-hook/resize-observer": "^2.0.2",
|
|
19
|
-
"@tscircuit/circuit-json-util": "^0.0.
|
|
20
|
-
"@tscircuit/math-utils": "^0.0.
|
|
21
|
-
"@tscircuit/schematic-viewer": "^2.0.
|
|
22
|
-
"@types/bun": "
|
|
20
|
+
"@tscircuit/circuit-json-util": "^0.0.95",
|
|
21
|
+
"@tscircuit/math-utils": "^0.0.36",
|
|
22
|
+
"@tscircuit/schematic-viewer": "^2.0.61",
|
|
23
|
+
"@types/bun": "^1.3.14",
|
|
24
|
+
"bun-match-svg": "^0.0.15",
|
|
23
25
|
"bpc-graph": "^0.0.66",
|
|
24
|
-
"calculate-packing": "^0.0.
|
|
25
|
-
"circuit-json": "^0.0.
|
|
26
|
-
"graphics-debug": "^0.0.
|
|
27
|
-
"react-cosmos": "^7.
|
|
28
|
-
"react-cosmos-plugin-vite": "^7.
|
|
29
|
-
"tscircuit": "^0.0.
|
|
30
|
-
"tsup": "^8.5.
|
|
31
|
-
"circuit-to-svg": "^0.0.
|
|
26
|
+
"calculate-packing": "^0.0.74",
|
|
27
|
+
"circuit-json": "^0.0.432",
|
|
28
|
+
"graphics-debug": "^0.0.95",
|
|
29
|
+
"react-cosmos": "^7.3.0",
|
|
30
|
+
"react-cosmos-plugin-vite": "^7.3.0",
|
|
31
|
+
"tscircuit": "^0.0.1819",
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"circuit-to-svg": "^0.0.351"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
36
|
"typescript": "^5"
|