Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
workflow_baseline_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: exact-regime workflow baseline.
3 
4 Builds the phase-level workflow-scale gate from the canonical exact-regime
5 workflow matrix while keeping the dedicated optimization trace out of scope
6 until the trace-anchor layer.
7 
8 The resulting bundle is intentionally a thin validation-evidence layer:
9 - it freezes the mandatory 4 / 6 / 8 / 10 workflow inventory,
10 - it validates stable workflow case identity and parameter-set coverage,
11 - it preserves exactness, backend attribution, and unsupported-free completion,
12 - and it makes incomplete or partial workflow evidence fail explicitly.
13 
14 Run with:
15  python benchmarks/density_matrix/validation_evidence/workflow_baseline_validation.py
16 """
17 
18 from __future__ import annotations
19 
20 import argparse
21 import json
22 import sys
23 from collections import Counter, defaultdict
24 from pathlib import Path
25 
26 REPO_ROOT = Path(__file__).resolve().parents[3]
27 if str(REPO_ROOT) not in sys.path:
28  sys.path.insert(0, str(REPO_ROOT))
29 
30 from benchmarks.density_matrix.workflow_evidence.exact_density_vqe_validation import (
31  PRIMARY_BACKEND,
32  REFERENCE_BACKEND,
33  EXACT_REGIME_PARAMETER_SET_COUNT,
34  EXACT_REGIME_WORKFLOW_QUBITS,
35  build_software_metadata,
36  build_exact_regime_threshold_metadata,
37  build_exact_regime_workflow_bundle,
38  run_exact_regime_workflow_matrix,
39 )
40 from benchmarks.density_matrix.noise_support.required_local_noise_micro_validation import (
41  REQUIRED_LOCAL_NOISE_MODELS,
42 )
43 from benchmarks.density_matrix.noise_support.support_tiers import (
44  SUPPORT_TIER_VOCABULARY,
45  build_support_tier_summary,
46 )
47 
48 SUITE_NAME = "workflow_baseline_validation"
49 ARTIFACT_FILENAME = "workflow_baseline_bundle.json"
50 DEFAULT_OUTPUT_DIR = (
51  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "validation_evidence"
52 )
53 ARTIFACT_CORE_FIELDS = (
54  "suite_name",
55  "status",
56  "backend",
57  "reference_backend",
58  "requirements",
59  "thresholds",
60  "software",
61  "summary",
62  "required_artifacts",
63  "cases",
64 )
65 
66 
68  *, qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS, parameter_set_count=EXACT_REGIME_PARAMETER_SET_COUNT
69 ):
70  parameter_set_ids = [f"set_{idx:02d}" for idx in range(parameter_set_count)]
71  mandatory_case_names = [
72  f"exact_regime_{qbit_num}q_{parameter_set_id}"
73  for qbit_num in qubit_sizes
74  for parameter_set_id in parameter_set_ids
75  ]
76  return {
77  "mandatory_workflow_qubits": list(qubit_sizes),
78  "fixed_parameter_sets_per_size": parameter_set_count,
79  "mandatory_parameter_set_ids": parameter_set_ids,
80  "mandatory_case_names": mandatory_case_names,
81  "required_gate_families": ["U3", "CNOT"],
82  "required_local_noise_models": list(REQUIRED_LOCAL_NOISE_MODELS),
83  "support_tier_vocabulary": list(SUPPORT_TIER_VOCABULARY),
84  "required_bundle_sources": ["exact_regime_workflow"],
85  "required_pass_rate": 1.0,
86  }
87 
88 
90  required_fields = (
91  "case_name",
92  "status",
93  "backend",
94  "reference_backend",
95  "qbit_num",
96  "workflow_completed",
97  "parameter_set_id",
98  "absolute_energy_error",
99  "energy_pass",
100  "density_valid_pass",
101  "trace_pass",
102  "observable_pass",
103  "bridge_supported_pass",
104  "support_tier",
105  "case_purpose",
106  "counts_toward_mandatory_baseline",
107  )
108  missing_fields = [field for field in required_fields if field not in case]
109  if missing_fields:
110  raise ValueError(
111  "Workflow-baseline case is missing required fields: {}".format(
112  ", ".join(missing_fields)
113  )
114  )
115 
116 
118  cases,
119  *,
120  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
121  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
122 ):
123  observed_case_names = [case["case_name"] for case in cases]
124  case_name_counts = Counter(observed_case_names)
125  duplicate_case_names = sorted(
126  case_name for case_name, count in case_name_counts.items() if count > 1
127  )
128 
129  expected_parameter_set_ids = [f"set_{idx:02d}" for idx in range(parameter_set_count)]
130  expected_case_names = {
131  f"exact_regime_{qbit_num}q_{parameter_set_id}"
132  for qbit_num in qubit_sizes
133  for parameter_set_id in expected_parameter_set_ids
134  }
135  observed_case_name_set = set(observed_case_names)
136  missing_mandatory_case_names = sorted(expected_case_names - observed_case_name_set)
137  unexpected_case_names = sorted(observed_case_name_set - expected_case_names)
138 
139  parameter_sets_per_qbit = defaultdict(list)
140  for case in cases:
141  parameter_sets_per_qbit[case["qbit_num"]].append(case["parameter_set_id"])
142 
143  missing_parameter_set_ids_by_qbit = {}
144  duplicate_parameter_set_ids_by_qbit = {}
145  cases_per_qbit = {}
146  for qbit_num in qubit_sizes:
147  observed_ids = parameter_sets_per_qbit.get(qbit_num, [])
148  counts = Counter(observed_ids)
149  duplicate_ids = sorted(
150  parameter_set_id
151  for parameter_set_id, count in counts.items()
152  if count > 1
153  )
154  missing_ids = sorted(set(expected_parameter_set_ids) - set(observed_ids))
155  duplicate_parameter_set_ids_by_qbit[str(qbit_num)] = duplicate_ids
156  missing_parameter_set_ids_by_qbit[str(qbit_num)] = missing_ids
157  cases_per_qbit[str(qbit_num)] = len(observed_ids)
158 
159  stable_case_ids_present = (
160  not missing_mandatory_case_names
161  and not duplicate_case_names
162  and not unexpected_case_names
163  and len(observed_case_names) == len(expected_case_names)
164  )
165  stable_parameter_set_ids_present = all(
166  not missing_parameter_set_ids_by_qbit[str(qbit_num)]
167  and not duplicate_parameter_set_ids_by_qbit[str(qbit_num)]
168  for qbit_num in qubit_sizes
169  )
170 
171  return {
172  "observed_case_names": observed_case_names,
173  "missing_mandatory_case_names": missing_mandatory_case_names,
174  "duplicate_case_names": duplicate_case_names,
175  "unexpected_case_names": unexpected_case_names,
176  "stable_case_ids_present": stable_case_ids_present,
177  "cases_per_qbit": cases_per_qbit,
178  "missing_parameter_set_ids_by_qbit": missing_parameter_set_ids_by_qbit,
179  "duplicate_parameter_set_ids_by_qbit": duplicate_parameter_set_ids_by_qbit,
180  "stable_parameter_set_ids_present": stable_parameter_set_ids_present,
181  }
182 
183 
185  exact_regime_workflow_bundle,
186  workflow_results,
187  *,
188  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
189  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
190 ):
191  cases = [dict(case) for case in workflow_results]
192  for case in cases:
194 
195  support_tier_summary = build_support_tier_summary(cases)
196  case_identity = build_case_identity_summary(
197  cases, qubit_sizes=qubit_sizes, parameter_set_count=parameter_set_count
198  )
199  total_cases = len(cases)
200  passed_cases = sum(case["status"] == "pass" for case in cases)
201  unsupported_cases = sum(case["status"] == "unsupported" for case in cases)
202  required_pass_rate = support_tier_summary["required_pass_rate"]
203  bridge_supported_cases = sum(
204  case.get("bridge_supported_pass", False) for case in cases
205  )
206  documented_10q_anchor_required = 10 in qubit_sizes
207  documented_10q_anchor_present = any(case["qbit_num"] == 10 for case in cases)
208  all_cases_required = all(case["support_tier"] == "required" for case in cases)
209  all_cases_mandatory = all(
210  case["counts_toward_mandatory_baseline"] for case in cases
211  )
212  workflow_baseline_completed = bool(
213  exact_regime_workflow_bundle["status"] == "pass"
214  and case_identity["stable_case_ids_present"]
215  and case_identity["stable_parameter_set_ids_present"]
216  and all_cases_required
217  and all_cases_mandatory
218  and support_tier_summary["mandatory_baseline_completed"]
219  and unsupported_cases == 0
220  and bridge_supported_cases == total_cases
221  and (
222  not documented_10q_anchor_required or documented_10q_anchor_present
223  )
224  )
225 
226  bundle = {
227  "suite_name": SUITE_NAME,
228  "status": "pass" if workflow_baseline_completed else "fail",
229  "backend": PRIMARY_BACKEND,
230  "reference_backend": REFERENCE_BACKEND,
231  "requirements": build_requirement_metadata(
232  qubit_sizes=qubit_sizes, parameter_set_count=parameter_set_count
233  ),
235  qubit_sizes=qubit_sizes, parameter_set_count=parameter_set_count
236  ),
237  "software": build_software_metadata(),
238  "summary": {
239  "total_cases": total_cases,
240  "passed_cases": passed_cases,
241  "failed_cases": total_cases - passed_cases,
242  "unsupported_cases": unsupported_cases,
243  "unsupported_status_cases": unsupported_cases,
244  "bridge_supported_cases": bridge_supported_cases,
245  "required_cases": support_tier_summary["required_cases"],
246  "required_passed_cases": support_tier_summary["required_passed_cases"],
247  "required_pass_rate": required_pass_rate,
248  "mandatory_baseline_case_count": support_tier_summary[
249  "mandatory_baseline_case_count"
250  ],
251  "mandatory_baseline_passed_cases": support_tier_summary[
252  "mandatory_baseline_passed_cases"
253  ],
254  "mandatory_baseline_completed": support_tier_summary[
255  "mandatory_baseline_completed"
256  ],
257  "optional_cases_count_toward_mandatory_baseline": support_tier_summary[
258  "optional_cases_count_toward_mandatory_baseline"
259  ],
260  "required_workflow_qubits": list(qubit_sizes),
261  "fixed_parameter_sets_per_size": parameter_set_count,
262  "documented_10q_anchor_required": documented_10q_anchor_required,
263  "documented_10q_anchor_present": documented_10q_anchor_present,
264  **case_identity,
265  "all_cases_required": all_cases_required,
266  "all_cases_count_toward_mandatory_baseline": all_cases_mandatory,
267  "workflow_baseline_completed": workflow_baseline_completed,
268  },
269  "required_artifacts": {
270  "exact_regime_workflow_reference": {
271  "suite_name": exact_regime_workflow_bundle["suite_name"],
272  "status": exact_regime_workflow_bundle["status"],
273  "summary": exact_regime_workflow_bundle["summary"],
274  }
275  },
276  "cases": cases,
277  }
279  return bundle
280 
281 
283  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
284  if missing_fields:
285  raise ValueError(
286  "Workflow-baseline bundle is missing required fields: {}".format(
287  ", ".join(missing_fields)
288  )
289  )
290 
291 
292 def write_artifact_bundle(output_path: Path, bundle):
294  output_path.parent.mkdir(parents=True, exist_ok=True)
295  output_path.write_text(
296  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
297  )
298 
299 
300 def run_validation(
301  *,
302  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
303  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
304  verbose=False,
305 ):
306  workflow_results = run_exact_regime_workflow_matrix(
307  qubit_sizes=qubit_sizes, parameter_set_count=parameter_set_count
308  )
309  exact_regime_workflow_bundle = build_exact_regime_workflow_bundle(
310  workflow_results,
311  qubit_sizes=qubit_sizes,
312  parameter_set_count=parameter_set_count,
313  trace_result=None,
314  )
315  bundle = build_artifact_bundle(
316  exact_regime_workflow_bundle,
317  workflow_results,
318  qubit_sizes=qubit_sizes,
319  parameter_set_count=parameter_set_count,
320  )
321  if verbose:
322  print(
323  "{} [{}] required cases={}/{} stable_case_ids={} stable_parameter_sets={}".format(
324  bundle["suite_name"],
325  bundle["status"],
326  bundle["summary"]["required_passed_cases"],
327  bundle["summary"]["required_cases"],
328  bundle["summary"]["stable_case_ids_present"],
329  bundle["summary"]["stable_parameter_set_ids_present"],
330  )
331  )
332  return exact_regime_workflow_bundle, bundle
333 
334 
336  parser = argparse.ArgumentParser(description=__doc__)
337  parser.add_argument(
338  "--output-dir",
339  type=Path,
340  default=DEFAULT_OUTPUT_DIR,
341  help="Directory for the workflow-baseline JSON artifact bundle.",
342  )
343  parser.add_argument(
344  "--parameter-set-count",
345  type=int,
346  default=EXACT_REGIME_PARAMETER_SET_COUNT,
347  help="Number of fixed parameter vectors per qubit size.",
348  )
349  parser.add_argument(
350  "--qubit-sizes",
351  type=int,
352  nargs="*",
353  default=list(EXACT_REGIME_WORKFLOW_QUBITS),
354  help="Workflow qubit sizes to include.",
355  )
356  parser.add_argument(
357  "--quiet",
358  action="store_true",
359  help="Suppress progress output.",
360  )
361  return parser.parse_args()
362 
363 
364 def main():
365  args = parse_args()
366  _, bundle = run_validation(
367  qubit_sizes=tuple(args.qubit_sizes),
368  parameter_set_count=args.parameter_set_count,
369  verbose=not args.quiet,
370  )
371  output_path = args.output_dir / ARTIFACT_FILENAME
372  write_artifact_bundle(output_path, bundle)
373  print(
374  "Wrote {} with status {} ({}/{})".format(
375  output_path,
376  bundle["status"],
377  bundle["summary"]["required_passed_cases"],
378  bundle["summary"]["required_cases"],
379  )
380  )
381  if bundle["status"] != "pass":
382  raise SystemExit(1)
383 
384 
385 if __name__ == "__main__":
386  main()
def build_requirement_metadata(qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS, parameter_set_count=EXACT_REGIME_PARAMETER_SET_COUNT)
def build_support_tier_summary(cases)
def build_software_metadata()