Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
unsupported_planner_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Unsupported planner boundary validation.
3 
4 Exercises representative unsupported planner-entry requests and records the
5 stable no-fallback outcome for each one. Unsupported requests fail before
6 execution and are not silently relabeled as supported `partitioned_density`
7 behavior.
8 
9 Run with:
10  python benchmarks/density_matrix/planner_surface/unsupported_planner_validation.py
11 """
12 
13 from __future__ import annotations
14 
15 import argparse
16 import json
17 import sys
18 from pathlib import Path
19 
20 REPO_ROOT = Path(__file__).resolve().parents[3]
21 if str(REPO_ROOT) not in sys.path:
22  sys.path.insert(0, str(REPO_ROOT))
23 
24 from benchmarks.density_matrix.planner_surface.common import (
25  build_phase2_continuity_vqe,
26  build_software_metadata,
27 )
28 from benchmarks.density_matrix.planner_surface.workloads import mandatory_microcase_definitions
29 from squander import Circuit
30 from squander.partitioning.noisy_planner import preflight_planner_request
31 
32 SUITE_NAME = "phase3_planner_surface_unsupported_planner"
33 ARTIFACT_FILENAME = "unsupported_planner_bundle.json"
34 DEFAULT_OUTPUT_DIR = (
35  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "planner_surface"
36 )
37 ARTIFACT_CORE_FIELDS = (
38  "suite_name",
39  "status",
40  "software",
41  "summary",
42  "cases",
43 )
44 
45 
46 def _unsupported_case(case_name: str, runner) -> dict:
47  try:
48  runner()
49  except Exception as err:
50  payload = err.to_dict() if hasattr(err, "to_dict") else {"reason": str(err)}
51  payload.update(
52  {
53  "case_name": case_name,
54  "status": "unsupported",
55  "supported_partitioned_case_recorded": False,
56  }
57  )
58  return payload
59  return {
60  "case_name": case_name,
61  "status": "unexpected_pass",
62  "supported_partitioned_case_recorded": False,
63  "reason": "unsupported case unexpectedly passed",
64  }
65 
66 
67 def build_cases() -> list[dict]:
68  microcase = mandatory_microcase_definitions()[0]
69  continuity_vqe, _, _ = build_phase2_continuity_vqe(4)
70  continuity_bridge = continuity_vqe.describe_density_bridge()
71 
72  legacy_h = Circuit(1)
73  legacy_h.add_H(0)
74 
75  return [
77  "unsupported_source_type",
79  source_type="binary_import",
80  workload_id="unsupported_source_type",
81  operation_specs=[],
82  qbit_num=2,
83  ),
84  ),
86  "missing_source_payload",
88  source_type="microcase_builder",
89  workload_id="missing_source_payload",
90  qbit_num=2,
91  ),
92  ),
94  "unsupported_mode_claim",
96  source_type="generated_hea",
97  workload_id="unsupported_mode_claim",
98  requested_mode="state_vector",
99  bridge_metadata=continuity_bridge,
100  ),
101  ),
103  "unsupported_noise_model",
105  source_type="microcase_builder",
106  workload_id="unsupported_noise_model",
107  operation_specs=[
108  *microcase["operation_specs"],
109  {
110  "kind": "noise",
111  "name": "readout_noise",
112  "target_qbit": 0,
113  "source_gate_index": 2,
114  "fixed_value": 0.1,
115  "param_count": 0,
116  },
117  ],
118  qbit_num=microcase["qbit_num"],
119  ),
120  ),
122  "legacy_gate_family_h",
124  source_type="legacy_qgd_circuit_exact",
125  workload_id="legacy_gate_family_h",
126  legacy_circuit=legacy_h,
127  ),
128  ),
130  "invalid_noise_insertion_index",
132  source_type="microcase_builder",
133  workload_id="invalid_noise_insertion_index",
134  operation_specs=[
135  {
136  "kind": "gate",
137  "name": "U3",
138  "target_qbit": 0,
139  "param_count": 3,
140  },
141  {
142  "kind": "noise",
143  "name": "phase_damping",
144  "target_qbit": 0,
145  "source_gate_index": 99,
146  "fixed_value": 0.07,
147  "param_count": 0,
148  },
149  ],
150  qbit_num=1,
151  ),
152  ),
153  ]
154 
155 
156 def build_artifact_bundle(cases: list[dict]) -> dict:
157  unsupported_cases = sum(case["status"] == "unsupported" for case in cases)
158  unexpected_passes = sum(case["status"] == "unexpected_pass" for case in cases)
159  bundle = {
160  "suite_name": SUITE_NAME,
161  "status": "pass"
162  if unsupported_cases == len(cases) and unexpected_passes == 0
163  else "fail",
164  "software": build_software_metadata(),
165  "summary": {
166  "total_cases": len(cases),
167  "unsupported_cases": unsupported_cases,
168  "unexpected_passes": unexpected_passes,
169  },
170  "cases": cases,
171  }
172  missing = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
173  if missing:
174  raise ValueError(
175  "Unsupported planner bundle missing required fields: {}".format(
176  ", ".join(missing)
177  )
178  )
179  return bundle
180 
181 
182 def write_artifact_bundle(bundle: dict, output_dir: Path = DEFAULT_OUTPUT_DIR) -> Path:
183  output_dir.mkdir(parents=True, exist_ok=True)
184  output_path = output_dir / ARTIFACT_FILENAME
185  output_path.write_text(json.dumps(bundle, indent=2, sort_keys=True) + "\n")
186  return output_path
187 
188 
189 def main(argv: list[str] | None = None) -> int:
190  parser = argparse.ArgumentParser(description=__doc__)
191  parser.add_argument(
192  "--output-dir",
193  type=Path,
194  default=DEFAULT_OUTPUT_DIR,
195  help="Directory to write the unsupported planner bundle into.",
196  )
197  parser.add_argument(
198  "--quiet",
199  action="store_true",
200  help="Suppress per-case console output.",
201  )
202  args = parser.parse_args(argv)
203 
204  cases = build_cases()
205  bundle = build_artifact_bundle(cases)
206  output_path = write_artifact_bundle(bundle, output_dir=args.output_dir)
207 
208  if not args.quiet:
209  for case in cases:
210  print("{case_name}: {status}".format(**case))
211  print("Wrote {}".format(output_path))
212 
213  return 0 if bundle["status"] == "pass" else 1
214 
215 
216 if __name__ == "__main__":
217  raise SystemExit(main())
def build_phase2_continuity_vqe
def build_software_metadata()