Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
validation_evidence_publication_bundle.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: publication-ready validation bundle.
3 
4 Builds the top-level validation-evidence manifest by assembling the delivered
5 artifacts into one reproducible, machine-checkable package. The bundle
6 preserves the canonical raw trace artifact explicitly while keeping the other
7 validation-evidence bundles as first-class top-level evidence layers.
8 
9 Run with:
10  python benchmarks/density_matrix/validation_evidence/validation_evidence_publication_bundle.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.workflow_evidence.exact_density_vqe_validation import (
25  EXACT_REGIME_PARAMETER_SET_COUNT,
26  EXACT_REGIME_WORKFLOW_QUBITS,
27  build_software_metadata,
28  capture_case,
29  get_git_revision,
30  run_optimization_trace,
31  write_json,
32 )
33 from benchmarks.density_matrix.validation_evidence.local_correctness_validation import (
34  ARTIFACT_FILENAME as LOCAL_CORRECTNESS_ARTIFACT_FILENAME,
35  run_validation as run_local_correctness_validation,
36  write_artifact_bundle as write_local_correctness_bundle_file,
37 )
38 from benchmarks.density_matrix.validation_evidence.workflow_baseline_validation import (
39  ARTIFACT_FILENAME as WORKFLOW_BASELINE_ARTIFACT_FILENAME,
40  run_validation as run_workflow_baseline_validation,
41  write_artifact_bundle as write_workflow_baseline_bundle_file,
42 )
43 from benchmarks.density_matrix.validation_evidence.trace_anchor_validation import (
44  ARTIFACT_FILENAME as TRACE_ANCHOR_ARTIFACT_FILENAME,
45  TRACE_CASE_NAME,
46  TRACE_ARTIFACT_FILENAME as TRACE_ARTIFACT_FILENAME,
47  build_artifact_bundle as build_trace_anchor_bundle,
48  write_artifact_bundle as write_trace_anchor_bundle_file,
49 )
50 from benchmarks.density_matrix.validation_evidence.metric_completeness_validation import (
51  ARTIFACT_FILENAME as METRIC_COMPLETENESS_ARTIFACT_FILENAME,
52  build_artifact_bundle as build_metric_completeness_bundle,
53  write_artifact_bundle as write_metric_completeness_bundle_file,
54 )
55 from benchmarks.density_matrix.validation_evidence.interpretation_validation import (
56  ARTIFACT_FILENAME as INTERPRETATION_ARTIFACT_FILENAME,
57  build_artifact_bundle as build_validation_interpretation_bundle,
58  write_artifact_bundle as write_validation_interpretation_bundle_file,
59 )
60 from benchmarks.density_matrix.noise_support.optional_noise_classification_validation import (
61  build_artifact_bundle as build_optional_noise_bundle,
62  run_validation as run_optional_noise_validation,
63 )
64 from benchmarks.density_matrix.noise_support.unsupported_noise_validation import (
65  build_artifact_bundle as build_unsupported_noise_bundle,
66  run_validation as run_unsupported_noise_validation,
67 )
68 
69 SUITE_NAME = "validation_evidence_publication"
70 ARTIFACT_FILENAME = "validation_evidence_publication_bundle.json"
71 DEFAULT_OUTPUT_DIR = (
72  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "validation_evidence"
73 )
74 BUNDLE_FIELDS = (
75  "suite_name",
76  "status",
77  "backend",
78  "reference_backend",
79  "software",
80  "provenance",
81  "summary",
82  "artifacts",
83 )
84 
85 
87  *,
88  artifact_id,
89  artifact_class,
90  mandatory,
91  path,
92  status,
93  expected_statuses,
94  purpose,
95  generation_command,
96  summary,
97 ):
98  return {
99  "artifact_id": artifact_id,
100  "artifact_class": artifact_class,
101  "mandatory": mandatory,
102  "path": path,
103  "status": status,
104  "expected_statuses": list(expected_statuses),
105  "purpose": purpose,
106  "generation_command": generation_command,
107  "summary": dict(summary),
108  }
109 
110 
111 def _load_json(path: Path):
112  return json.loads(path.read_text(encoding="utf-8"))
113 
114 
116  output_dir: Path,
117  *,
118  local_correctness_bundle,
119  workflow_baseline_bundle,
120  trace_anchor_bundle,
121  trace_artifact,
122  metric_completeness_bundle,
123  interpretation_bundle,
124 ):
125  output_dir = Path(output_dir)
126  local_correctness_command = (
127  f"python benchmarks/density_matrix/validation_evidence/local_correctness_validation.py "
128  f"--output-dir {output_dir}"
129  )
130  workflow_baseline_command = (
131  f"python benchmarks/density_matrix/validation_evidence/workflow_baseline_validation.py "
132  f"--output-dir {output_dir}"
133  )
134  trace_anchor_command = (
135  f"python benchmarks/density_matrix/validation_evidence/trace_anchor_validation.py "
136  f"--output-dir {output_dir}"
137  )
138  metric_completeness_command = (
139  f"python benchmarks/density_matrix/validation_evidence/metric_completeness_validation.py "
140  f"--output-dir {output_dir}"
141  )
142  interpretation_command = (
143  f"python benchmarks/density_matrix/validation_evidence/interpretation_validation.py "
144  f"--output-dir {output_dir}"
145  )
146  publication_bundle_command = (
147  f"python benchmarks/density_matrix/validation_evidence/validation_evidence_publication_bundle.py "
148  f"--output-dir {output_dir}"
149  )
150 
151  artifacts = [
153  artifact_id="local_correctness_bundle",
154  artifact_class="local_correctness_baseline_bundle",
155  mandatory=True,
156  path=LOCAL_CORRECTNESS_ARTIFACT_FILENAME,
157  status=local_correctness_bundle["status"],
158  expected_statuses=["pass"],
159  purpose="Phase-level local correctness gate for the mandatory 1 to 3 qubit micro-validation matrix.",
160  generation_command=local_correctness_command,
161  summary={
162  "required_cases": local_correctness_bundle["summary"]["required_cases"],
163  "required_passed_cases": local_correctness_bundle["summary"][
164  "required_passed_cases"
165  ],
166  "required_pass_rate": local_correctness_bundle["summary"][
167  "required_pass_rate"
168  ],
169  "stable_case_ids_present": local_correctness_bundle["summary"][
170  "stable_case_ids_present"
171  ],
172  },
173  ),
175  artifact_id="workflow_baseline_bundle",
176  artifact_class="workflow_exact_regime_baseline_bundle",
177  mandatory=True,
178  path=WORKFLOW_BASELINE_ARTIFACT_FILENAME,
179  status=workflow_baseline_bundle["status"],
180  expected_statuses=["pass"],
181  purpose="Phase-level 4/6/8/10 workflow-scale exact-regime baseline.",
182  generation_command=workflow_baseline_command,
183  summary={
184  "required_cases": workflow_baseline_bundle["summary"]["required_cases"],
185  "required_passed_cases": workflow_baseline_bundle["summary"][
186  "required_passed_cases"
187  ],
188  "required_pass_rate": workflow_baseline_bundle["summary"][
189  "required_pass_rate"
190  ],
191  "documented_10q_anchor_present": workflow_baseline_bundle["summary"][
192  "documented_10q_anchor_present"
193  ],
194  "stable_case_ids_present": workflow_baseline_bundle["summary"][
195  "stable_case_ids_present"
196  ],
197  "stable_parameter_set_ids_present": workflow_baseline_bundle["summary"][
198  "stable_parameter_set_ids_present"
199  ],
200  },
201  ),
203  artifact_id="trace_anchor_bundle",
204  artifact_class="trace_and_anchor_bundle",
205  mandatory=True,
206  path=TRACE_ANCHOR_ARTIFACT_FILENAME,
207  status=trace_anchor_bundle["status"],
208  expected_statuses=["pass"],
209  purpose="Phase-level bounded trace plus documented 10-qubit anchor package.",
210  generation_command=trace_anchor_command,
211  summary={
212  "documented_10q_anchor_present": trace_anchor_bundle["summary"][
213  "documented_10q_anchor_present"
214  ],
215  "required_trace_case_name": trace_anchor_bundle["summary"][
216  "required_trace_case_name"
217  ],
218  "required_trace_present": trace_anchor_bundle["summary"][
219  "required_trace_present"
220  ],
221  "required_trace_completed": trace_anchor_bundle["summary"][
222  "required_trace_completed"
223  ],
224  "required_trace_bridge_supported": trace_anchor_bundle["summary"][
225  "required_trace_bridge_supported"
226  ],
227  },
228  ),
230  artifact_id="optimization_trace_4q",
231  artifact_class="raw_trace_artifact",
232  mandatory=True,
233  path=TRACE_ARTIFACT_FILENAME,
234  status=trace_artifact["status"],
235  expected_statuses=["completed"],
236  purpose="Canonical raw bounded optimization trace linked from the trace-and-anchor bundle.",
237  generation_command=trace_anchor_command,
238  summary={
239  "case_name": trace_artifact["case_name"],
240  "workflow_completed": trace_artifact["workflow_completed"],
241  "bridge_supported_pass": trace_artifact["bridge_supported_pass"],
242  "required_validation_trace": trace_artifact["required_validation_trace"],
243  },
244  ),
246  artifact_id="metric_completeness_bundle",
247  artifact_class="metric_completeness_bundle",
248  mandatory=True,
249  path=METRIC_COMPLETENESS_ARTIFACT_FILENAME,
250  status=metric_completeness_bundle["status"],
251  expected_statuses=["pass"],
252  purpose="Phase-level metric-completeness gate for mandatory supported evidence.",
253  generation_command=metric_completeness_command,
254  summary={
255  "micro_cases_missing_required_metrics": metric_completeness_bundle[
256  "summary"
257  ][
258  "micro_cases_missing_required_metrics"
259  ],
260  "workflow_cases_missing_required_metrics": metric_completeness_bundle[
261  "summary"
262  ][
263  "workflow_cases_missing_required_metrics"
264  ],
265  "trace_artifacts_missing_required_metrics": metric_completeness_bundle[
266  "summary"
267  ][
268  "trace_artifacts_missing_required_metrics"
269  ],
270  "metric_completeness_gate_completed": metric_completeness_bundle[
271  "summary"
272  ][
273  "metric_completeness_gate_completed"
274  ],
275  },
276  ),
278  artifact_id="interpretation_bundle",
279  artifact_class="interpretation_guardrail_bundle",
280  mandatory=True,
281  path=INTERPRETATION_ARTIFACT_FILENAME,
282  status=interpretation_bundle["status"],
283  expected_statuses=["pass"],
284  purpose="Phase-level interpretation guardrails preventing optional, unsupported, or incomplete evidence from inflating the main claim.",
285  generation_command=interpretation_command,
286  summary={
287  "mandatory_artifacts_complete": interpretation_bundle["summary"][
288  "mandatory_artifacts_complete"
289  ],
290  "optional_evidence_supplemental": interpretation_bundle["summary"][
291  "optional_evidence_supplemental"
292  ],
293  "unsupported_evidence_negative_only": interpretation_bundle["summary"][
294  "unsupported_evidence_negative_only"
295  ],
296  "main_validation_claim_completed": interpretation_bundle["summary"][
297  "main_validation_claim_completed"
298  ],
299  },
300  ),
301  ]
302 
303  mandatory_artifacts = [artifact for artifact in artifacts if artifact["mandatory"]]
304  present_count = 0
305  status_match_count = 0
306  for artifact in mandatory_artifacts:
307  if (output_dir / artifact["path"]).exists():
308  present_count += 1
309  if artifact["status"] in artifact["expected_statuses"]:
310  status_match_count += 1
311 
312  bundle_status = (
313  "pass"
314  if present_count == len(mandatory_artifacts)
315  and status_match_count == len(mandatory_artifacts)
316  else "fail"
317  )
318  bundle = {
319  "suite_name": SUITE_NAME,
320  "status": bundle_status,
321  "backend": local_correctness_bundle["backend"],
322  "reference_backend": local_correctness_bundle["reference_backend"],
323  "software": build_software_metadata(),
324  "provenance": {
325  "generation_command": publication_bundle_command,
326  "working_directory": str(REPO_ROOT),
327  "git_revision": get_git_revision(),
328  },
329  "summary": {
330  "mandatory_artifact_count": len(mandatory_artifacts),
331  "present_artifact_count": present_count,
332  "status_match_count": status_match_count,
333  "missing_artifact_count": len(mandatory_artifacts) - present_count,
334  "mismatched_status_count": len(mandatory_artifacts) - status_match_count,
335  "raw_trace_reference_pass": trace_anchor_bundle["summary"][
336  "required_trace_case_name"
337  ]
338  == trace_artifact["case_name"],
339  },
340  "artifacts": artifacts,
341  }
343  return bundle
344 
345 
347  missing_fields = [field for field in BUNDLE_FIELDS if field not in bundle]
348  if missing_fields:
349  raise ValueError(
350  "Validation-evidence publication bundle is missing required fields: {}".format(
351  ", ".join(missing_fields)
352  )
353  )
354 
355  artifact_ids = {artifact["artifact_id"] for artifact in bundle["artifacts"]}
356  required_ids = {
357  "local_correctness_bundle",
358  "workflow_baseline_bundle",
359  "trace_anchor_bundle",
360  "optimization_trace_4q",
361  "metric_completeness_bundle",
362  "interpretation_bundle",
363  }
364  missing_ids = required_ids - artifact_ids
365  if missing_ids:
366  raise ValueError(
367  "Validation-evidence publication bundle is missing required artifact IDs: {}".format(
368  ", ".join(sorted(missing_ids))
369  )
370  )
371 
372  required_summary_fields = {
373  "local_correctness_bundle": {
374  "required_cases",
375  "required_passed_cases",
376  "required_pass_rate",
377  "stable_case_ids_present",
378  },
379  "workflow_baseline_bundle": {
380  "required_cases",
381  "required_passed_cases",
382  "required_pass_rate",
383  "documented_10q_anchor_present",
384  "stable_case_ids_present",
385  "stable_parameter_set_ids_present",
386  },
387  "trace_anchor_bundle": {
388  "documented_10q_anchor_present",
389  "required_trace_case_name",
390  "required_trace_present",
391  "required_trace_completed",
392  "required_trace_bridge_supported",
393  },
394  "optimization_trace_4q": {
395  "case_name",
396  "workflow_completed",
397  "bridge_supported_pass",
398  "required_validation_trace",
399  },
400  "metric_completeness_bundle": {
401  "micro_cases_missing_required_metrics",
402  "workflow_cases_missing_required_metrics",
403  "trace_artifacts_missing_required_metrics",
404  "metric_completeness_gate_completed",
405  },
406  "interpretation_bundle": {
407  "mandatory_artifacts_complete",
408  "optional_evidence_supplemental",
409  "unsupported_evidence_negative_only",
410  "main_validation_claim_completed",
411  },
412  }
413 
414  for artifact in bundle["artifacts"]:
415  artifact_path = bundle_dir / artifact["path"]
416  if artifact["mandatory"] and not artifact_path.exists():
417  raise ValueError(
418  f"Validation-evidence publication bundle is missing artifact file: {artifact['path']}"
419  )
420  if artifact["status"] not in artifact["expected_statuses"]:
421  raise ValueError(
422  "Validation-evidence publication artifact {} has unexpected status {}".format(
423  artifact["artifact_id"], artifact["status"]
424  )
425  )
426 
427  payload = _load_json(artifact_path)
428  required_fields = required_summary_fields[artifact["artifact_id"]]
429  target = payload.get("summary", payload)
430  missing_summary_fields = [
431  field for field in required_fields if field not in target
432  ]
433  if missing_summary_fields:
434  raise ValueError(
435  "Artifact {} is missing required summary fields: {}".format(
436  artifact["artifact_id"], ", ".join(missing_summary_fields)
437  )
438  )
439 
440 
441 def write_validation_evidence_publication_bundle(output_path: Path, bundle):
442  validate_validation_evidence_publication_bundle(bundle, output_path.parent)
443  output_path.parent.mkdir(parents=True, exist_ok=True)
444  output_path.write_text(
445  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
446  )
447 
448 
450  output_dir: Path,
451  *,
452  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
453  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
454  verbose=False,
455 ):
456  output_dir = Path(output_dir)
457  output_dir.mkdir(parents=True, exist_ok=True)
458 
459  _, _, local_correctness_bundle = run_local_correctness_validation(verbose=verbose)
460  write_local_correctness_bundle_file(
461  output_dir / LOCAL_CORRECTNESS_ARTIFACT_FILENAME,
462  local_correctness_bundle,
463  )
464 
465  _, workflow_baseline_bundle = run_workflow_baseline_validation(
466  qubit_sizes=qubit_sizes,
467  parameter_set_count=parameter_set_count,
468  verbose=verbose,
469  )
470  write_workflow_baseline_bundle_file(
471  output_dir / WORKFLOW_BASELINE_ARTIFACT_FILENAME,
472  workflow_baseline_bundle,
473  )
474 
475  trace_artifact = capture_case(TRACE_CASE_NAME, run_optimization_trace)
476  trace_anchor_bundle = build_trace_anchor_bundle(
477  workflow_baseline_bundle,
478  trace_artifact,
479  qubit_sizes=qubit_sizes,
480  parameter_set_count=parameter_set_count,
481  )
482  write_trace_anchor_bundle_file(
483  output_dir / TRACE_ANCHOR_ARTIFACT_FILENAME,
484  trace_anchor_bundle,
485  )
486  write_json(output_dir / TRACE_ARTIFACT_FILENAME, trace_artifact)
487 
488  metric_completeness_bundle = build_metric_completeness_bundle(
489  local_correctness_bundle,
490  workflow_baseline_bundle,
491  trace_anchor_bundle,
492  )
493  write_metric_completeness_bundle_file(
494  output_dir / METRIC_COMPLETENESS_ARTIFACT_FILENAME,
495  metric_completeness_bundle,
496  )
497 
498  required_local_noise_bundle, required_local_noise_micro_bundle, optional_results = (
499  run_optional_noise_validation(verbose=verbose)
500  )
501  optional_bundle = build_optional_noise_bundle(
502  required_local_noise_bundle,
503  required_local_noise_micro_bundle,
504  optional_results,
505  )
506  unsupported_results = run_unsupported_noise_validation(verbose=verbose)
507  unsupported_bundle = build_unsupported_noise_bundle(unsupported_results)
508  interpretation_bundle = build_validation_interpretation_bundle(
509  metric_completeness_bundle,
510  optional_bundle,
511  unsupported_bundle,
512  )
513  write_validation_interpretation_bundle_file(
514  output_dir / INTERPRETATION_ARTIFACT_FILENAME,
515  interpretation_bundle,
516  )
517 
519  output_dir,
520  local_correctness_bundle=local_correctness_bundle,
521  workflow_baseline_bundle=workflow_baseline_bundle,
522  trace_anchor_bundle=trace_anchor_bundle,
523  trace_artifact=trace_artifact,
524  metric_completeness_bundle=metric_completeness_bundle,
525  interpretation_bundle=interpretation_bundle,
526  )
527  write_validation_evidence_publication_bundle(output_dir / ARTIFACT_FILENAME, bundle)
528  return bundle
529 
530 
532  parser = argparse.ArgumentParser(description=__doc__)
533  parser.add_argument(
534  "--output-dir",
535  type=Path,
536  default=DEFAULT_OUTPUT_DIR,
537  help="Directory for the validation-evidence publication JSON artifacts.",
538  )
539  parser.add_argument(
540  "--parameter-set-count",
541  type=int,
542  default=EXACT_REGIME_PARAMETER_SET_COUNT,
543  help="Number of fixed parameter vectors per workflow qubit size.",
544  )
545  parser.add_argument(
546  "--qubit-sizes",
547  type=int,
548  nargs="*",
549  default=list(EXACT_REGIME_WORKFLOW_QUBITS),
550  help="Workflow qubit sizes to include in the mandatory baseline.",
551  )
552  parser.add_argument(
553  "--quiet",
554  action="store_true",
555  help="Suppress progress output.",
556  )
557  return parser.parse_args()
558 
559 
560 def main():
561  args = parse_args()
563  args.output_dir,
564  qubit_sizes=tuple(args.qubit_sizes),
565  parameter_set_count=args.parameter_set_count,
566  verbose=not args.quiet,
567  )
568  print(
569  "Wrote {} with status {} ({}/{})".format(
570  args.output_dir / ARTIFACT_FILENAME,
571  bundle["status"],
572  bundle["summary"]["status_match_count"],
573  bundle["summary"]["mandatory_artifact_count"],
574  )
575  )
576  if bundle["status"] != "pass":
577  raise SystemExit(1)
578 
579 
580 if __name__ == "__main__":
581  main()
def _build_artifact_entry(artifact_id, artifact_class, mandatory, path, status, expected_statuses, purpose, generation_command, summary)
def build_software_metadata()