Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
planner_candidate_audit_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: Phase 3 planner-candidate audit surface.
3 
4 Emits one auditable candidate surface for the current noisy planner by showing
5 that each supported planner candidate can build representative continuity,
6 microcase, and structured descriptor sets on the frozen Phase 3 workload
7 surface.
8 
9 Run with:
10  python benchmarks/density_matrix/planner_calibration/planner_candidate_audit_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_calibration.common import (
25  PLANNER_CANDIDATE_SCHEMA_VERSION,
26  build_planner_candidates,
27 )
28 from benchmarks.density_matrix.planner_surface.common import (
29  build_phase2_continuity_vqe,
30  build_software_metadata,
31 )
32 from benchmarks.density_matrix.planner_surface.workloads import (
33  iter_microcase_descriptor_sets,
34  iter_structured_descriptor_sets,
35 )
36 from squander.partitioning.noisy_planner import build_phase3_continuity_partition_descriptor_set
37 
38 SUITE_NAME = "phase3_planner_calibration_candidate_audit"
39 ARTIFACT_FILENAME = "planner_candidate_audit_bundle.json"
40 DEFAULT_OUTPUT_DIR = (
41  REPO_ROOT
42  / "benchmarks"
43  / "density_matrix"
44  / "artifacts"
45  / "planner_calibration"
46  / "planner_candidate_audit"
47 )
48 ARTIFACT_CORE_FIELDS = (
49  "suite_name",
50  "status",
51  "candidate_schema_version",
52  "software",
53  "summary",
54  "cases",
55 )
56 REQUIRED_CASE_KINDS = ("continuity", "microcase", "structured_family")
57 
58 
59 def _descriptor_summary(case_kind: str, metadata: dict, descriptor_set) -> dict:
60  payload = descriptor_set.to_dict()
61  return {
62  "case_kind": case_kind,
63  "workload_id": payload["workload_id"],
64  "qbit_num": payload["qbit_num"],
65  "max_partition_qubits": payload["max_partition_qubits"],
66  "partition_count": payload["partition_count"],
67  "descriptor_member_count": payload["descriptor_member_count"],
68  "max_partition_span": payload["max_partition_span"],
69  "partition_member_counts": payload["partition_member_counts"],
70  "family_name": metadata.get("family_name"),
71  "noise_pattern": metadata.get("noise_pattern"),
72  "source_type": payload["source_type"],
73  }
74 
75 
76 def _representative_continuity_case(candidate) -> dict:
77  qbit_num = 4
78  vqe, _, topology = build_phase2_continuity_vqe(qbit_num)
80  vqe,
81  workload_id=f"phase2_xxz_hea_q{qbit_num}_continuity",
82  max_partition_qubits=candidate.max_partition_qubits,
83  )
84  return _descriptor_summary(
85  "continuity",
86  {"topology": topology},
87  descriptor_set,
88  )
89 
90 
91 def _representative_microcase(candidate) -> dict:
92  metadata, descriptor_set = next(
93  iter(
95  max_partition_qubits=candidate.max_partition_qubits
96  )
97  )
98  )
99  return _descriptor_summary("microcase", metadata, descriptor_set)
100 
101 
102 def _representative_structured_case(candidate) -> dict:
103  metadata, descriptor_set = next(
104  iter(
106  max_partition_qubits=candidate.max_partition_qubits
107  )
108  )
109  )
110  return _descriptor_summary("structured_family", metadata, descriptor_set)
111 
112 
113 def _candidate_case(candidate) -> dict:
114  representative_cases = [
116  _representative_microcase(candidate),
118  ]
119  supported_case_kinds = [case["case_kind"] for case in representative_cases]
120  representative_workload_ids = [case["workload_id"] for case in representative_cases]
121  candidate_payload = candidate.to_dict()
122  return {
123  **candidate_payload,
124  "supported_case_kinds": supported_case_kinds,
125  "representative_workload_ids": representative_workload_ids,
126  "representative_cases": representative_cases,
127  "candidate_surface_pass": (
128  candidate_payload["schema_version"] == PLANNER_CANDIDATE_SCHEMA_VERSION
129  and supported_case_kinds == list(REQUIRED_CASE_KINDS)
130  and len(set(representative_workload_ids)) == len(REQUIRED_CASE_KINDS)
131  and all(
132  case["max_partition_qubits"] == candidate.max_partition_qubits
133  for case in representative_cases
134  )
135  and all(case["partition_count"] > 0 for case in representative_cases)
136  ),
137  }
138 
139 
140 def build_cases() -> list[dict]:
141  return [_candidate_case(candidate) for candidate in build_planner_candidates()]
142 
143 
144 def build_artifact_bundle(cases: list[dict]) -> dict:
145  candidate_ids = [case["candidate_id"] for case in cases]
146  candidate_passes = sum(case["candidate_surface_pass"] for case in cases)
147  bundle = {
148  "suite_name": SUITE_NAME,
149  "status": "pass"
150  if candidate_passes == len(cases) and len(set(candidate_ids)) == len(candidate_ids)
151  else "fail",
152  "candidate_schema_version": PLANNER_CANDIDATE_SCHEMA_VERSION,
153  "software": build_software_metadata(),
154  "summary": {
155  "total_candidates": len(cases),
156  "candidate_passes": candidate_passes,
157  "candidate_ids": candidate_ids,
158  "planner_families": sorted({case["planner_family"] for case in cases}),
159  "max_partition_qubits_values": [
160  case["max_partition_qubits"] for case in cases
161  ],
162  "representative_case_kinds": list(REQUIRED_CASE_KINDS),
163  },
164  "cases": cases,
165  }
166  missing = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
167  if missing:
168  raise ValueError(
169  "Planner-candidate audit bundle missing required fields: {}".format(
170  ", ".join(missing)
171  )
172  )
173  return bundle
174 
175 
176 def write_artifact_bundle(bundle: dict, output_dir: Path = DEFAULT_OUTPUT_DIR) -> Path:
177  output_dir.mkdir(parents=True, exist_ok=True)
178  output_path = output_dir / ARTIFACT_FILENAME
179  output_path.write_text(json.dumps(bundle, indent=2, sort_keys=True) + "\n")
180  return output_path
181 
182 
183 def main(argv: list[str] | None = None) -> int:
184  parser = argparse.ArgumentParser(description=__doc__)
185  parser.add_argument(
186  "--output-dir",
187  type=Path,
188  default=DEFAULT_OUTPUT_DIR,
189  help="Directory to write the planner-candidate audit bundle into.",
190  )
191  parser.add_argument(
192  "--quiet",
193  action="store_true",
194  help="Suppress per-case console output.",
195  )
196  args = parser.parse_args(argv)
197 
198  cases = build_cases()
199  bundle = build_artifact_bundle(cases)
200  output_path = write_artifact_bundle(bundle, output_dir=args.output_dir)
201 
202  if not args.quiet:
203  for case in cases:
204  print(
205  "{candidate_id}: max_partition_qubits={max_partition_qubits}, cases={supported_case_kinds}".format(
206  **case
207  )
208  )
209  print("Wrote {}".format(output_path))
210 
211  return 0 if bundle["status"] == "pass" else 1
212 
213 
214 if __name__ == "__main__":
215  raise SystemExit(main())
def build_phase2_continuity_vqe
def build_phase3_continuity_partition_descriptor_set
def build_software_metadata()