Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
required_local_noise_micro_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: required local-noise exact microcases.
3 
4 Reuses the canonical micro-validation harness and adds required-local-noise
5 traceability for:
6 - required local-noise coverage,
7 - mixed required-noise sequence order,
8 - mandatory-baseline classification that keeps these cases milestone-defining,
9 - and one stable artifact bundle for the mandatory 1 to 3 qubit exact
10  micro-validation matrix.
11 
12 Run with:
13  python benchmarks/density_matrix/noise_support/required_local_noise_micro_validation.py
14 """
15 
16 from __future__ import annotations
17 
18 import argparse
19 import json
20 from pathlib import Path
21 import sys
22 
23 REPO_ROOT = Path(__file__).resolve().parents[3]
24 if str(REPO_ROOT) not in sys.path:
25  sys.path.insert(0, str(REPO_ROOT))
26 
27 from benchmarks.density_matrix.circuits import MANDATORY_MICROCASES
28 from benchmarks.density_matrix.validate_squander_vs_qiskit import (
29  PRIMARY_BACKEND,
30  REFERENCE_BACKEND,
31  build_software_metadata,
32  build_threshold_metadata,
33  run_validation as run_required_local_noise_micro_validation,
34 )
35 from benchmarks.density_matrix.noise_support.support_tiers import (
36  SUPPORT_TIER_VOCABULARY,
37  build_required_case_classification,
38  build_support_tier_summary,
39 )
40 
41 SUITE_NAME = "required_local_noise_micro_validation"
42 ARTIFACT_FILENAME = "required_local_noise_micro_bundle.json"
43 DEFAULT_OUTPUT_DIR = (
44  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "noise_support"
45 )
46 REQUIRED_LOCAL_NOISE_MODELS = (
47  "local_depolarizing",
48  "amplitude_damping",
49  "phase_damping",
50 )
51 ARTIFACT_CORE_FIELDS = (
52  "suite_name",
53  "status",
54  "backend",
55  "reference_backend",
56  "requirements",
57  "thresholds",
58  "software",
59  "summary",
60  "cases",
61 )
62 
63 
65  individual_noise_cases = [
66  case["case_name"]
67  for case in MANDATORY_MICROCASES
68  if case["case_kind"] == "individual_noise"
69  ]
70  mixed_sequence_cases = [
71  case["case_name"]
72  for case in MANDATORY_MICROCASES
73  if case["case_kind"] == "mixed_sequence"
74  ]
75  return {
76  "required_local_noise_models": list(REQUIRED_LOCAL_NOISE_MODELS),
77  "required_gate_families": ["U3", "CNOT"],
78  "support_tier_vocabulary": list(SUPPORT_TIER_VOCABULARY),
79  "mandatory_case_names": [case["case_name"] for case in MANDATORY_MICROCASES],
80  "individual_noise_case_names": individual_noise_cases,
81  "mixed_sequence_case_names": mixed_sequence_cases,
82  "microcase_qubits": sorted({case["qbit_num"] for case in MANDATORY_MICROCASES}),
83  "required_pass_rate": 1.0,
84  }
85 
86 
88  required_fields = (
89  "case_name",
90  "status",
91  "required_noise_models",
92  "case_kind",
93  "energy_pass",
94  "density_valid_pass",
95  "trace_pass",
96  "observable_pass",
97  "required_gate_coverage_pass",
98  "required_noise_model_coverage_pass",
99  "noise_sequence_match_pass",
100  "operation_audit_pass",
101  "noise_operation_sequence",
102  "required_local_noise_microcase_pass",
103  "support_tier",
104  "case_purpose",
105  "counts_toward_mandatory_baseline",
106  )
107  missing_fields = [field for field in required_fields if field not in case]
108  if missing_fields:
109  raise ValueError(
110  "Required local-noise microcase payload is missing required fields: {}".format(
111  ", ".join(missing_fields)
112  )
113  )
114 
115 
117  cases = []
118  for result in results:
119  case = dict(result)
121  case["required_local_noise_microcase_pass"] = bool(
122  case["status"] == "pass"
123  and case["energy_pass"]
124  and case["density_valid_pass"]
125  and case["trace_pass"]
126  and case["observable_pass"]
127  and case["required_gate_coverage_pass"]
128  and case["required_noise_model_coverage_pass"]
129  and case["noise_sequence_match_pass"]
130  and case["operation_audit_pass"]
131  )
133  cases.append(case)
134 
135  total_cases = len(cases)
136  passed_cases = sum(case["required_local_noise_microcase_pass"] for case in cases)
137  exact_threshold_passed_cases = sum(
138  case["energy_pass"]
139  and case["density_valid_pass"]
140  and case["trace_pass"]
141  and case["observable_pass"]
142  for case in cases
143  )
144  operation_audit_passed_cases = sum(case["operation_audit_pass"] for case in cases)
145  mixed_sequence_case_count = sum(case["case_kind"] == "mixed_sequence" for case in cases)
146  mixed_sequence_passed_cases = sum(
147  case["case_kind"] == "mixed_sequence" and case["mixed_sequence_order_pass"]
148  for case in cases
149  )
150  required_noise_models_covered = sorted(
151  {
152  noise_model
153  for case in cases
154  for noise_model in case["required_noise_models"]
155  }
156  )
157  pass_rate = 0.0 if total_cases == 0 else passed_cases / total_cases
158  support_tier_summary = build_support_tier_summary(cases)
159 
160  bundle = {
161  "suite_name": SUITE_NAME,
162  "status": "pass"
163  if support_tier_summary["mandatory_baseline_completed"]
164  and passed_cases == total_cases
165  and total_cases
166  else "fail",
167  "backend": PRIMARY_BACKEND,
168  "reference_backend": REFERENCE_BACKEND,
169  "requirements": build_requirement_metadata(),
170  "thresholds": build_threshold_metadata(),
171  "software": build_software_metadata(),
172  "summary": {
173  "total_cases": total_cases,
174  "passed_cases": passed_cases,
175  "failed_cases": total_cases - passed_cases,
176  "pass_rate": pass_rate,
177  **support_tier_summary,
178  "exact_threshold_passed_cases": exact_threshold_passed_cases,
179  "operation_audit_passed_cases": operation_audit_passed_cases,
180  "mixed_sequence_case_count": mixed_sequence_case_count,
181  "mixed_sequence_passed_cases": mixed_sequence_passed_cases,
182  "required_noise_models_covered": required_noise_models_covered,
183  },
184  "cases": cases,
185  }
187  return bundle
188 
189 
191  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
192  if missing_fields:
193  raise ValueError(
194  "Required local-noise micro-validation bundle is missing required fields: {}".format(
195  ", ".join(missing_fields)
196  )
197  )
198 
199 
200 def write_artifact_bundle(output_path: Path, bundle):
202  output_path.parent.mkdir(parents=True, exist_ok=True)
203  output_path.write_text(json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8")
204 
205 
207  parser = argparse.ArgumentParser(description=__doc__)
208  parser.add_argument(
209  "--output-dir",
210  type=Path,
211  default=DEFAULT_OUTPUT_DIR,
212  help="Directory for the required local-noise micro-validation JSON artifact bundle.",
213  )
214  parser.add_argument(
215  "--quiet",
216  action="store_true",
217  help="Suppress per-case validation output.",
218  )
219  return parser.parse_args()
220 
221 
222 def main():
223  args = parse_args()
224  results = run_required_local_noise_micro_validation(verbose=not args.quiet)
225  bundle = build_artifact_bundle(results)
226  output_path = args.output_dir / ARTIFACT_FILENAME
227  write_artifact_bundle(output_path, bundle)
228  print(
229  "Wrote {} with status {} ({}/{})".format(
230  output_path,
231  bundle["status"],
232  bundle["summary"]["passed_cases"],
233  bundle["summary"]["total_cases"],
234  )
235  )
236  if bundle["status"] != "pass":
237  raise SystemExit(1)
238 
239 
240 if __name__ == "__main__":
241  main()
def build_support_tier_summary(cases)
def build_required_case_classification()
def build_software_metadata()