Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
workflow_contract_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: canonical workflow contract.
3 
4 Builds a machine-readable contract artifact for the canonical Phase 2 noisy
5 workflow. This is intentionally a thin contract layer:
6 - it freezes one stable workflow ID and contract version,
7 - it defines explicit input and output contract sections,
8 - it records supported / optional / deferred / unsupported workflow boundaries,
9 - and it links those contract sections back to the delivered validation-evidence
10  inventory without re-running the full validation stack.
11 
12 Run with:
13  python benchmarks/density_matrix/workflow_evidence/workflow_contract_validation.py
14 """
15 
16 from __future__ import annotations
17 
18 import argparse
19 import importlib.metadata
20 import json
21 import subprocess
22 import sys
23 from pathlib import Path
24 
25 import numpy as np
26 
27 REPO_ROOT = Path(__file__).resolve().parents[3]
28 if str(REPO_ROOT) not in sys.path:
29  sys.path.insert(0, str(REPO_ROOT))
30 
31 from benchmarks.density_matrix.noise_support.support_tiers import SUPPORT_TIER_VOCABULARY
32 
33 PRIMARY_BACKEND = "density_matrix"
34 REFERENCE_BACKEND = "qiskit_aer_density_matrix"
35 DEFAULT_ANSATZ = "HEA"
36 DEFAULT_LAYERS = 1
37 DEFAULT_INNER_BLOCKS = 1
38 FIXED_PARAMETER_QUBITS = (4, 6)
39 EXACT_REGIME_WORKFLOW_QUBITS = (4, 6, 8, 10)
40 EXACT_REGIME_PARAMETER_SET_COUNT = 10
41 WORKFLOW_ERROR_TOL = 1e-8
42 VALIDITY_TOL = 1e-10
43 TRACE_TOL = 1e-10
44 OBSERVABLE_IMAG_TOL = 1e-10
45 REQUIRED_PASS_RATE = 1.0
46 
47 SUITE_NAME = "workflow_contract_validation"
48 ARTIFACT_FILENAME = "workflow_contract_bundle.json"
49 DEFAULT_OUTPUT_DIR = (
50  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "workflow_evidence"
51 )
52 VALIDATION_EVIDENCE_REFERENCE_BUNDLE_PATH = (
53  REPO_ROOT
54  / "benchmarks"
55  / "density_matrix"
56  / "artifacts"
57  / "validation_evidence"
58  / "validation_evidence_publication_bundle.json"
59 )
60 WORKFLOW_ID = "phase2_xxz_hea_density_matrix_anchor_workflow"
61 CONTRACT_VERSION = "v1"
62 STATUS_VOCABULARY = ("pass", "fail", "incomplete", "completed", "unsupported")
63 BOUNDARY_CLASS_NAMES = ("supported", "optional", "deferred", "unsupported")
64 ARTIFACT_CORE_FIELDS = (
65  "suite_name",
66  "status",
67  "workflow_id",
68  "contract_version",
69  "backend",
70  "reference_backend",
71  "requirements",
72  "thresholds",
73  "input_contract",
74  "output_contract",
75  "boundary_classification",
76  "reference_artifacts",
77  "software",
78  "provenance",
79  "summary",
80 )
81 THRESHOLD_CORE_FIELDS = (
82  "absolute_energy_error",
83  "rho_is_valid_tol",
84  "trace_deviation",
85  "observable_imag_abs",
86  "required_pass_rate",
87  "required_end_to_end_qubits",
88  "required_workflow_qubits",
89  "fixed_parameter_sets_per_size",
90  "documented_anchor_qubit",
91 )
92 
93 
95  return [
96  {
97  "channel": "local_depolarizing",
98  "target": 0,
99  "after_gate_index": 0,
100  "error_rate": 0.1,
101  },
102  {
103  "channel": "amplitude_damping",
104  "target": 1,
105  "after_gate_index": 2,
106  "gamma": 0.05,
107  },
108  {
109  "channel": "phase_damping",
110  "target": 0,
111  "after_gate_index": 4,
112  "lambda": 0.07,
113  },
114  ]
115 
116 
117 def build_open_chain_topology(qbit_num: int):
118  return [(idx, idx + 1) for idx in range(qbit_num - 1)]
119 
120 
122  return {
123  "max_inner_iterations": 4,
124  "max_iterations": 1,
125  "convergence_length": 2,
126  }
127 
128 
130  return {
131  "Jx": 1.0,
132  "Jy": 1.0,
133  "Jz": 1.0,
134  "h": 0.5,
135  }
136 
137 
138 def _get_package_version(name: str):
139  try:
140  return importlib.metadata.version(name)
141  except importlib.metadata.PackageNotFoundError:
142  return "unavailable"
143 
144 
146  return {
147  "python": sys.version.split()[0],
148  "numpy": np.__version__,
149  "qiskit": _get_package_version("qiskit"),
150  "qiskit_aer": _get_package_version("qiskit-aer"),
151  }
152 
153 
155  try:
156  result = subprocess.run(
157  ["git", "rev-parse", "HEAD"],
158  cwd=REPO_ROOT,
159  capture_output=True,
160  text=True,
161  check=True,
162  )
163  return result.stdout.strip()
164  except Exception:
165  return "unknown"
166 
167 
169  reference_path: Path = VALIDATION_EVIDENCE_REFERENCE_BUNDLE_PATH,
170 ):
171  payload = json.loads(reference_path.read_text(encoding="utf-8"))
172  required_fields = ("suite_name", "status", "artifacts", "software", "provenance")
173  missing_fields = [field for field in required_fields if field not in payload]
174  if missing_fields:
175  raise ValueError(
176  "Validation-evidence reference bundle is missing required fields: {}".format(
177  ", ".join(missing_fields)
178  )
179  )
180  return payload
181 
182 
183 def build_requirement_metadata(reference_bundle):
184  mandatory_reference_artifact_ids = [
185  artifact["artifact_id"]
186  for artifact in reference_bundle["artifacts"]
187  if artifact.get("mandatory", False)
188  ]
189  return {
190  "workflow_id": WORKFLOW_ID,
191  "contract_version": CONTRACT_VERSION,
192  "support_tier_vocabulary": list(SUPPORT_TIER_VOCABULARY),
193  "status_vocabulary": list(STATUS_VOCABULARY),
194  "end_to_end_qubits": list(FIXED_PARAMETER_QUBITS),
195  "fixed_parameter_matrix_qubits": list(EXACT_REGIME_WORKFLOW_QUBITS),
196  "documented_anchor_qubit": 10,
197  "fixed_parameter_sets_per_size": EXACT_REGIME_PARAMETER_SET_COUNT,
198  "required_input_fields": [
199  "workflow_id",
200  "contract_version",
201  "hamiltonian_family",
202  "hamiltonian_parameters",
203  "qubit_inventory",
204  "ansatz",
205  "backend_selection",
206  "noise_schedule_policy",
207  "execution_modes",
208  "seed_policy",
209  ],
210  "required_output_fields": [
211  "real_energy_semantics",
212  "case_status_vocabulary",
213  "bundle_status_vocabulary",
214  "aggregate_status_semantics",
215  "required_case_fields",
216  "required_trace_fields",
217  "required_unsupported_case_fields",
218  "required_bundle_fields",
219  "stability_metrics",
220  ],
221  "required_threshold_fields": list(THRESHOLD_CORE_FIELDS),
222  "required_boundary_classes": list(BOUNDARY_CLASS_NAMES),
223  "required_reference_artifact_ids": mandatory_reference_artifact_ids,
224  "required_reference_bundle_sources": [
225  "validation_evidence_publication",
226  ],
227  }
228 
229 
231  return {
232  "absolute_energy_error": WORKFLOW_ERROR_TOL,
233  "rho_is_valid_tol": VALIDITY_TOL,
234  "trace_deviation": TRACE_TOL,
235  "observable_imag_abs": OBSERVABLE_IMAG_TOL,
236  "required_pass_rate": REQUIRED_PASS_RATE,
237  "required_end_to_end_qubits": list(FIXED_PARAMETER_QUBITS),
238  "required_workflow_qubits": list(EXACT_REGIME_WORKFLOW_QUBITS),
239  "fixed_parameter_sets_per_size": EXACT_REGIME_PARAMETER_SET_COUNT,
240  "documented_anchor_qubit": 10,
241  }
242 
243 
245  return {
246  "workflow_id": WORKFLOW_ID,
247  "contract_version": CONTRACT_VERSION,
248  "workflow_family": "noisy_vqe_ground_state_estimation",
249  "hamiltonian_family": "1d_xxz_with_local_z_field",
250  "hamiltonian_parameters": build_hamiltonian_metadata(),
251  "qubit_inventory": {
252  "end_to_end_qubits": list(FIXED_PARAMETER_QUBITS),
253  "fixed_parameter_matrix_qubits": list(EXACT_REGIME_WORKFLOW_QUBITS),
254  "documented_anchor_qubit": 10,
255  "topology_family": "open_chain",
256  "example_topology_4q": build_open_chain_topology(4),
257  },
258  "ansatz": {
259  "family": DEFAULT_ANSATZ,
260  "layers": DEFAULT_LAYERS,
261  "inner_blocks": DEFAULT_INNER_BLOCKS,
262  "source_type": "generated_hea_circuit",
263  },
264  "backend_selection": {
265  "selected_backend": PRIMARY_BACKEND,
266  "selection_mode": "explicit",
267  "reference_backend": REFERENCE_BACKEND,
268  "silent_fallback_allowed": False,
269  },
270  "noise_schedule_policy": {
271  "insertion_policy": "explicit_ordered_after_gate_index",
272  "required_local_noise_models": [
273  "local_depolarizing",
274  "amplitude_damping",
275  "phase_damping",
276  ],
277  "canonical_example_schedule": build_reference_noise(),
278  },
279  "execution_modes": {
280  "fixed_parameter_matrix": {
281  "required": True,
282  "parameter_sets_per_size": EXACT_REGIME_PARAMETER_SET_COUNT,
283  },
284  "bounded_optimization_trace": {
285  "required": True,
286  "canonical_trace_case_name": "optimization_trace_4q",
287  "optimizer_name": "COSINE",
288  "optimizer_config": build_optimizer_config(),
289  },
290  },
291  "seed_policy": {
292  "fixed_parameter_matrix": {
293  "source": "deterministic_parameter_set_schedule",
294  "generator": "build_exact_regime_parameter_sets",
295  "random_seed_required": False,
296  },
297  "bounded_optimization_trace": {
298  "initial_parameter_source": "deterministic_linspace_schedule",
299  "generator": "build_initial_parameters",
300  "random_seed_required": False,
301  },
302  },
303  }
304 
305 
307  return {
308  "real_energy_semantics": "Return exact Hermitian energy through Re Tr(H*rho).",
309  "case_status_vocabulary": list(STATUS_VOCABULARY),
310  "bundle_status_vocabulary": ["pass", "fail"],
311  "aggregate_status_semantics": {
312  "pass": "All required contract sections, thresholds, boundary classes, and reference artifacts are present.",
313  "fail": "At least one required contract section, threshold, boundary class, or reference artifact is missing or inconsistent.",
314  },
315  "required_case_fields": [
316  "case_name",
317  "status",
318  "backend",
319  "reference_backend",
320  "qbit_num",
321  "support_tier",
322  "case_purpose",
323  "counts_toward_mandatory_baseline",
324  "workflow_completed",
325  "absolute_energy_error",
326  "energy_pass",
327  "density_valid_pass",
328  "trace_pass",
329  "observable_pass",
330  "bridge_supported_pass",
331  "total_case_runtime_ms",
332  "process_peak_rss_kb",
333  ],
334  "required_trace_fields": [
335  "case_name",
336  "status",
337  "workflow_completed",
338  "bridge_supported_pass",
339  "optimizer",
340  "parameter_count",
341  "initial_energy",
342  "final_energy",
343  "energy_improvement",
344  "total_trace_runtime_ms",
345  "process_peak_rss_kb",
346  ],
347  "required_unsupported_case_fields": [
348  "case_name",
349  "status",
350  "backend",
351  "support_tier",
352  "case_purpose",
353  "counts_toward_mandatory_baseline",
354  "unsupported_category",
355  "unsupported_reason",
356  "first_unsupported_condition",
357  "noise_boundary_class",
358  "failure_stage",
359  "workflow_id",
360  "contract_version",
361  ],
362  "required_bundle_fields": list(ARTIFACT_CORE_FIELDS),
363  "stability_metrics": [
364  "workflow_completed",
365  "total_case_runtime_ms",
366  "total_trace_runtime_ms",
367  "process_peak_rss_kb",
368  ],
369  }
370 
371 
373  return {
374  "supported": {
375  "backend_modes": [PRIMARY_BACKEND],
376  "workflow_anchor": "xxz_plus_hea_plus_density_matrix",
377  "bridge_source_type": "generated_hea_circuit",
378  "required_gate_families": ["U3", "CNOT"],
379  "required_local_noise_models": [
380  "local_depolarizing",
381  "amplitude_damping",
382  "phase_damping",
383  ],
384  "execution_modes": [
385  "fixed_parameter_matrix",
386  "bounded_optimization_trace",
387  ],
388  },
389  "optional": {
390  "secondary_reference_baselines": [
391  "one_additional_simulator_if_justified",
392  ],
393  "regression_or_stress_only": [
394  "whole_register_depolarizing",
395  ],
396  "supplemental_workflow_evidence": [
397  "extra_fixed_parameter_cases_not_counting_toward_mandatory_closure",
398  ],
399  },
400  "deferred": {
401  "noise_families": [
402  "correlated_multi_qubit_noise",
403  "readout_noise",
404  "calibration_aware_noise",
405  "non_markovian_noise",
406  ],
407  "workflow_extensions": [
408  "broader_noisy_algorithm_families",
409  "broader_hamiltonian_classes",
410  "phase3_acceleration_claims",
411  "phase4_optimizer_studies",
412  ],
413  },
414  "unsupported": {
415  "backend_behaviors": [
416  "implicit_auto_backend_selection",
417  "silent_density_to_state_vector_fallback",
418  ],
419  "workflow_conditions": [
420  "unsupported_bridge_input",
421  "unsupported_gate_or_noise_schedule",
422  "unsupported_observable_request",
423  "backend_incompatible_request",
424  ],
425  },
426  }
427 
428 
429 def build_reference_artifacts(reference_bundle):
430  artifacts = []
431  for artifact in reference_bundle["artifacts"]:
432  artifacts.append(
433  {
434  "artifact_id": artifact["artifact_id"],
435  "artifact_class": artifact["artifact_class"],
436  "mandatory": artifact["mandatory"],
437  "path": artifact["path"],
438  "status": artifact["status"],
439  "expected_statuses": list(artifact["expected_statuses"]),
440  "purpose": artifact["purpose"],
441  "generation_command": artifact["generation_command"],
442  }
443  )
444  return artifacts
445 
446 
448  required_input_fields = artifact["requirements"]["required_input_fields"]
449  required_output_fields = artifact["requirements"]["required_output_fields"]
450  required_bundle_fields = artifact["output_contract"]["required_bundle_fields"]
451  required_threshold_fields = artifact["requirements"]["required_threshold_fields"]
452  required_boundary_classes = set(artifact["requirements"]["required_boundary_classes"])
453  return bool(
454  artifact["workflow_id"]
455  and artifact["contract_version"]
456  and all(field in artifact["input_contract"] for field in required_input_fields)
457  and all(field in artifact["output_contract"] for field in required_output_fields)
458  and all(field in artifact for field in required_bundle_fields)
459  and all(field in artifact["thresholds"] for field in required_threshold_fields)
460  and required_boundary_classes == set(artifact["boundary_classification"].keys())
461  and artifact["reference_artifacts"]
462  )
463 
464 
465 def build_artifact_bundle(reference_bundle):
466  artifact = {
467  "suite_name": SUITE_NAME,
468  "status": "fail",
469  "workflow_id": WORKFLOW_ID,
470  "contract_version": CONTRACT_VERSION,
471  "backend": PRIMARY_BACKEND,
472  "reference_backend": REFERENCE_BACKEND,
473  "requirements": build_requirement_metadata(reference_bundle),
474  "thresholds": build_threshold_metadata(),
475  "input_contract": build_input_contract(),
476  "output_contract": build_output_contract(),
477  "boundary_classification": build_boundary_classification(),
478  "reference_artifacts": build_reference_artifacts(reference_bundle),
479  "software": build_software_metadata(),
480  "provenance": {
481  "generation_command": (
482  "python benchmarks/density_matrix/"
483  "workflow_evidence/workflow_contract_validation.py"
484  ),
485  "working_directory": str(REPO_ROOT),
486  "git_revision": get_git_revision(),
487  "reference_validation_bundle_path": str(
488  VALIDATION_EVIDENCE_REFERENCE_BUNDLE_PATH
489  ),
490  },
491  "summary": {},
492  }
493  artifact["summary"] = {
494  "required_input_field_count": len(
495  artifact["requirements"]["required_input_fields"]
496  ),
497  "required_output_field_count": len(
498  artifact["requirements"]["required_output_fields"]
499  ),
500  "required_threshold_field_count": len(
501  artifact["requirements"]["required_threshold_fields"]
502  ),
503  "required_bundle_field_count": len(
504  artifact["output_contract"]["required_bundle_fields"]
505  ),
506  "boundary_class_count": len(artifact["boundary_classification"]),
507  "mandatory_reference_artifact_count": sum(
508  entry["mandatory"] for entry in artifact["reference_artifacts"]
509  ),
510  "reference_artifact_count": len(artifact["reference_artifacts"]),
511  "contract_sections_complete": _contract_sections_complete(artifact),
512  }
513  artifact["status"] = "pass" if artifact["summary"]["contract_sections_complete"] else "fail"
514  validate_artifact_bundle(artifact)
515  return artifact
516 
517 
519  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in artifact]
520  if missing_fields:
521  raise ValueError(
522  "Workflow contract artifact is missing required fields: {}".format(
523  ", ".join(missing_fields)
524  )
525  )
526 
527  if not artifact["workflow_id"]:
528  raise ValueError("Workflow contract workflow_id must be non-empty")
529  if not artifact["contract_version"]:
530  raise ValueError("Workflow contract contract_version must be non-empty")
531 
532  if artifact["status"] not in {"pass", "fail"}:
533  raise ValueError(
534  "Workflow contract artifact has unsupported status '{}'".format(
535  artifact["status"]
536  )
537  )
538 
539  required_boundary_classes = set(artifact["requirements"]["required_boundary_classes"])
540  observed_boundary_classes = set(artifact["boundary_classification"].keys())
541  if required_boundary_classes != observed_boundary_classes:
542  raise ValueError(
543  "Workflow contract boundary classes mismatch: expected {}, observed {}".format(
544  sorted(required_boundary_classes), sorted(observed_boundary_classes)
545  )
546  )
547 
548  for field in artifact["requirements"]["required_input_fields"]:
549  if field not in artifact["input_contract"]:
550  raise ValueError(
551  "Workflow contract input_contract is missing required field '{}'".format(
552  field
553  )
554  )
555 
556  for field in artifact["requirements"]["required_output_fields"]:
557  if field not in artifact["output_contract"]:
558  raise ValueError(
559  "Workflow contract output_contract is missing required field '{}'".format(
560  field
561  )
562  )
563 
564  for field in artifact["output_contract"]["required_bundle_fields"]:
565  if field not in artifact:
566  raise ValueError(
567  "Workflow contract artifact is missing required bundle field '{}'".format(
568  field
569  )
570  )
571 
572  for field in artifact["requirements"]["required_threshold_fields"]:
573  if field not in artifact["thresholds"]:
574  raise ValueError(
575  "Workflow contract thresholds are missing required field '{}'".format(
576  field
577  )
578  )
579 
580  aggregate_status_semantics = artifact["output_contract"]["aggregate_status_semantics"]
581  if set(aggregate_status_semantics.keys()) != {"pass", "fail"}:
582  raise ValueError(
583  "Workflow contract aggregate_status_semantics must define exactly 'pass' and 'fail'"
584  )
585 
586  if not artifact["reference_artifacts"]:
587  raise ValueError("Workflow contract requires at least one reference artifact")
588 
589  required_reference_fields = (
590  "artifact_id",
591  "artifact_class",
592  "mandatory",
593  "path",
594  "status",
595  "expected_statuses",
596  "purpose",
597  "generation_command",
598  )
599  for entry in artifact["reference_artifacts"]:
600  missing_reference_fields = [
601  field for field in required_reference_fields if field not in entry
602  ]
603  if missing_reference_fields:
604  raise ValueError(
605  "Workflow contract reference artifact is missing fields: {}".format(
606  ", ".join(missing_reference_fields)
607  )
608  )
609 
610  contract_sections_complete = _contract_sections_complete(artifact)
611  if artifact["summary"]["contract_sections_complete"] != contract_sections_complete:
612  raise ValueError(
613  "Workflow contract contract_sections_complete summary is inconsistent"
614  )
615 
616 
617 def write_artifact_bundle(output_path: Path, artifact):
618  validate_artifact_bundle(artifact)
619  output_path.parent.mkdir(parents=True, exist_ok=True)
620  output_path.write_text(
621  json.dumps(artifact, indent=2, sort_keys=True) + "\n", encoding="utf-8"
622  )
623 
624 
625 def run_validation(
626  *,
627  verbose=False,
628  reference_bundle_path: Path = VALIDATION_EVIDENCE_REFERENCE_BUNDLE_PATH,
629 ):
630  reference_bundle = _load_reference_validation_bundle(reference_bundle_path)
631  artifact = build_artifact_bundle(reference_bundle)
632  if verbose:
633  print(
634  "{} [{}] workflow_id={} reference_artifacts={}".format(
635  artifact["suite_name"],
636  artifact["status"],
637  artifact["workflow_id"],
638  artifact["summary"]["reference_artifact_count"],
639  )
640  )
641  return reference_bundle, artifact
642 
643 
645  parser = argparse.ArgumentParser(description=__doc__)
646  parser.add_argument(
647  "--output-dir",
648  type=Path,
649  default=DEFAULT_OUTPUT_DIR,
650  help="Directory for the workflow-contract JSON artifact bundle.",
651  )
652  parser.add_argument(
653  "--reference-bundle-path",
654  type=Path,
655  default=VALIDATION_EVIDENCE_REFERENCE_BUNDLE_PATH,
656  help="Path to the validation-evidence bundle used as the reference inventory.",
657  )
658  parser.add_argument(
659  "--quiet",
660  action="store_true",
661  help="Suppress summary output.",
662  )
663  return parser.parse_args()
664 
665 
666 def main():
667  args = parse_args()
668  _, artifact = run_validation(
669  verbose=not args.quiet,
670  reference_bundle_path=args.reference_bundle_path,
671  )
672  output_path = args.output_dir / ARTIFACT_FILENAME
673  write_artifact_bundle(output_path, artifact)
674  print(
675  "Wrote {} with status {} ({})".format(
676  output_path,
677  artifact["status"],
678  artifact["workflow_id"],
679  )
680  )
681  if artifact["status"] != "pass":
682  raise SystemExit(1)
683 
684 
685 if __name__ == "__main__":
686  main()
def build_requirement_metadata(reference_bundle)