qcoder 0.1.0a0__py3-none-any.whl
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.
- qcoder/__init__.py +3 -0
- qcoder/__main__.py +6 -0
- qcoder/cli.py +116 -0
- qcoder/core/__init__.py +1 -0
- qcoder/core/context.py +16 -0
- qcoder/core/qasm2/__init__.py +1 -0
- qcoder/core/qasm2/adjoint_eligibility.py +128 -0
- qcoder/core/qasm2/mirror_build.py +234 -0
- qcoder/core/run_config.py +84 -0
- qcoder/core/schema.py +26 -0
- qcoder/engines/feature_extraction/adapters/__init__.py +1 -0
- qcoder/engines/feature_extraction/adapters/qiskit_intake.py +46 -0
- qcoder/engines/feature_extraction/extractor.py +43 -0
- qcoder/engines/feature_extraction/features/compute_v0.py +157 -0
- qcoder/engines/feature_extraction/features/schema_v0.py +84 -0
- qcoder/engines/feature_extraction/ir.py +41 -0
- qcoder/engines/feature_extraction/labeling.py +68 -0
- qcoder/engines/feature_extraction/parsers/__init__.py +21 -0
- qcoder/engines/feature_extraction/qasm2_regex_parser.py +184 -0
- qcoder/engines/feature_extraction/reps/cut_profile.py +106 -0
- qcoder/engines/feature_extraction/reps/depth.py +47 -0
- qcoder/engines/feature_extraction/reps/entangling_layers.py +57 -0
- qcoder/engines/feature_extraction/reps/gate_set_stats.py +82 -0
- qcoder/engines/feature_extraction/reps/interaction_graph.py +30 -0
- qcoder/engines/feature_extraction/reps/interaction_graph_metrics.py +113 -0
- qcoder/engines/feature_extraction/reps/spans.py +89 -0
- qcoder/engines/prediction_model/__init__.py +16 -0
- qcoder/engines/prediction_model/artifact.py +85 -0
- qcoder/engines/prediction_model/engine.py +209 -0
- qcoder/engines/prediction_model/models.py +62 -0
- qcoder/engines/prediction_model/policy.py +45 -0
- qcoder/engines/prediction_model/schema_alignment.py +41 -0
- qcoder/engines/quantumness/__init__.py +8 -0
- qcoder/engines/quantumness/scorer.py +254 -0
- qcoder/pipelines/analyze.py +131 -0
- qcoder/pipelines/batch.py +56 -0
- qcoder/tools/analyze.py +88 -0
- qcoder/tools/analyze_shot_scaling.py +239 -0
- qcoder/tools/batch.py +39 -0
- qcoder/tools/generate_corpus.py +491 -0
- qcoder/tools/harness.py +15 -0
- qcoder/tools/inspect_corpus_features.py +273 -0
- qcoder/tools/join_runs_features.py +252 -0
- qcoder/tools/mirror.py +15 -0
- qcoder/tools/predict_baseline.py +347 -0
- qcoder/tools/qr_dll_bootstrap.py +31 -0
- qcoder/tools/runner.py +15 -0
- qcoder/tools/runners/__init__.py +1 -0
- qcoder/tools/runners/quantum_rings/__init__.py +1 -0
- qcoder/tools/runners/quantum_rings/v12/__init__.py +1 -0
- qcoder/tools/runners/quantum_rings/v12/harness.py +1350 -0
- qcoder/tools/runners/quantum_rings/v12/mirror.py +459 -0
- qcoder/tools/runners/quantum_rings/v12/runner.py +549 -0
- qcoder/tools/train_baseline_models.py +619 -0
- qcoder/tools/validate_baseline.py +307 -0
- qcoder-0.1.0a0.dist-info/METADATA +86 -0
- qcoder-0.1.0a0.dist-info/RECORD +62 -0
- qcoder-0.1.0a0.dist-info/WHEEL +5 -0
- qcoder-0.1.0a0.dist-info/entry_points.txt +2 -0
- qcoder-0.1.0a0.dist-info/licenses/LICENSE +201 -0
- qcoder-0.1.0a0.dist-info/licenses/NOTICE +11 -0
- qcoder-0.1.0a0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
SYNTH_FAMILIES = (
|
|
11
|
+
"span_sweep",
|
|
12
|
+
"entangling_depth",
|
|
13
|
+
"graph_topology",
|
|
14
|
+
"temporal_variants",
|
|
15
|
+
"pair_reuse",
|
|
16
|
+
)
|
|
17
|
+
ALGO_FAMILIES = (
|
|
18
|
+
"ghz",
|
|
19
|
+
"qft",
|
|
20
|
+
"grover_like",
|
|
21
|
+
"qaoa_like",
|
|
22
|
+
"trotter_like",
|
|
23
|
+
)
|
|
24
|
+
ALL_FAMILIES = SYNTH_FAMILIES + ALGO_FAMILIES
|
|
25
|
+
|
|
26
|
+
WIDTH_PRESETS: dict[str, list[int]] = {
|
|
27
|
+
"fast": [8, 12, 16, 20, 24],
|
|
28
|
+
"mid": [32, 48, 64, 80],
|
|
29
|
+
"large": [96, 128, 160, 200],
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True)
|
|
34
|
+
class CircuitSpec:
|
|
35
|
+
source: str
|
|
36
|
+
family: str
|
|
37
|
+
subfamily: str
|
|
38
|
+
width: int
|
|
39
|
+
nominal_depth_target: int
|
|
40
|
+
span_regime: str | None = None
|
|
41
|
+
graph_type: str | None = None
|
|
42
|
+
temporal_variant: str | None = None
|
|
43
|
+
pair_reuse_regime: str | None = None
|
|
44
|
+
generator_params: dict[str, Any] | None = None
|
|
45
|
+
body_lines: tuple[str, ...] = ()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _qasm_header(width: int) -> list[str]:
|
|
49
|
+
return [
|
|
50
|
+
"OPENQASM 2.0;",
|
|
51
|
+
'include "qelib1.inc";',
|
|
52
|
+
f"qreg q[{int(width)}];",
|
|
53
|
+
f"creg c[{int(width)}];",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _qasm_footer_measurements(width: int) -> list[str]:
|
|
58
|
+
return [f"measure q[{i}] -> c[{i}];" for i in range(int(width))]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _name_from_spec(spec: CircuitSpec) -> str:
|
|
62
|
+
parts = [spec.family, f"w{spec.width:03d}", f"d{spec.nominal_depth_target:03d}"]
|
|
63
|
+
if spec.subfamily:
|
|
64
|
+
parts.append(spec.subfamily)
|
|
65
|
+
if spec.span_regime:
|
|
66
|
+
parts.append(f"span_{spec.span_regime}")
|
|
67
|
+
if spec.graph_type:
|
|
68
|
+
parts.append(f"graph_{spec.graph_type}")
|
|
69
|
+
if spec.temporal_variant:
|
|
70
|
+
parts.append(f"tvar_{spec.temporal_variant}")
|
|
71
|
+
if spec.pair_reuse_regime:
|
|
72
|
+
parts.append(f"reuse_{spec.pair_reuse_regime}")
|
|
73
|
+
return "__".join(parts) + ".qasm"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _edge_pairs_for_graph(width: int, graph_type: str) -> list[tuple[int, int]]:
|
|
77
|
+
if width < 2:
|
|
78
|
+
return []
|
|
79
|
+
if graph_type == "chain":
|
|
80
|
+
return [(i, i + 1) for i in range(width - 1)]
|
|
81
|
+
if graph_type == "ring":
|
|
82
|
+
return [(i, i + 1) for i in range(width - 1)] + [(width - 1, 0)]
|
|
83
|
+
if graph_type == "star":
|
|
84
|
+
return [(0, i) for i in range(1, width)]
|
|
85
|
+
if graph_type == "sparse_random_like":
|
|
86
|
+
pairs: set[tuple[int, int]] = set()
|
|
87
|
+
for i in range(width):
|
|
88
|
+
j = (i * 7 + 3) % width
|
|
89
|
+
if i == j:
|
|
90
|
+
continue
|
|
91
|
+
a, b = (i, j) if i < j else (j, i)
|
|
92
|
+
pairs.add((a, b))
|
|
93
|
+
return sorted(pairs)
|
|
94
|
+
# clustered
|
|
95
|
+
half = max(1, width // 2)
|
|
96
|
+
left = list(range(0, half))
|
|
97
|
+
right = list(range(half, width))
|
|
98
|
+
pairs: list[tuple[int, int]] = []
|
|
99
|
+
for group in (left, right):
|
|
100
|
+
for i in range(0, len(group) - 1, 2):
|
|
101
|
+
pairs.append((group[i], group[i + 1]))
|
|
102
|
+
if left and right:
|
|
103
|
+
pairs.append((left[-1], right[0]))
|
|
104
|
+
return pairs
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _emit_pairs_rounds(pairs: list[tuple[int, int]], rounds: int) -> list[str]:
|
|
108
|
+
out: list[str] = []
|
|
109
|
+
if not pairs:
|
|
110
|
+
return out
|
|
111
|
+
for r in range(max(1, int(rounds))):
|
|
112
|
+
# deterministic parity staggering for lighter layering.
|
|
113
|
+
for idx, (a, b) in enumerate(pairs):
|
|
114
|
+
if (idx + r) % 2 == 0:
|
|
115
|
+
out.append(f"cx q[{a}],q[{b}];")
|
|
116
|
+
return out
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _build_span_sweep(widths: list[int]) -> list[CircuitSpec]:
|
|
120
|
+
specs: list[CircuitSpec] = []
|
|
121
|
+
for w in widths:
|
|
122
|
+
regimes = [
|
|
123
|
+
("short", 1),
|
|
124
|
+
("mid", max(2, w // 4)),
|
|
125
|
+
("long", max(2, w // 2)),
|
|
126
|
+
]
|
|
127
|
+
depth_modes = [("shallow", max(4, w // 2)), ("medium", max(8, w))]
|
|
128
|
+
for depth_name, d in depth_modes:
|
|
129
|
+
for span_name, span in regimes:
|
|
130
|
+
span = min(span, max(1, w - 1))
|
|
131
|
+
pairs = [(i, i + span) for i in range(0, w - span)]
|
|
132
|
+
body = _emit_pairs_rounds(pairs, max(1, d // max(1, len(pairs))))
|
|
133
|
+
specs.append(
|
|
134
|
+
CircuitSpec(
|
|
135
|
+
source="synthetic_diagnostics",
|
|
136
|
+
family="span_sweep",
|
|
137
|
+
subfamily=depth_name,
|
|
138
|
+
width=w,
|
|
139
|
+
nominal_depth_target=d,
|
|
140
|
+
span_regime=span_name,
|
|
141
|
+
generator_params={"interaction_span": span, "depth_mode": depth_name},
|
|
142
|
+
body_lines=tuple(body),
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
return specs
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _build_entangling_depth(widths: list[int]) -> list[CircuitSpec]:
|
|
149
|
+
specs: list[CircuitSpec] = []
|
|
150
|
+
for w in widths:
|
|
151
|
+
layer_options = [4, 8] if w <= 24 else ([8, 16] if w <= 80 else [12])
|
|
152
|
+
for layers in layer_options:
|
|
153
|
+
body: list[str] = []
|
|
154
|
+
for _ in range(layers):
|
|
155
|
+
for start in (0, 1):
|
|
156
|
+
for i in range(start, w - 1, 2):
|
|
157
|
+
body.append(f"cx q[{i}],q[{i+1}];")
|
|
158
|
+
specs.append(
|
|
159
|
+
CircuitSpec(
|
|
160
|
+
source="synthetic_diagnostics",
|
|
161
|
+
family="entangling_depth",
|
|
162
|
+
subfamily="brickwork",
|
|
163
|
+
width=w,
|
|
164
|
+
nominal_depth_target=layers,
|
|
165
|
+
graph_type="brickwork",
|
|
166
|
+
generator_params={"entangling_layers": layers},
|
|
167
|
+
body_lines=tuple(body),
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
return specs
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _build_graph_topology(widths: list[int]) -> list[CircuitSpec]:
|
|
174
|
+
specs: list[CircuitSpec] = []
|
|
175
|
+
for w in widths:
|
|
176
|
+
for g in ("chain", "ring", "star", "sparse_random_like", "clustered"):
|
|
177
|
+
pairs = _edge_pairs_for_graph(w, g)
|
|
178
|
+
d = max(6, min(24, w // 2))
|
|
179
|
+
body = _emit_pairs_rounds(pairs, max(1, d // 2))
|
|
180
|
+
specs.append(
|
|
181
|
+
CircuitSpec(
|
|
182
|
+
source="synthetic_diagnostics",
|
|
183
|
+
family="graph_topology",
|
|
184
|
+
subfamily=g,
|
|
185
|
+
width=w,
|
|
186
|
+
nominal_depth_target=d,
|
|
187
|
+
graph_type=g,
|
|
188
|
+
generator_params={"graph_type": g, "n_pairs": len(pairs)},
|
|
189
|
+
body_lines=tuple(body),
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
return specs
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _build_temporal_variants(widths: list[int]) -> list[CircuitSpec]:
|
|
196
|
+
specs: list[CircuitSpec] = []
|
|
197
|
+
for w in widths:
|
|
198
|
+
short_pairs = [(i, i + 1) for i in range(0, w - 1, 2)]
|
|
199
|
+
long_span = min(max(2, w // 2), max(1, w - 1))
|
|
200
|
+
long_pairs = [(i, i + long_span) for i in range(0, w - long_span, 2)]
|
|
201
|
+
d = max(8, min(32, w))
|
|
202
|
+
blocks = max(2, d // 4)
|
|
203
|
+
for variant in ("early", "late", "interleaved"):
|
|
204
|
+
body: list[str] = []
|
|
205
|
+
for blk in range(blocks):
|
|
206
|
+
if variant == "early":
|
|
207
|
+
use_long = blk < (blocks // 2)
|
|
208
|
+
elif variant == "late":
|
|
209
|
+
use_long = blk >= (blocks // 2)
|
|
210
|
+
else:
|
|
211
|
+
use_long = (blk % 2 == 0)
|
|
212
|
+
body.extend(_emit_pairs_rounds(long_pairs if use_long else short_pairs, 1))
|
|
213
|
+
specs.append(
|
|
214
|
+
CircuitSpec(
|
|
215
|
+
source="synthetic_diagnostics",
|
|
216
|
+
family="temporal_variants",
|
|
217
|
+
subfamily="same_totals",
|
|
218
|
+
width=w,
|
|
219
|
+
nominal_depth_target=d,
|
|
220
|
+
temporal_variant=variant,
|
|
221
|
+
generator_params={"variant": variant, "blocks": blocks},
|
|
222
|
+
body_lines=tuple(body),
|
|
223
|
+
)
|
|
224
|
+
)
|
|
225
|
+
return specs
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _build_pair_reuse(widths: list[int]) -> list[CircuitSpec]:
|
|
229
|
+
specs: list[CircuitSpec] = []
|
|
230
|
+
for w in widths:
|
|
231
|
+
d = max(10, min(40, w))
|
|
232
|
+
many_pairs = _edge_pairs_for_graph(w, "ring") or _edge_pairs_for_graph(w, "chain")
|
|
233
|
+
concentrated = many_pairs[:2] if len(many_pairs) >= 2 else many_pairs
|
|
234
|
+
for regime in ("spread", "concentrated"):
|
|
235
|
+
body: list[str] = []
|
|
236
|
+
if regime == "spread":
|
|
237
|
+
pairs = many_pairs
|
|
238
|
+
for r in range(max(1, d // 2)):
|
|
239
|
+
a, b = pairs[r % len(pairs)]
|
|
240
|
+
body.append(f"cx q[{a}],q[{b}];")
|
|
241
|
+
else:
|
|
242
|
+
pairs = concentrated
|
|
243
|
+
for r in range(max(1, d // 2)):
|
|
244
|
+
a, b = pairs[r % len(pairs)]
|
|
245
|
+
body.append(f"cx q[{a}],q[{b}];")
|
|
246
|
+
if r % 4 == 0 and many_pairs:
|
|
247
|
+
u, v = many_pairs[(r // 4) % len(many_pairs)]
|
|
248
|
+
body.append(f"cx q[{u}],q[{v}];")
|
|
249
|
+
specs.append(
|
|
250
|
+
CircuitSpec(
|
|
251
|
+
source="synthetic_diagnostics",
|
|
252
|
+
family="pair_reuse",
|
|
253
|
+
subfamily="controlled_mass",
|
|
254
|
+
width=w,
|
|
255
|
+
nominal_depth_target=d,
|
|
256
|
+
pair_reuse_regime=regime,
|
|
257
|
+
generator_params={"regime": regime, "base_pairs": len(pairs)},
|
|
258
|
+
body_lines=tuple(body),
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
return specs
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _build_algo_families(widths: list[int]) -> list[CircuitSpec]:
|
|
265
|
+
specs: list[CircuitSpec] = []
|
|
266
|
+
for w in widths:
|
|
267
|
+
# ghz
|
|
268
|
+
ghz_body = [f"h q[0];"] + [f"cx q[{i}],q[{i+1}];" for i in range(0, w - 1)]
|
|
269
|
+
specs.append(
|
|
270
|
+
CircuitSpec(
|
|
271
|
+
source="algorithms_generated",
|
|
272
|
+
family="ghz",
|
|
273
|
+
subfamily="chain",
|
|
274
|
+
width=w,
|
|
275
|
+
nominal_depth_target=max(2, w),
|
|
276
|
+
generator_params={"style": "chain_ghz"},
|
|
277
|
+
body_lines=tuple(ghz_body),
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# qft (minimal canonical form)
|
|
282
|
+
qft_body: list[str] = []
|
|
283
|
+
for i in range(w):
|
|
284
|
+
qft_body.append(f"h q[{i}];")
|
|
285
|
+
max_j = min(w, i + 4)
|
|
286
|
+
for j in range(i + 1, max_j):
|
|
287
|
+
denom = 2 ** (j - i)
|
|
288
|
+
qft_body.append(f"cu1(pi/{denom}) q[{j}],q[{i}];")
|
|
289
|
+
specs.append(
|
|
290
|
+
CircuitSpec(
|
|
291
|
+
source="algorithms_generated",
|
|
292
|
+
family="qft",
|
|
293
|
+
subfamily="truncated_phase",
|
|
294
|
+
width=w,
|
|
295
|
+
nominal_depth_target=max(4, w),
|
|
296
|
+
generator_params={"phase_span_limit": 3},
|
|
297
|
+
body_lines=tuple(qft_body),
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
# grover_like
|
|
302
|
+
grover_body = [f"h q[{i}];" for i in range(w)]
|
|
303
|
+
for _ in range(2):
|
|
304
|
+
grover_body += [f"x q[{i}];" for i in range(w)]
|
|
305
|
+
if w >= 2:
|
|
306
|
+
grover_body += [f"cz q[{i}],q[{i+1}];" for i in range(w - 1)]
|
|
307
|
+
grover_body += [f"h q[{i}];" for i in range(w)]
|
|
308
|
+
specs.append(
|
|
309
|
+
CircuitSpec(
|
|
310
|
+
source="algorithms_generated",
|
|
311
|
+
family="grover_like",
|
|
312
|
+
subfamily="2_iter",
|
|
313
|
+
width=w,
|
|
314
|
+
nominal_depth_target=max(6, w // 2),
|
|
315
|
+
generator_params={"iterations": 2},
|
|
316
|
+
body_lines=tuple(grover_body),
|
|
317
|
+
)
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
# qaoa_like
|
|
321
|
+
qaoa_body = [f"h q[{i}];" for i in range(w)]
|
|
322
|
+
for _ in range(2):
|
|
323
|
+
for i in range(w - 1):
|
|
324
|
+
qaoa_body.append(f"cx q[{i}],q[{i+1}];")
|
|
325
|
+
qaoa_body.append(f"rz(pi/8) q[{i+1}];")
|
|
326
|
+
qaoa_body.append(f"cx q[{i}],q[{i+1}];")
|
|
327
|
+
for i in range(w):
|
|
328
|
+
qaoa_body.append(f"rx(pi/6) q[{i}];")
|
|
329
|
+
specs.append(
|
|
330
|
+
CircuitSpec(
|
|
331
|
+
source="algorithms_generated",
|
|
332
|
+
family="qaoa_like",
|
|
333
|
+
subfamily="p2_chain",
|
|
334
|
+
width=w,
|
|
335
|
+
nominal_depth_target=max(8, w),
|
|
336
|
+
generator_params={"p_layers": 2},
|
|
337
|
+
body_lines=tuple(qaoa_body),
|
|
338
|
+
)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# trotter_like
|
|
342
|
+
trotter_body: list[str] = []
|
|
343
|
+
for _ in range(3):
|
|
344
|
+
for i in range(w):
|
|
345
|
+
trotter_body.append(f"rx(pi/9) q[{i}];")
|
|
346
|
+
for i in range(w - 1):
|
|
347
|
+
trotter_body.append(f"cx q[{i}],q[{i+1}];")
|
|
348
|
+
trotter_body.append(f"rz(pi/7) q[{i+1}];")
|
|
349
|
+
trotter_body.append(f"cx q[{i}],q[{i+1}];")
|
|
350
|
+
specs.append(
|
|
351
|
+
CircuitSpec(
|
|
352
|
+
source="algorithms_generated",
|
|
353
|
+
family="trotter_like",
|
|
354
|
+
subfamily="nn_chain_3step",
|
|
355
|
+
width=w,
|
|
356
|
+
nominal_depth_target=max(8, w),
|
|
357
|
+
generator_params={"steps": 3},
|
|
358
|
+
body_lines=tuple(trotter_body),
|
|
359
|
+
)
|
|
360
|
+
)
|
|
361
|
+
return specs
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _selected_widths(width_preset: str) -> list[int]:
|
|
365
|
+
if width_preset == "all":
|
|
366
|
+
return WIDTH_PRESETS["fast"] + WIDTH_PRESETS["mid"] + WIDTH_PRESETS["large"]
|
|
367
|
+
if width_preset in WIDTH_PRESETS:
|
|
368
|
+
return list(WIDTH_PRESETS[width_preset])
|
|
369
|
+
raise ValueError(f"unknown width preset: {width_preset}")
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _build_specs(selected_families: set[str], width_preset: str) -> list[CircuitSpec]:
|
|
373
|
+
widths = _selected_widths(width_preset)
|
|
374
|
+
specs: list[CircuitSpec] = []
|
|
375
|
+
if "span_sweep" in selected_families:
|
|
376
|
+
specs.extend(_build_span_sweep(widths))
|
|
377
|
+
if "entangling_depth" in selected_families:
|
|
378
|
+
specs.extend(_build_entangling_depth(widths))
|
|
379
|
+
if "graph_topology" in selected_families:
|
|
380
|
+
specs.extend(_build_graph_topology(widths))
|
|
381
|
+
if "temporal_variants" in selected_families:
|
|
382
|
+
specs.extend(_build_temporal_variants(widths))
|
|
383
|
+
if "pair_reuse" in selected_families:
|
|
384
|
+
specs.extend(_build_pair_reuse(widths))
|
|
385
|
+
algo_widths = [w for w in widths if w <= 80] + [96, 128]
|
|
386
|
+
algo_widths = sorted(set(algo_widths))
|
|
387
|
+
if selected_families.intersection(ALGO_FAMILIES):
|
|
388
|
+
# Build once then filter to keep deterministic ordering.
|
|
389
|
+
for spec in _build_algo_families(algo_widths):
|
|
390
|
+
if spec.family in selected_families:
|
|
391
|
+
specs.append(spec)
|
|
392
|
+
return specs
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def generate_corpus(
|
|
396
|
+
*,
|
|
397
|
+
output_root: str | Path = "circuits",
|
|
398
|
+
families: list[str] | None = None,
|
|
399
|
+
width_preset: str = "all",
|
|
400
|
+
overwrite: bool = False,
|
|
401
|
+
manifest_path: str | Path | None = None,
|
|
402
|
+
) -> list[dict[str, Any]]:
|
|
403
|
+
selected = set(families or ALL_FAMILIES)
|
|
404
|
+
unknown = sorted(selected.difference(ALL_FAMILIES))
|
|
405
|
+
if unknown:
|
|
406
|
+
raise ValueError(f"unknown families: {', '.join(unknown)}")
|
|
407
|
+
|
|
408
|
+
root = Path(output_root)
|
|
409
|
+
specs = _build_specs(selected, width_preset)
|
|
410
|
+
rows: list[dict[str, Any]] = []
|
|
411
|
+
for spec in specs:
|
|
412
|
+
rel_dir = Path(spec.source) / spec.family
|
|
413
|
+
out_dir = root / rel_dir
|
|
414
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
415
|
+
fname = _name_from_spec(spec)
|
|
416
|
+
out_path = out_dir / fname
|
|
417
|
+
if out_path.exists() and not overwrite:
|
|
418
|
+
raise FileExistsError(f"file exists (use --overwrite): {out_path}")
|
|
419
|
+
qasm_lines = (
|
|
420
|
+
_qasm_header(spec.width)
|
|
421
|
+
+ list(spec.body_lines)
|
|
422
|
+
+ _qasm_footer_measurements(spec.width)
|
|
423
|
+
)
|
|
424
|
+
out_path.write_text("\n".join(qasm_lines) + "\n", encoding="utf-8")
|
|
425
|
+
|
|
426
|
+
row = {
|
|
427
|
+
"circuit_path": str(out_path),
|
|
428
|
+
"source": spec.source,
|
|
429
|
+
"family": spec.family,
|
|
430
|
+
"subfamily": spec.subfamily,
|
|
431
|
+
"width": spec.width,
|
|
432
|
+
"nominal_depth_target": spec.nominal_depth_target,
|
|
433
|
+
"span_regime": spec.span_regime,
|
|
434
|
+
"graph_type": spec.graph_type,
|
|
435
|
+
"temporal_variant": spec.temporal_variant,
|
|
436
|
+
"pair_reuse_regime": spec.pair_reuse_regime,
|
|
437
|
+
"generator_params": spec.generator_params or {},
|
|
438
|
+
}
|
|
439
|
+
rows.append(row)
|
|
440
|
+
|
|
441
|
+
rows.sort(key=lambda r: r["circuit_path"])
|
|
442
|
+
mpath = Path(manifest_path) if manifest_path else (root / "generated_corpus_manifest.jsonl")
|
|
443
|
+
mpath.parent.mkdir(parents=True, exist_ok=True)
|
|
444
|
+
with mpath.open("w", encoding="utf-8") as f:
|
|
445
|
+
for row in rows:
|
|
446
|
+
f.write(json.dumps(row, sort_keys=True) + "\n")
|
|
447
|
+
return rows
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def main(argv: list[str] | None = None) -> int:
|
|
451
|
+
ap = argparse.ArgumentParser(description="Generate synthetic and algorithmic QASM corpus with manifest.")
|
|
452
|
+
ap.add_argument("--output-root", default="circuits", help="Root directory for generated circuit folders.")
|
|
453
|
+
ap.add_argument(
|
|
454
|
+
"--families",
|
|
455
|
+
nargs="+",
|
|
456
|
+
default=list(ALL_FAMILIES),
|
|
457
|
+
help="Families to generate.",
|
|
458
|
+
)
|
|
459
|
+
ap.add_argument(
|
|
460
|
+
"--width-preset",
|
|
461
|
+
choices=("fast", "mid", "large", "all"),
|
|
462
|
+
default="all",
|
|
463
|
+
help="Width preset band.",
|
|
464
|
+
)
|
|
465
|
+
ap.add_argument("--manifest-path", default=None, help="Optional explicit manifest JSONL path.")
|
|
466
|
+
ap.add_argument("--overwrite", action="store_true", help="Overwrite existing generated files.")
|
|
467
|
+
ap.add_argument("--list-families", action="store_true", help="Print available families and exit.")
|
|
468
|
+
args = ap.parse_args(argv)
|
|
469
|
+
|
|
470
|
+
if args.list_families:
|
|
471
|
+
print("\n".join(ALL_FAMILIES))
|
|
472
|
+
return 0
|
|
473
|
+
|
|
474
|
+
rows = generate_corpus(
|
|
475
|
+
output_root=args.output_root,
|
|
476
|
+
families=args.families,
|
|
477
|
+
width_preset=args.width_preset,
|
|
478
|
+
overwrite=bool(args.overwrite),
|
|
479
|
+
manifest_path=args.manifest_path,
|
|
480
|
+
)
|
|
481
|
+
print(f"[ok] generated {len(rows)} circuits")
|
|
482
|
+
print(f"[ok] root: {args.output_root}")
|
|
483
|
+
print(
|
|
484
|
+
f"[ok] manifest: {args.manifest_path if args.manifest_path else str(Path(args.output_root) / 'generated_corpus_manifest.jsonl')}"
|
|
485
|
+
)
|
|
486
|
+
print("[todo] external benchmark import hook is intentionally deferred (future extension point).")
|
|
487
|
+
return 0
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
if __name__ == "__main__":
|
|
491
|
+
raise SystemExit(main())
|
qcoder/tools/harness.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
qcoder.tools.harness — entrypoint that delegates to Quantum Rings v12 harness.
|
|
4
|
+
"""
|
|
5
|
+
from qcoder.tools.runners.quantum_rings.v12.harness import main, die
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
try:
|
|
9
|
+
main()
|
|
10
|
+
except SystemExit:
|
|
11
|
+
raise
|
|
12
|
+
except Exception as e:
|
|
13
|
+
import traceback
|
|
14
|
+
traceback.print_exc()
|
|
15
|
+
die(f"Unhandled exception: {e}")
|