Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
trace_anchor_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Validation: trace-and-anchor package.
3 
4 Builds the phase-level trace-and-anchor gate from:
5 - the already passing workflow baseline, which must contain the documented
6  10-qubit anchor evidence,
7 - and the canonical bounded 4-qubit optimization trace, kept as a stable raw
8  artifact rather than renamed into a second trace identity.
9 
10 The resulting bundle is intentionally a thin validation-evidence layer:
11 - it keeps the workflow baseline and the bounded trace as separate evidence
12  layers,
13 - it requires both the supported trace and the documented 10-qubit anchor,
14 - it preserves trace identity and supported-path attribution explicitly,
15 - and it makes missing trace-or-anchor evidence fail explicitly.
16 
17 Run with:
18  python benchmarks/density_matrix/validation_evidence/trace_anchor_validation.py
19 """
20 
21 from __future__ import annotations
22 
23 import argparse
24 import json
25 import sys
26 from pathlib import Path
27 
28 REPO_ROOT = Path(__file__).resolve().parents[3]
29 if str(REPO_ROOT) not in sys.path:
30  sys.path.insert(0, str(REPO_ROOT))
31 
32 from benchmarks.density_matrix.workflow_evidence.exact_density_vqe_validation import (
33  EXACT_REGIME_PARAMETER_SET_COUNT,
34  EXACT_REGIME_WORKFLOW_QUBITS,
35  capture_case,
36  run_optimization_trace,
37  write_json,
38 )
39 from benchmarks.density_matrix.validation_evidence.workflow_baseline_validation import (
40  PRIMARY_BACKEND,
41  REFERENCE_BACKEND,
42  run_validation as run_workflow_baseline_validation,
43 )
44 
45 SUITE_NAME = "trace_anchor_validation"
46 ARTIFACT_FILENAME = "trace_anchor_bundle.json"
47 TRACE_CASE_NAME = "optimization_trace_4q"
48 TRACE_ARTIFACT_FILENAME = "optimization_trace_4q.json"
49 DEFAULT_OUTPUT_DIR = (
50  REPO_ROOT / "benchmarks" / "density_matrix" / "artifacts" / "validation_evidence"
51 )
52 ARTIFACT_CORE_FIELDS = (
53  "suite_name",
54  "status",
55  "backend",
56  "reference_backend",
57  "requirements",
58  "thresholds",
59  "software",
60  "summary",
61  "required_artifacts",
62  "trace_artifact",
63 )
64 
65 
67  workflow_baseline_bundle,
68  *,
69  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
70  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
71  required_trace_case_name: str = TRACE_CASE_NAME,
72 ):
73  return {
74  "mandatory_workflow_qubits": list(qubit_sizes),
75  "fixed_parameter_sets_per_size": parameter_set_count,
76  "documented_anchor_qubit": 10,
77  "required_trace_case_name": required_trace_case_name,
78  "required_bundle_sources": [
79  "workflow_baseline_validation",
80  "canonical_bounded_optimization_trace",
81  ],
82  "workflow_baseline_status": workflow_baseline_bundle["status"],
83  }
84 
85 
86 def validate_trace_artifact(trace_artifact):
87  required_fields = (
88  "case_name",
89  "status",
90  "workflow_completed",
91  "bridge_supported_pass",
92  "support_tier",
93  "case_purpose",
94  "counts_toward_mandatory_baseline",
95  "required_validation_trace",
96  "optimizer",
97  "parameter_count",
98  "total_trace_runtime_ms",
99  "process_peak_rss_kb",
100  )
101  missing_fields = [field for field in required_fields if field not in trace_artifact]
102  if missing_fields:
103  raise ValueError(
104  "Trace-anchor artifact is missing required fields: {}".format(
105  ", ".join(missing_fields)
106  )
107  )
108 
109 
111  workflow_baseline_bundle,
112  trace_result,
113  *,
114  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
115  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
116 ):
117  trace_artifact = dict(trace_result)
118  validate_trace_artifact(trace_artifact)
119 
120  documented_10q_anchor_case_names = sorted(
121  case["case_name"]
122  for case in workflow_baseline_bundle["cases"]
123  if case["qbit_num"] == 10
124  )
125  workflow_baseline_completed = bool(
126  workflow_baseline_bundle["summary"]["workflow_baseline_completed"]
127  )
128  documented_10q_anchor_present = bool(
129  workflow_baseline_bundle["summary"]["documented_10q_anchor_present"]
130  )
131  required_trace_present = bool(trace_artifact.get("required_validation_trace"))
132  required_trace_completed = bool(
133  trace_artifact["status"] == "completed"
134  and trace_artifact.get("workflow_completed", False)
135  )
136  required_trace_bridge_supported = bool(
137  trace_artifact.get("bridge_supported_pass", False)
138  )
139  trace_and_anchor_gate_completed = bool(
140  workflow_baseline_completed
141  and documented_10q_anchor_present
142  and required_trace_present
143  and required_trace_completed
144  and required_trace_bridge_supported
145  )
146 
147  bundle = {
148  "suite_name": SUITE_NAME,
149  "status": "pass" if trace_and_anchor_gate_completed else "fail",
150  "backend": PRIMARY_BACKEND,
151  "reference_backend": REFERENCE_BACKEND,
152  "requirements": build_requirement_metadata(
153  workflow_baseline_bundle,
154  qubit_sizes=qubit_sizes,
155  parameter_set_count=parameter_set_count,
156  required_trace_case_name=trace_artifact["case_name"],
157  ),
158  "thresholds": dict(workflow_baseline_bundle["thresholds"]),
159  "software": dict(workflow_baseline_bundle["software"]),
160  "summary": {
161  "workflow_baseline_completed": workflow_baseline_completed,
162  "documented_10q_anchor_present": documented_10q_anchor_present,
163  "documented_10q_anchor_case_names": documented_10q_anchor_case_names,
164  "required_trace_case_name": trace_artifact["case_name"],
165  "required_trace_present": required_trace_present,
166  "required_trace_completed": required_trace_completed,
167  "required_trace_bridge_supported": required_trace_bridge_supported,
168  "required_trace_counts_toward_mandatory_baseline": trace_artifact.get(
169  "counts_toward_mandatory_baseline"
170  ),
171  "trace_and_anchor_gate_completed": trace_and_anchor_gate_completed,
172  },
173  "required_artifacts": {
174  "workflow_baseline_reference": {
175  "suite_name": workflow_baseline_bundle["suite_name"],
176  "status": workflow_baseline_bundle["status"],
177  "summary": workflow_baseline_bundle["summary"],
178  }
179  },
180  "trace_artifact": trace_artifact,
181  }
183  return bundle
184 
185 
187  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in bundle]
188  if missing_fields:
189  raise ValueError(
190  "Trace-anchor bundle is missing required fields: {}".format(
191  ", ".join(missing_fields)
192  )
193  )
194 
195 
196 def write_artifact_bundle(output_path: Path, bundle):
198  output_path.parent.mkdir(parents=True, exist_ok=True)
199  output_path.write_text(
200  json.dumps(bundle, indent=2, sort_keys=True) + "\n", encoding="utf-8"
201  )
202 
203 
204 def run_validation(
205  *,
206  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
207  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
208  verbose=False,
209 ):
210  _, workflow_baseline_bundle = run_workflow_baseline_validation(
211  qubit_sizes=qubit_sizes,
212  parameter_set_count=parameter_set_count,
213  verbose=verbose,
214  )
215  trace_result = capture_case(TRACE_CASE_NAME, run_optimization_trace)
216  bundle = build_artifact_bundle(
217  workflow_baseline_bundle,
218  trace_result,
219  qubit_sizes=qubit_sizes,
220  parameter_set_count=parameter_set_count,
221  )
222  if verbose:
223  print(
224  "{} [{}] 10q_anchor={} trace={}".format(
225  bundle["suite_name"],
226  bundle["status"],
227  bundle["summary"]["documented_10q_anchor_present"],
228  bundle["summary"]["required_trace_completed"],
229  )
230  )
231  return workflow_baseline_bundle, trace_result, bundle
232 
233 
235  parser = argparse.ArgumentParser(description=__doc__)
236  parser.add_argument(
237  "--output-dir",
238  type=Path,
239  default=DEFAULT_OUTPUT_DIR,
240  help="Directory for the trace-and-anchor JSON artifacts.",
241  )
242  parser.add_argument(
243  "--parameter-set-count",
244  type=int,
245  default=EXACT_REGIME_PARAMETER_SET_COUNT,
246  help="Number of fixed parameter vectors per qubit size.",
247  )
248  parser.add_argument(
249  "--qubit-sizes",
250  type=int,
251  nargs="*",
252  default=list(EXACT_REGIME_WORKFLOW_QUBITS),
253  help="Workflow qubit sizes to include.",
254  )
255  parser.add_argument(
256  "--quiet",
257  action="store_true",
258  help="Suppress progress output.",
259  )
260  return parser.parse_args()
261 
262 
263 def main():
264  args = parse_args()
265  _, trace_result, bundle = run_validation(
266  qubit_sizes=tuple(args.qubit_sizes),
267  parameter_set_count=args.parameter_set_count,
268  verbose=not args.quiet,
269  )
270  args.output_dir.mkdir(parents=True, exist_ok=True)
271  write_artifact_bundle(args.output_dir / ARTIFACT_FILENAME, bundle)
272  write_json(args.output_dir / TRACE_ARTIFACT_FILENAME, trace_result)
273  print(
274  "Wrote {} and {} with status {}".format(
275  args.output_dir / ARTIFACT_FILENAME,
276  args.output_dir / TRACE_ARTIFACT_FILENAME,
277  bundle["status"],
278  )
279  )
280  if bundle["status"] != "pass":
281  raise SystemExit(1)
282 
283 
284 if __name__ == "__main__":
285  main()
def validate_trace_artifact(trace_artifact)