Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
metric_completeness_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: metric-completeness gate.
3 
4 Builds the phase-level metric-completeness gate from the delivered validation
5 evidence layers:
6 - local correctness bundle,
7 - workflow baseline bundle,
8 - trace-and-anchor bundle plus raw trace artifact.
9 
10 The resulting bundle is intentionally a thin validation-evidence layer:
11 - it checks required internal-consistency fields on mandatory microcases,
12 - it checks required execution and performance fields on mandatory workflow
13  cases,
14 - it checks the delivered trace artifact for required runtime and stability
15  metadata,
16 - and it fails explicitly when required metrics are missing.
17 
18 Run with:
19  python benchmarks/density_matrix/validation_evidence/metric_completeness_validation.py
20 """
21 
22 from __future__ import annotations
23 
24 import argparse
25 import json
26 import sys
27 from pathlib import Path
28 
29 REPO_ROOT = Path(__file__).resolve().parents[3]
30 if str(REPO_ROOT) not in sys.path:
31  sys.path.insert(0, str(REPO_ROOT))
32 
33 from benchmarks.density_matrix.workflow_evidence.exact_density_vqe_validation import (
34  EXACT_REGIME_PARAMETER_SET_COUNT,
35  EXACT_REGIME_WORKFLOW_QUBITS,
36 )
37 from benchmarks.density_matrix.validation_evidence.local_correctness_validation import (
38  run_validation as run_local_correctness_validation,
39 )
40 from benchmarks.density_matrix.validation_evidence.trace_anchor_validation import (
41  PRIMARY_BACKEND,
42  REFERENCE_BACKEND,
43  run_validation as run_trace_anchor_validation,
44 )
45 
46 SUITE_NAME = "metric_completeness_validation"
47 ARTIFACT_FILENAME = "metric_completeness_bundle.json"
48 DEFAULT_OUTPUT_DIR = (
49  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "validation_evidence"
50 )
51 ARTIFACT_CORE_FIELDS = (
52  "suite_name",
53  "status",
54  "backend",
55  "reference_backend",
56  "requirements",
57  "thresholds",
58  "software",
59  "summary",
60  "required_artifacts",
61 )
62 REQUIRED_MICRO_FIELDS = (
63  "status",
64  "energy_pass",
65  "density_valid_pass",
66  "trace_pass",
67  "observable_pass",
68 )
69 REQUIRED_WORKFLOW_FIELDS = (
70  "status",
71  "workflow_completed",
72  "energy_pass",
73  "density_valid_pass",
74  "trace_pass",
75  "observable_pass",
76  "bridge_supported_pass",
77  "total_case_runtime_ms",
78  "process_peak_rss_kb",
79 )
80 REQUIRED_TRACE_FIELDS = (
81  "status",
82  "workflow_completed",
83  "bridge_supported_pass",
84  "total_trace_runtime_ms",
85  "process_peak_rss_kb",
86  "required_validation_trace",
87 )
88 
89 
91  return {
92  "micro_required_fields": list(REQUIRED_MICRO_FIELDS),
93  "workflow_required_fields": list(REQUIRED_WORKFLOW_FIELDS),
94  "trace_required_fields": list(REQUIRED_TRACE_FIELDS),
95  "required_bundle_sources": [
96  "local_correctness_validation",
97  "workflow_baseline_validation",
98  "trace_anchor_validation",
99  ],
100  }
101 
102 
103 def _missing_fields(payload, required_fields):
104  return [field for field in required_fields if field not in payload]
105 
106 
107 def _build_missing_field_map(cases, required_fields):
108  missing_by_case = {}
109  for case in cases:
110  missing = _missing_fields(case, required_fields)
111  if missing:
112  missing_by_case[case["case_name"]] = missing
113  return missing_by_case
114 
115 
117  local_correctness_bundle,
118  workflow_baseline_bundle,
119  trace_anchor_bundle,
120 ):
121  micro_cases = [dict(case) for case in local_correctness_bundle["cases"]]
122  workflow_cases = [dict(case) for case in workflow_baseline_bundle["cases"]]
123  trace_artifact = dict(trace_anchor_bundle["trace_artifact"])
124 
125  missing_micro_metric_fields_by_case = _build_missing_field_map(
126  micro_cases, REQUIRED_MICRO_FIELDS
127  )
128  missing_workflow_metric_fields_by_case = _build_missing_field_map(
129  workflow_cases, REQUIRED_WORKFLOW_FIELDS
130  )
131  missing_trace_metric_fields = _missing_fields(trace_artifact, REQUIRED_TRACE_FIELDS)
132 
133  workflow_cases_with_stable_execution = sum(
134  bool(
135  case.get("workflow_completed", False)
136  and case.get("bridge_supported_pass", False)
137  and case.get("status") == "pass"
138  )
139  for case in workflow_cases
140  )
141  trace_execution_stability_pass = bool(
142  trace_artifact.get("workflow_completed", False)
143  and trace_artifact.get("bridge_supported_pass", False)
144  and trace_artifact.get("status") == "completed"
145  )
146  metric_completeness_gate_completed = bool(
147  local_correctness_bundle["status"] == "pass"
148  and workflow_baseline_bundle["status"] == "pass"
149  and trace_anchor_bundle["status"] == "pass"
150  and not missing_micro_metric_fields_by_case
151  and not missing_workflow_metric_fields_by_case
152  and not missing_trace_metric_fields
153  )
154 
155  bundle = {
156  "suite_name": SUITE_NAME,
157  "status": "pass" if metric_completeness_gate_completed else "fail",
158  "backend": PRIMARY_BACKEND,
159  "reference_backend": REFERENCE_BACKEND,
160  "requirements": build_requirement_metadata(),
161  "thresholds": {
162  "micro": dict(local_correctness_bundle["thresholds"]),
163  "workflow": dict(workflow_baseline_bundle["thresholds"]),
164  },
165  "software": dict(workflow_baseline_bundle["software"]),
166  "summary": {
167  "micro_cases_checked": len(micro_cases),
168  "workflow_cases_checked": len(workflow_cases),
169  "trace_artifacts_checked": 1,
170  "micro_cases_missing_required_metrics": len(
171  missing_micro_metric_fields_by_case
172  ),
173  "workflow_cases_missing_required_metrics": len(
174  missing_workflow_metric_fields_by_case
175  ),
176  "trace_artifacts_missing_required_metrics": len(
177  missing_trace_metric_fields
178  ),
179  "missing_micro_metric_fields_by_case": missing_micro_metric_fields_by_case,
180  "missing_workflow_metric_fields_by_case": (
181  missing_workflow_metric_fields_by_case
182  ),
183  "missing_trace_metric_fields": missing_trace_metric_fields,
184  "workflow_cases_with_stable_execution": workflow_cases_with_stable_execution,
185  "trace_execution_stability_pass": trace_execution_stability_pass,
186  "metric_completeness_gate_completed": metric_completeness_gate_completed,
187  },
188  "required_artifacts": {
189  "local_correctness_reference": {
190  "suite_name": local_correctness_bundle["suite_name"],
191  "status": local_correctness_bundle["status"],
192  "summary": local_correctness_bundle["summary"],
193  },
194  "workflow_baseline_reference": {
195  "suite_name": workflow_baseline_bundle["suite_name"],
196  "status": workflow_baseline_bundle["status"],
197  "summary": workflow_baseline_bundle["summary"],
198  },
199  "trace_anchor_reference": {
200  "suite_name": trace_anchor_bundle["suite_name"],
201  "status": trace_anchor_bundle["status"],
202  "summary": trace_anchor_bundle["summary"],
203  },
204  },
205  }
207  return bundle
208 
209 
211  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
212  if missing_fields:
213  raise ValueError(
214  "Metric-completeness bundle is missing required fields: {}".format(
215  ", ".join(missing_fields)
216  )
217  )
218 
219 
220 def write_artifact_bundle(output_path: Path, bundle):
222  output_path.parent.mkdir(parents=True, exist_ok=True)
223  output_path.write_text(
224  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
225  )
226 
227 
228 def run_validation(
229  *,
230  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
231  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
232  verbose=False,
233 ):
234  _, _, local_correctness_bundle = run_local_correctness_validation(verbose=verbose)
235  workflow_baseline_bundle, _, trace_anchor_bundle = run_trace_anchor_validation(
236  qubit_sizes=qubit_sizes,
237  parameter_set_count=parameter_set_count,
238  verbose=verbose,
239  )
240  bundle = build_artifact_bundle(
241  local_correctness_bundle,
242  workflow_baseline_bundle,
243  trace_anchor_bundle,
244  )
245  if verbose:
246  print(
247  "{} [{}] micro_missing={} workflow_missing={} trace_missing={}".format(
248  bundle["suite_name"],
249  bundle["status"],
250  bundle["summary"]["micro_cases_missing_required_metrics"],
251  bundle["summary"]["workflow_cases_missing_required_metrics"],
252  bundle["summary"]["trace_artifacts_missing_required_metrics"],
253  )
254  )
255  return (
256  local_correctness_bundle,
257  workflow_baseline_bundle,
258  trace_anchor_bundle,
259  bundle,
260  )
261 
262 
264  parser = argparse.ArgumentParser(description=__doc__)
265  parser.add_argument(
266  "--output-dir",
267  type=Path,
268  default=DEFAULT_OUTPUT_DIR,
269  help="Directory for the metric-completeness JSON artifact bundle.",
270  )
271  parser.add_argument(
272  "--parameter-set-count",
273  type=int,
274  default=EXACT_REGIME_PARAMETER_SET_COUNT,
275  help="Number of fixed parameter vectors per qubit size.",
276  )
277  parser.add_argument(
278  "--qubit-sizes",
279  type=int,
280  nargs="*",
281  default=list(EXACT_REGIME_WORKFLOW_QUBITS),
282  help="Workflow qubit sizes to include.",
283  )
284  parser.add_argument(
285  "--quiet",
286  action="store_true",
287  help="Suppress progress output.",
288  )
289  return parser.parse_args()
290 
291 
292 def main():
293  args = parse_args()
294  _, _, _, bundle = run_validation(
295  qubit_sizes=tuple(args.qubit_sizes),
296  parameter_set_count=args.parameter_set_count,
297  verbose=not args.quiet,
298  )
299  output_path = args.output_dir / ARTIFACT_FILENAME
300  write_artifact_bundle(output_path, bundle)
301  print(
302  "Wrote {} with status {}".format(
303  output_path,
304  bundle["status"],
305  )
306  )
307  if bundle["status"] != "pass":
308  raise SystemExit(1)
309 
310 
311 if __name__ == "__main__":
312  main()
def _missing_fields(payload, required_fields)
def _build_missing_field_map(cases, required_fields)
def build_artifact_bundle(local_correctness_bundle, workflow_baseline_bundle, trace_anchor_bundle)