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.
Files changed (62) hide show
  1. qcoder/__init__.py +3 -0
  2. qcoder/__main__.py +6 -0
  3. qcoder/cli.py +116 -0
  4. qcoder/core/__init__.py +1 -0
  5. qcoder/core/context.py +16 -0
  6. qcoder/core/qasm2/__init__.py +1 -0
  7. qcoder/core/qasm2/adjoint_eligibility.py +128 -0
  8. qcoder/core/qasm2/mirror_build.py +234 -0
  9. qcoder/core/run_config.py +84 -0
  10. qcoder/core/schema.py +26 -0
  11. qcoder/engines/feature_extraction/adapters/__init__.py +1 -0
  12. qcoder/engines/feature_extraction/adapters/qiskit_intake.py +46 -0
  13. qcoder/engines/feature_extraction/extractor.py +43 -0
  14. qcoder/engines/feature_extraction/features/compute_v0.py +157 -0
  15. qcoder/engines/feature_extraction/features/schema_v0.py +84 -0
  16. qcoder/engines/feature_extraction/ir.py +41 -0
  17. qcoder/engines/feature_extraction/labeling.py +68 -0
  18. qcoder/engines/feature_extraction/parsers/__init__.py +21 -0
  19. qcoder/engines/feature_extraction/qasm2_regex_parser.py +184 -0
  20. qcoder/engines/feature_extraction/reps/cut_profile.py +106 -0
  21. qcoder/engines/feature_extraction/reps/depth.py +47 -0
  22. qcoder/engines/feature_extraction/reps/entangling_layers.py +57 -0
  23. qcoder/engines/feature_extraction/reps/gate_set_stats.py +82 -0
  24. qcoder/engines/feature_extraction/reps/interaction_graph.py +30 -0
  25. qcoder/engines/feature_extraction/reps/interaction_graph_metrics.py +113 -0
  26. qcoder/engines/feature_extraction/reps/spans.py +89 -0
  27. qcoder/engines/prediction_model/__init__.py +16 -0
  28. qcoder/engines/prediction_model/artifact.py +85 -0
  29. qcoder/engines/prediction_model/engine.py +209 -0
  30. qcoder/engines/prediction_model/models.py +62 -0
  31. qcoder/engines/prediction_model/policy.py +45 -0
  32. qcoder/engines/prediction_model/schema_alignment.py +41 -0
  33. qcoder/engines/quantumness/__init__.py +8 -0
  34. qcoder/engines/quantumness/scorer.py +254 -0
  35. qcoder/pipelines/analyze.py +131 -0
  36. qcoder/pipelines/batch.py +56 -0
  37. qcoder/tools/analyze.py +88 -0
  38. qcoder/tools/analyze_shot_scaling.py +239 -0
  39. qcoder/tools/batch.py +39 -0
  40. qcoder/tools/generate_corpus.py +491 -0
  41. qcoder/tools/harness.py +15 -0
  42. qcoder/tools/inspect_corpus_features.py +273 -0
  43. qcoder/tools/join_runs_features.py +252 -0
  44. qcoder/tools/mirror.py +15 -0
  45. qcoder/tools/predict_baseline.py +347 -0
  46. qcoder/tools/qr_dll_bootstrap.py +31 -0
  47. qcoder/tools/runner.py +15 -0
  48. qcoder/tools/runners/__init__.py +1 -0
  49. qcoder/tools/runners/quantum_rings/__init__.py +1 -0
  50. qcoder/tools/runners/quantum_rings/v12/__init__.py +1 -0
  51. qcoder/tools/runners/quantum_rings/v12/harness.py +1350 -0
  52. qcoder/tools/runners/quantum_rings/v12/mirror.py +459 -0
  53. qcoder/tools/runners/quantum_rings/v12/runner.py +549 -0
  54. qcoder/tools/train_baseline_models.py +619 -0
  55. qcoder/tools/validate_baseline.py +307 -0
  56. qcoder-0.1.0a0.dist-info/METADATA +86 -0
  57. qcoder-0.1.0a0.dist-info/RECORD +62 -0
  58. qcoder-0.1.0a0.dist-info/WHEEL +5 -0
  59. qcoder-0.1.0a0.dist-info/entry_points.txt +2 -0
  60. qcoder-0.1.0a0.dist-info/licenses/LICENSE +201 -0
  61. qcoder-0.1.0a0.dist-info/licenses/NOTICE +11 -0
  62. 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())
@@ -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}")