Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
local_correctness_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: local correctness baseline.
3 
4 Builds the phase-level local correctness gate from the already authoritative
5 micro-validation surfaces:
6 - the canonical exactness matrix against Qiskit Aer,
7 - and the required-local-noise wrapper that adds required-noise coverage,
8  mixed-sequence auditability, and mandatory-baseline semantics.
9 
10 The resulting bundle is intentionally a thin validation-evidence layer:
11 - it freezes the mandatory 1 to 3 qubit local correctness inventory,
12 - it validates stable case identity and explicit status fields,
13 - it preserves required gate/noise coverage and mixed-sequence auditability,
14 - and it makes incomplete or partial local evidence fail explicitly.
15 
16 Run with:
17  python benchmarks/density_matrix/validation_evidence/local_correctness_validation.py
18 """
19 
20 from __future__ import annotations
21 
22 import argparse
23 import json
24 import sys
25 from collections import Counter
26 from pathlib import Path
27 
28 REPO_ROOT = Path(__file__).resolve().parents[3]
29 if str(REPO_ROOT) not in sys.path:
30  sys.path.insert(0, str(REPO_ROOT))
31 
32 from benchmarks.density_matrix.circuits import MANDATORY_MICROCASES
33 from benchmarks.density_matrix.noise_support.required_local_noise_micro_validation import (
34  REQUIRED_LOCAL_NOISE_MODELS,
35  build_artifact_bundle as build_required_local_noise_micro_validation_bundle,
36 )
37 from benchmarks.density_matrix.noise_support.support_tiers import (
38  SUPPORT_TIER_VOCABULARY,
39  build_support_tier_summary,
40 )
41 from benchmarks.density_matrix.validate_squander_vs_qiskit import (
42  PRIMARY_BACKEND,
43  REFERENCE_BACKEND,
44  build_artifact_bundle as build_micro_validation_bundle,
45  build_software_metadata,
46  build_threshold_metadata,
47  run_validation as run_micro_validation,
48 )
49 
50 SUITE_NAME = "local_correctness_validation"
51 ARTIFACT_FILENAME = "local_correctness_bundle.json"
52 DEFAULT_OUTPUT_DIR = (
53  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "validation_evidence"
54 )
55 MANDATORY_CASE_NAMES = tuple(case["case_name"] for case in MANDATORY_MICROCASES)
56 ARTIFACT_CORE_FIELDS = (
57  "suite_name",
58  "status",
59  "backend",
60  "reference_backend",
61  "requirements",
62  "thresholds",
63  "software",
64  "summary",
65  "required_artifacts",
66  "cases",
67 )
68 
69 
71  return {
72  "mandatory_case_names": list(MANDATORY_CASE_NAMES),
73  "required_gate_families": ["U3", "CNOT"],
74  "required_local_noise_models": list(REQUIRED_LOCAL_NOISE_MODELS),
75  "support_tier_vocabulary": list(SUPPORT_TIER_VOCABULARY),
76  "required_bundle_sources": [
77  "mandatory_micro_validation",
78  "required_local_noise_micro_validation",
79  ],
80  "required_pass_rate": 1.0,
81  }
82 
83 
85  required_fields = (
86  "case_name",
87  "status",
88  "case_kind",
89  "energy_pass",
90  "density_valid_pass",
91  "trace_pass",
92  "observable_pass",
93  "required_gate_coverage_pass",
94  "required_noise_model_coverage_pass",
95  "noise_sequence_match_pass",
96  "operation_audit_pass",
97  "support_tier",
98  "case_purpose",
99  "counts_toward_mandatory_baseline",
100  "required_local_noise_microcase_pass",
101  )
102  missing_fields = [field for field in required_fields if field not in case]
103  if missing_fields:
104  raise ValueError(
105  "Local-correctness case payload is missing required fields: {}".format(
106  ", ".join(missing_fields)
107  )
108  )
109 
110 
112  case_names = [case["case_name"] for case in cases]
113  counts = Counter(case_names)
114  duplicate_case_names = sorted(
115  case_name for case_name, count in counts.items() if count > 1
116  )
117  missing_mandatory_case_names = sorted(set(MANDATORY_CASE_NAMES) - set(case_names))
118  unexpected_case_names = sorted(set(case_names) - set(MANDATORY_CASE_NAMES))
119  stable_case_ids_present = (
120  not missing_mandatory_case_names
121  and not duplicate_case_names
122  and not unexpected_case_names
123  and len(case_names) == len(MANDATORY_CASE_NAMES)
124  )
125  return {
126  "observed_case_names": case_names,
127  "missing_mandatory_case_names": missing_mandatory_case_names,
128  "duplicate_case_names": duplicate_case_names,
129  "unexpected_case_names": unexpected_case_names,
130  "stable_case_ids_present": stable_case_ids_present,
131  }
132 
133 
135  micro_validation_bundle, required_local_noise_micro_validation_bundle
136 ):
137  cases = [dict(case) for case in required_local_noise_micro_validation_bundle["cases"]]
138  for case in cases:
140 
141  case_identity = build_case_identity_summary(cases)
142  support_tier_summary = build_support_tier_summary(cases)
143  total_cases = len(cases)
144  passed_cases = sum(case["status"] == "pass" for case in cases)
145  pass_rate = (passed_cases / total_cases) if total_cases else 0.0
146  exact_threshold_passed_cases = sum(
147  case["energy_pass"]
148  and case["density_valid_pass"]
149  and case["trace_pass"]
150  and case["observable_pass"]
151  for case in cases
152  )
153  operation_audit_passed_cases = sum(case["operation_audit_pass"] for case in cases)
154  mixed_sequence_case_count = sum(case["case_kind"] == "mixed_sequence" for case in cases)
155  mixed_sequence_passed_cases = sum(
156  case["case_kind"] == "mixed_sequence" and case["mixed_sequence_order_pass"]
157  for case in cases
158  )
159  required_noise_models_covered = sorted(
160  {
161  noise_model
162  for case in cases
163  for noise_model in case["required_noise_models"]
164  }
165  )
166  all_cases_required = all(case["support_tier"] == "required" for case in cases)
167  all_cases_mandatory = all(
168  case["counts_toward_mandatory_baseline"] for case in cases
169  )
170  local_correctness_gate_completed = bool(
171  micro_validation_bundle["status"] == "pass"
172  and required_local_noise_micro_validation_bundle["status"] == "pass"
173  and case_identity["stable_case_ids_present"]
174  and all_cases_required
175  and all_cases_mandatory
176  and support_tier_summary["mandatory_baseline_completed"]
177  and exact_threshold_passed_cases == total_cases
178  and operation_audit_passed_cases == total_cases
179  )
180 
181  bundle = {
182  "suite_name": SUITE_NAME,
183  "status": "pass" if local_correctness_gate_completed else "fail",
184  "backend": PRIMARY_BACKEND,
185  "reference_backend": REFERENCE_BACKEND,
186  "requirements": build_requirement_metadata(),
187  "thresholds": build_threshold_metadata(),
188  "software": build_software_metadata(),
189  "summary": {
190  "total_cases": total_cases,
191  "passed_cases": passed_cases,
192  "failed_cases": total_cases - passed_cases,
193  "pass_rate": pass_rate,
194  "required_cases": support_tier_summary["required_cases"],
195  "required_passed_cases": support_tier_summary["required_passed_cases"],
196  "required_pass_rate": support_tier_summary["required_pass_rate"],
197  "mandatory_baseline_case_count": support_tier_summary[
198  "mandatory_baseline_case_count"
199  ],
200  "mandatory_baseline_passed_cases": support_tier_summary[
201  "mandatory_baseline_passed_cases"
202  ],
203  "mandatory_baseline_completed": support_tier_summary[
204  "mandatory_baseline_completed"
205  ],
206  "optional_cases_count_toward_mandatory_baseline": support_tier_summary[
207  "optional_cases_count_toward_mandatory_baseline"
208  ],
209  "exact_threshold_passed_cases": exact_threshold_passed_cases,
210  "operation_audit_passed_cases": operation_audit_passed_cases,
211  "mixed_sequence_case_count": mixed_sequence_case_count,
212  "mixed_sequence_passed_cases": mixed_sequence_passed_cases,
213  "required_noise_models_covered": required_noise_models_covered,
214  "support_tiers_present": support_tier_summary["support_tiers_present"],
215  **case_identity,
216  "all_cases_required": all_cases_required,
217  "all_cases_count_toward_mandatory_baseline": all_cases_mandatory,
218  "local_correctness_gate_completed": local_correctness_gate_completed,
219  },
220  "required_artifacts": {
221  "micro_validation_reference": {
222  "suite_name": micro_validation_bundle["suite_name"],
223  "status": micro_validation_bundle["status"],
224  "summary": micro_validation_bundle["summary"],
225  },
226  "required_local_noise_micro_validation": {
227  "suite_name": required_local_noise_micro_validation_bundle["suite_name"],
228  "status": required_local_noise_micro_validation_bundle["status"],
229  "summary": required_local_noise_micro_validation_bundle["summary"],
230  },
231  },
232  "cases": cases,
233  }
235  return bundle
236 
237 
239  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
240  if missing_fields:
241  raise ValueError(
242  "Local-correctness bundle is missing required fields: {}".format(
243  ", ".join(missing_fields)
244  )
245  )
246 
247 
248 def write_artifact_bundle(output_path: Path, bundle):
250  output_path.parent.mkdir(parents=True, exist_ok=True)
251  output_path.write_text(
252  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
253  )
254 
255 
256 def run_validation(*, verbose=False):
257  results = run_micro_validation(verbose=verbose)
258  micro_validation_bundle = build_micro_validation_bundle(results)
259  required_local_noise_micro_validation_bundle = (
260  build_required_local_noise_micro_validation_bundle(results)
261  )
262  bundle = build_artifact_bundle(
263  micro_validation_bundle, required_local_noise_micro_validation_bundle
264  )
265  if verbose:
266  print(
267  "{} [{}] mandatory cases={}/{} stable_case_ids={}".format(
268  bundle["suite_name"],
269  bundle["status"],
270  bundle["summary"]["required_passed_cases"],
271  bundle["summary"]["required_cases"],
272  bundle["summary"]["stable_case_ids_present"],
273  )
274  )
275  return micro_validation_bundle, required_local_noise_micro_validation_bundle, bundle
276 
277 
279  parser = argparse.ArgumentParser(description=__doc__)
280  parser.add_argument(
281  "--output-dir",
282  type=Path,
283  default=DEFAULT_OUTPUT_DIR,
284  help="Directory for the local-correctness JSON artifact bundle.",
285  )
286  parser.add_argument(
287  "--quiet",
288  action="store_true",
289  help="Suppress per-case validation output.",
290  )
291  return parser.parse_args()
292 
293 
294 def main():
295  args = parse_args()
296  _, _, bundle = run_validation(verbose=not args.quiet)
297  output_path = args.output_dir / ARTIFACT_FILENAME
298  write_artifact_bundle(output_path, bundle)
299  print(
300  "Wrote {} with status {} ({}/{})".format(
301  output_path,
302  bundle["status"],
303  bundle["summary"]["required_passed_cases"],
304  bundle["summary"]["required_cases"],
305  )
306  )
307  if bundle["status"] != "pass":
308  raise SystemExit(1)
309 
310 
311 if __name__ == "__main__":
312  main()
def build_support_tier_summary(cases)
def build_software_metadata()
def build_artifact_bundle(micro_validation_bundle, required_local_noise_micro_validation_bundle)