Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
unsupported_workflow_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: unsupported workflow boundaries.
3 
4 Builds the unsupported-boundary evidence layer from:
5 - the emitted canonical workflow contract,
6 - the emitted end-to-end trace bundle,
7 - the emitted matrix baseline bundle,
8 - the committed unsupported/deferred noise bundle,
9 - and the committed backend-mismatch unsupported case.
10 
11 This layer is intentionally thin:
12 - it keeps unsupported and deferred cases explicit and machine-readable,
13 - it binds them to the same canonical workflow identity as the positive-path
14  bundles,
15 - and it fails explicitly when negative evidence is incomplete or ambiguous.
16 
17 Run with:
18  python benchmarks/density_matrix/workflow_evidence/unsupported_workflow_validation.py
19 """
20 
21 from __future__ import annotations
22 
23 import argparse
24 import json
25 import sys
26 from collections import Counter
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.noise_support.support_tiers import (
34  SUPPORT_TIER_DEFERRED,
35  SUPPORT_TIER_UNSUPPORTED,
36 )
37 from benchmarks.density_matrix.workflow_evidence.workflow_contract_validation import (
38  ARTIFACT_FILENAME as WORKFLOW_CONTRACT_ARTIFACT_FILENAME,
39  CONTRACT_VERSION,
40  DEFAULT_OUTPUT_DIR as WORKFLOW_EVIDENCE_OUTPUT_DIR,
41  REFERENCE_BACKEND,
42  WORKFLOW_ID,
43  build_software_metadata,
44  get_git_revision,
45  run_validation as run_workflow_contract_validation,
46  validate_artifact_bundle as validate_workflow_contract_artifact,
47 )
48 from benchmarks.density_matrix.workflow_evidence.end_to_end_trace_validation import (
49  ARTIFACT_FILENAME as END_TO_END_TRACE_ARTIFACT_FILENAME,
50  run_validation as run_end_to_end_trace_validation,
51  validate_artifact_bundle as validate_end_to_end_trace_artifact,
52 )
53 from benchmarks.density_matrix.workflow_evidence.matrix_baseline_validation import (
54  ARTIFACT_FILENAME as MATRIX_BASELINE_ARTIFACT_FILENAME,
55  run_validation as run_matrix_baseline_validation,
56  validate_artifact_bundle as validate_matrix_baseline_artifact,
57 )
58 
59 SUITE_NAME = "unsupported_workflow_validation"
60 ARTIFACT_FILENAME = "unsupported_workflow_bundle.json"
61 DEFAULT_OUTPUT_DIR = WORKFLOW_EVIDENCE_OUTPUT_DIR
62 WORKFLOW_CONTRACT_PATH = DEFAULT_OUTPUT_DIR / WORKFLOW_CONTRACT_ARTIFACT_FILENAME
63 END_TO_END_TRACE_BUNDLE_PATH = DEFAULT_OUTPUT_DIR / END_TO_END_TRACE_ARTIFACT_FILENAME
64 MATRIX_BASELINE_BUNDLE_PATH = DEFAULT_OUTPUT_DIR / MATRIX_BASELINE_ARTIFACT_FILENAME
65 UNSUPPORTED_NOISE_BUNDLE_PATH = (
66  REPO_ROOT
67  / "benchmarks"
68  / "density_matrix"
69  / "artifacts"
70  / "noise_support"
71  / "unsupported_noise_bundle.json"
72 )
73 BACKEND_MISMATCH_CASE_PATH = (
74  REPO_ROOT
75  / "benchmarks"
76  / "density_matrix"
77  / "artifacts"
78  / "exact_density_validation"
79  / "unsupported_state_vector_density_noise.json"
80 )
81 BACKEND_MISMATCH_CASE_NAME = "unsupported_state_vector_density_noise"
82 ARTIFACT_CORE_FIELDS = (
83  "suite_name",
84  "status",
85  "workflow_id",
86  "contract_version",
87  "backend",
88  "reference_backend",
89  "requirements",
90  "thresholds",
91  "software",
92  "provenance",
93  "summary",
94  "required_artifacts",
95  "cases",
96 )
97 
98 
99 def _load_json(path: Path):
100  return json.loads(path.read_text(encoding="utf-8"))
101 
102 
103 def _load_workflow_contract(path: Path = WORKFLOW_CONTRACT_PATH):
104  if path.exists():
105  artifact = _load_json(path)
106  validate_workflow_contract_artifact(artifact)
107  return artifact
108  _, artifact = run_workflow_contract_validation(verbose=False)
109  return artifact
110 
111 
112 def _load_end_to_end_trace_bundle(path: Path = END_TO_END_TRACE_BUNDLE_PATH):
113  if path.exists():
114  artifact = _load_json(path)
115  validate_end_to_end_trace_artifact(artifact)
116  return artifact
117  _, _, _, artifact = run_end_to_end_trace_validation(verbose=False)
118  return artifact
119 
120 
121 def _load_matrix_baseline_bundle(path: Path = MATRIX_BASELINE_BUNDLE_PATH):
122  if path.exists():
123  artifact = _load_json(path)
124  validate_matrix_baseline_artifact(artifact)
125  return artifact
126  _, _, _, artifact = run_matrix_baseline_validation(verbose=False)
127  return artifact
128 
129 
131  return tuple(workflow_contract["output_contract"]["required_unsupported_case_fields"])
132 
133 
134 def build_requirement_metadata(unsupported_noise_bundle, workflow_contract):
135  categories = sorted(
136  set(case["unsupported_category"] for case in unsupported_noise_bundle["cases"])
137  | {"backend_incompatible_request"}
138  )
139  boundary_classes = sorted(
140  set(case["noise_boundary_class"] for case in unsupported_noise_bundle["cases"])
141  | {"backend_mode"}
142  )
143  required_case_names = [
144  case["case_name"] for case in unsupported_noise_bundle["cases"]
145  ] + [BACKEND_MISMATCH_CASE_NAME]
146  return {
147  "workflow_id": WORKFLOW_ID,
148  "contract_version": CONTRACT_VERSION,
149  "required_case_names": required_case_names,
150  "required_support_tiers": [
151  SUPPORT_TIER_DEFERRED,
152  SUPPORT_TIER_UNSUPPORTED,
153  ],
154  "required_case_fields": list(
155  get_required_unsupported_case_fields(workflow_contract)
156  ),
157  "required_categories": categories,
158  "required_boundary_classes": boundary_classes,
159  "required_bundle_sources": [
160  "workflow_contract_validation",
161  "end_to_end_trace_validation",
162  "matrix_baseline_validation",
163  "unsupported_noise_boundary",
164  "exact_density_validation_backend_mismatch_case",
165  ],
166  }
167 
168 
170  case = dict(raw_case)
171  case.update(
172  {
173  "reference_backend": REFERENCE_BACKEND,
174  "support_tier": SUPPORT_TIER_UNSUPPORTED,
175  "case_purpose": "unsupported_scope_guard",
176  "counts_toward_mandatory_baseline": False,
177  "source_unsupported_category": case.get("unsupported_category"),
178  "unsupported_category": "backend_incompatible_request",
179  "first_unsupported_condition": "state_vector_backend_density_noise",
180  "noise_boundary_class": "backend_mode",
181  "failure_stage": "density_anchor_preflight",
182  "pre_execution_failure_pass": True,
183  "silent_fallback_detected": False,
184  "silent_substitution_detected": False,
185  "unsupported_boundary_pass": case["status"] == "unsupported",
186  "workflow_completed": False,
187  }
188  )
189  return case
190 
191 
192 def _enrich_case(case):
193  case = dict(case)
194  case["workflow_id"] = WORKFLOW_ID
195  case["contract_version"] = CONTRACT_VERSION
196  case["workflow_evidence_role"] = "unsupported_boundary"
197  case["required_unsupported_case"] = True
198  return case
199 
200 
201 def validate_case_payload(case, required_fields):
202  missing_fields = [field for field in required_fields if field not in case]
203  if missing_fields:
204  raise ValueError(
205  "Unsupported-workflow case is missing required fields: {}".format(
206  ", ".join(missing_fields)
207  )
208  )
209 
210 
212  workflow_contract,
213  end_to_end_trace_bundle,
214  matrix_baseline_bundle,
215  unsupported_noise_bundle,
216  backend_mismatch_case,
217 ):
218  requirements = build_requirement_metadata(unsupported_noise_bundle, workflow_contract)
219  cases = [_enrich_case(case) for case in unsupported_noise_bundle["cases"]]
220  cases.append(_enrich_case(_augment_backend_mismatch_case(backend_mismatch_case)))
221  for case in cases:
222  validate_case_payload(case, requirements["required_case_fields"])
223 
224  expected_case_names = set(requirements["required_case_names"])
225  observed_case_names = [case["case_name"] for case in cases]
226  case_counts = Counter(observed_case_names)
227  duplicate_case_names = sorted(
228  case_name for case_name, count in case_counts.items() if count > 1
229  )
230  missing_case_names = sorted(expected_case_names - set(observed_case_names))
231  unexpected_case_names = sorted(set(observed_case_names) - expected_case_names)
232 
233  deferred_cases = sum(case["support_tier"] == SUPPORT_TIER_DEFERRED for case in cases)
234  unsupported_cases = sum(
235  case["support_tier"] == SUPPORT_TIER_UNSUPPORTED for case in cases
236  )
237  unsupported_status_cases = sum(case["status"] == "unsupported" for case in cases)
238  mandatory_baseline_case_count = sum(
239  case["counts_toward_mandatory_baseline"] for case in cases
240  )
241  pre_execution_failure_passed_cases = sum(
242  case.get("pre_execution_failure_pass", False) for case in cases
243  )
244  no_silent_fallback_cases = sum(
245  not case.get("silent_fallback_detected", False) for case in cases
246  )
247  no_silent_substitution_cases = sum(
248  not case.get("silent_substitution_detected", False) for case in cases
249  )
250  first_condition_present_cases = sum(
251  bool(case.get("first_unsupported_condition")) for case in cases
252  )
253  categories_present = sorted(set(case["unsupported_category"] for case in cases))
254  boundary_classes_present = sorted(
255  set(case["noise_boundary_class"] for case in cases)
256  )
257  backend_incompatible_case_present = any(
258  case["case_name"] == BACKEND_MISMATCH_CASE_NAME for case in cases
259  )
260  all_cases_match_contract = all(
261  case["workflow_id"] == workflow_contract["workflow_id"]
262  and case["contract_version"] == workflow_contract["contract_version"]
263  for case in cases
264  )
265  unsupported_gate_completed = bool(
266  workflow_contract["status"] == "pass"
267  and end_to_end_trace_bundle["status"] == "pass"
268  and matrix_baseline_bundle["status"] == "pass"
269  and unsupported_noise_bundle["status"] == "pass"
270  and not duplicate_case_names
271  and not missing_case_names
272  and not unexpected_case_names
273  and unsupported_status_cases == len(cases)
274  and mandatory_baseline_case_count == 0
275  and pre_execution_failure_passed_cases == len(cases)
276  and no_silent_fallback_cases == len(cases)
277  and no_silent_substitution_cases == len(cases)
278  and first_condition_present_cases == len(cases)
279  and backend_incompatible_case_present
280  and all_cases_match_contract
281  )
282 
283  bundle = {
284  "suite_name": SUITE_NAME,
285  "status": "pass" if unsupported_gate_completed else "fail",
286  "workflow_id": workflow_contract["workflow_id"],
287  "contract_version": workflow_contract["contract_version"],
288  "backend": workflow_contract["backend"],
289  "reference_backend": workflow_contract["reference_backend"],
290  "requirements": requirements,
291  "thresholds": {
292  "expected_status": "unsupported",
293  "silent_fallback_allowed": workflow_contract["input_contract"][
294  "backend_selection"
295  ]["silent_fallback_allowed"],
296  "silent_substitution_allowed": False,
297  "mandatory_baseline_case_count": 0,
298  },
299  "software": build_software_metadata(),
300  "provenance": {
301  "generation_command": (
302  "python benchmarks/density_matrix/"
303  "workflow_evidence/unsupported_workflow_validation.py"
304  ),
305  "working_directory": str(REPO_ROOT),
306  "git_revision": get_git_revision(),
307  "workflow_contract_path": str(WORKFLOW_CONTRACT_PATH),
308  "end_to_end_trace_bundle_path": str(END_TO_END_TRACE_BUNDLE_PATH),
309  "matrix_baseline_bundle_path": str(MATRIX_BASELINE_BUNDLE_PATH),
310  "unsupported_noise_bundle_path": str(UNSUPPORTED_NOISE_BUNDLE_PATH),
311  "backend_mismatch_case_path": str(BACKEND_MISMATCH_CASE_PATH),
312  },
313  "summary": {
314  "total_cases": len(cases),
315  "unsupported_status_cases": unsupported_status_cases,
316  "unsupported_cases": unsupported_cases,
317  "deferred_cases": deferred_cases,
318  "mandatory_baseline_case_count": mandatory_baseline_case_count,
319  "duplicate_case_names": duplicate_case_names,
320  "missing_case_names": missing_case_names,
321  "unexpected_case_names": unexpected_case_names,
322  "pre_execution_failure_passed_cases": pre_execution_failure_passed_cases,
323  "no_silent_fallback_cases": no_silent_fallback_cases,
324  "no_silent_substitution_cases": no_silent_substitution_cases,
325  "first_condition_present_cases": first_condition_present_cases,
326  "categories_present": categories_present,
327  "boundary_classes_present": boundary_classes_present,
328  "backend_incompatible_case_present": backend_incompatible_case_present,
329  "all_cases_match_contract": all_cases_match_contract,
330  "unsupported_gate_completed": unsupported_gate_completed,
331  },
332  "required_artifacts": {
333  "workflow_contract": {
334  "suite_name": workflow_contract["suite_name"],
335  "status": workflow_contract["status"],
336  "required_unsupported_case_fields": workflow_contract["output_contract"][
337  "required_unsupported_case_fields"
338  ],
339  "summary": workflow_contract["summary"],
340  },
341  "end_to_end_trace_reference": {
342  "suite_name": end_to_end_trace_bundle["suite_name"],
343  "status": end_to_end_trace_bundle["status"],
344  "summary": end_to_end_trace_bundle["summary"],
345  },
346  "matrix_baseline_reference": {
347  "suite_name": matrix_baseline_bundle["suite_name"],
348  "status": matrix_baseline_bundle["status"],
349  "summary": matrix_baseline_bundle["summary"],
350  },
351  "unsupported_noise_reference": {
352  "suite_name": unsupported_noise_bundle["suite_name"],
353  "status": unsupported_noise_bundle["status"],
354  "summary": unsupported_noise_bundle["summary"],
355  },
356  },
357  "cases": cases,
358  }
360  return bundle
361 
362 
364  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
365  if missing_fields:
366  raise ValueError(
367  "Unsupported-workflow bundle is missing required fields: {}".format(
368  ", ".join(missing_fields)
369  )
370  )
371 
372  if bundle["workflow_id"] != WORKFLOW_ID:
373  raise ValueError(
374  "Unsupported-workflow bundle has unexpected workflow_id '{}'".format(
375  bundle["workflow_id"]
376  )
377  )
378  if bundle["contract_version"] != CONTRACT_VERSION:
379  raise ValueError(
380  "Unsupported-workflow bundle has unexpected contract_version '{}'".format(
381  bundle["contract_version"]
382  )
383  )
384  for case in bundle["cases"]:
385  validate_case_payload(case, bundle["requirements"]["required_case_fields"])
386  if case["workflow_id"] != bundle["workflow_id"]:
387  raise ValueError(
388  "Unsupported-workflow case '{}' does not match bundle workflow_id".format(
389  case["case_name"]
390  )
391  )
392  if bundle["summary"]["unsupported_gate_completed"] != (bundle["status"] == "pass"):
393  raise ValueError(
394  "Unsupported-workflow bundle unsupported_gate_completed summary is inconsistent"
395  )
396 
397 
398 def write_artifact_bundle(output_path: Path, bundle):
400  output_path.parent.mkdir(parents=True, exist_ok=True)
401  output_path.write_text(
402  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
403  )
404 
405 
406 def run_validation(
407  *,
408  workflow_contract_path: Path = WORKFLOW_CONTRACT_PATH,
409  end_to_end_trace_bundle_path: Path = END_TO_END_TRACE_BUNDLE_PATH,
410  matrix_baseline_bundle_path: Path = MATRIX_BASELINE_BUNDLE_PATH,
411  unsupported_noise_bundle_path: Path = UNSUPPORTED_NOISE_BUNDLE_PATH,
412  backend_mismatch_case_path: Path = BACKEND_MISMATCH_CASE_PATH,
413  verbose=False,
414 ):
415  workflow_contract = _load_workflow_contract(workflow_contract_path)
416  end_to_end_trace_bundle = _load_end_to_end_trace_bundle(
417  end_to_end_trace_bundle_path
418  )
419  matrix_baseline_bundle = _load_matrix_baseline_bundle(matrix_baseline_bundle_path)
420  unsupported_noise_bundle = _load_json(unsupported_noise_bundle_path)
421  backend_mismatch_case = _load_json(backend_mismatch_case_path)
422  bundle = build_artifact_bundle(
423  workflow_contract,
424  end_to_end_trace_bundle,
425  matrix_baseline_bundle,
426  unsupported_noise_bundle,
427  backend_mismatch_case,
428  )
429  if verbose:
430  print(
431  "{} [{}] unsupported_cases={} backend_mismatch={}".format(
432  bundle["suite_name"],
433  bundle["status"],
434  bundle["summary"]["unsupported_status_cases"],
435  bundle["summary"]["backend_incompatible_case_present"],
436  )
437  )
438  return (
439  workflow_contract,
440  end_to_end_trace_bundle,
441  matrix_baseline_bundle,
442  unsupported_noise_bundle,
443  backend_mismatch_case,
444  bundle,
445  )
446 
447 
449  parser = argparse.ArgumentParser(description=__doc__)
450  parser.add_argument(
451  "--output-dir",
452  type=Path,
453  default=DEFAULT_OUTPUT_DIR,
454  help="Directory for the unsupported-workflow JSON artifact bundle.",
455  )
456  parser.add_argument(
457  "--workflow-contract-path",
458  type=Path,
459  default=WORKFLOW_CONTRACT_PATH,
460  help="Path to the canonical workflow-contract artifact.",
461  )
462  parser.add_argument(
463  "--end-to-end-trace-bundle-path",
464  type=Path,
465  default=END_TO_END_TRACE_BUNDLE_PATH,
466  help="Path to the end-to-end trace bundle.",
467  )
468  parser.add_argument(
469  "--matrix-baseline-bundle-path",
470  type=Path,
471  default=MATRIX_BASELINE_BUNDLE_PATH,
472  help="Path to the matrix-baseline bundle.",
473  )
474  parser.add_argument(
475  "--unsupported-noise-bundle-path",
476  type=Path,
477  default=UNSUPPORTED_NOISE_BUNDLE_PATH,
478  help="Path to the committed unsupported-noise bundle.",
479  )
480  parser.add_argument(
481  "--backend-mismatch-case-path",
482  type=Path,
483  default=BACKEND_MISMATCH_CASE_PATH,
484  help="Path to the committed backend-mismatch unsupported case.",
485  )
486  parser.add_argument(
487  "--quiet",
488  action="store_true",
489  help="Suppress summary output.",
490  )
491  return parser.parse_args()
492 
493 
494 def main():
495  args = parse_args()
496  *_, bundle = run_validation(
497  workflow_contract_path=args.workflow_contract_path,
498  end_to_end_trace_bundle_path=args.end_to_end_trace_bundle_path,
499  matrix_baseline_bundle_path=args.matrix_baseline_bundle_path,
500  unsupported_noise_bundle_path=args.unsupported_noise_bundle_path,
501  backend_mismatch_case_path=args.backend_mismatch_case_path,
502  verbose=not args.quiet,
503  )
504  output_path = args.output_dir / ARTIFACT_FILENAME
505  write_artifact_bundle(output_path, bundle)
506  print(
507  "Wrote {} with status {} ({})".format(
508  output_path,
509  bundle["status"],
510  bundle["summary"]["unsupported_status_cases"],
511  )
512  )
513  if bundle["status"] != "pass":
514  raise SystemExit(1)
515 
516 
517 if __name__ == "__main__":
518  main()
def build_software_metadata()
def build_requirement_metadata(unsupported_noise_bundle, workflow_contract)
def build_artifact_bundle(workflow_contract, end_to_end_trace_bundle, matrix_baseline_bundle, unsupported_noise_bundle, backend_mismatch_case)
def get_required_unsupported_case_fields(workflow_contract)