Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
exact_density_vqe_validation.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """Exact-density VQE validation for canonical anchor cases.
3 
4 Runs the foundational exact density-matrix evidence used by the higher-level
5 Phase 2 bundles:
6 - fixed-parameter 4-qubit and 6-qubit XXZ anchor comparisons against Qiskit Aer,
7 - one bounded 4-qubit density-backed optimization trace,
8 - an exact-regime workflow matrix,
9 - and a compact validation bundle tying those artifacts together.
10 
11 Unsupported cases are emitted as structured negative evidence instead of
12 crashing or silently disappearing.
13 """
14 
15 from __future__ import annotations
16 
17 import argparse
18 import json
19 import resource
20 import subprocess
21 import sys
22 import time
23 from pathlib import Path
24 
25 import numpy as np
26 import qiskit
27 import qiskit_aer
28 from qiskit import QuantumCircuit
29 from qiskit_aer import AerSimulator
30 from qiskit_aer.noise import (
31  amplitude_damping_error,
32  depolarizing_error,
33  phase_damping_error,
34 )
35 from qiskit.quantum_info import DensityMatrix as QiskitDensityMatrix
36 from qiskit.quantum_info import state_fidelity
37 
38 REPO_ROOT = Path(__file__).resolve().parents[3]
39 if str(REPO_ROOT) not in sys.path:
40  sys.path.insert(0, str(REPO_ROOT))
41 
42 from examples.VQE.shot_noise_measurement import generate_zz_xx_hamiltonian
43 from benchmarks.density_matrix.validate_squander_vs_qiskit import (
44  ARTIFACT_FILENAME as MICRO_VALIDATION_BUNDLE_FILENAME,
45  build_artifact_bundle as build_micro_validation_bundle,
46  run_validation as run_micro_validation,
47  write_artifact_bundle as write_micro_validation_bundle_file,
48 )
49 from benchmarks.density_matrix.noise_support.support_tiers import (
50  build_required_case_classification,
51  build_support_tier_summary,
52  classify_noise_boundary_reason,
53 )
54 from squander import Variational_Quantum_Eigensolver
55 from squander.density_matrix import DensityMatrix, NoisyCircuit
56 from squander.partitioning.noisy_planner import (
57  PLANNER_OP_KIND_GATE,
58  PLANNER_OP_KIND_NOISE,
59 )
60 
61 PRIMARY_BACKEND = "density_matrix"
62 REFERENCE_BACKEND = "qiskit_aer_density_matrix"
63 DEFAULT_ANSATZ = "HEA"
64 DEFAULT_LAYERS = 1
65 DEFAULT_INNER_BLOCKS = 1
66 FIXED_PARAMETER_QUBITS = (4, 6)
67 EXACT_REGIME_WORKFLOW_QUBITS = (4, 6, 8, 10)
68 EXACT_REGIME_PARAMETER_SET_COUNT = 10
69 EXACT_REGIME_WORKFLOW_ERROR_TOL = 1e-8
70 EXACT_REGIME_VALIDITY_TOL = 1e-10
71 EXACT_REGIME_TRACE_TOL = 1e-10
72 EXACT_REGIME_OBSERVABLE_IMAG_TOL = 1e-10
73 EXACT_REGIME_WORKFLOW_BUNDLE_FILENAME = "exact_regime_workflow_bundle.json"
74 OPTIMIZATION_TRACE_ARTIFACT_FILENAME = "optimization_trace_4q.json"
75 EXACT_REGIME_WORKFLOW_BUNDLE_FIELDS = (
76  "suite_name",
77  "status",
78  "backend",
79  "reference_backend",
80  "thresholds",
81  "software",
82  "summary",
83  "cases",
84 )
85 EXACT_DENSITY_VALIDATION_BUNDLE_FILENAME = "exact_density_validation_bundle.json"
86 EXACT_DENSITY_VALIDATION_BUNDLE_FIELDS = (
87  "suite_name",
88  "status",
89  "backend",
90  "reference_backend",
91  "software",
92  "provenance",
93  "summary",
94  "artifacts",
95 )
96 SUPPORTED_BACKEND_LABELS = {PRIMARY_BACKEND, "state_vector"}
97 REQUIRED_BRIDGE_GATE_NAMES = {"U3", "CNOT"}
98 REQUIRED_BRIDGE_NOISE_NAMES = {
99  "local_depolarizing",
100  "amplitude_damping",
101  "phase_damping",
102 }
103 ARTIFACT_CORE_FIELDS = (
104  "case_name",
105  "status",
106  "backend",
107  "qbit_num",
108  "topology",
109  "ansatz",
110  "layers",
111  "inner_blocks",
112  "density_noise",
113 )
114 
115 
117  return [
118  {
119  "channel": "local_depolarizing",
120  "target": 0,
121  "after_gate_index": 0,
122  "error_rate": 0.1,
123  },
124  {
125  "channel": "amplitude_damping",
126  "target": 1,
127  "after_gate_index": 2,
128  "gamma": 0.05,
129  },
130  {
131  "channel": "phase_damping",
132  "target": 0,
133  "after_gate_index": 4,
134  "lambda": 0.07,
135  },
136  ]
137 
138 
139 def build_open_chain_topology(qbit_num: int):
140  return [(idx, idx + 1) for idx in range(qbit_num - 1)]
141 
142 
144  return {
145  "max_inner_iterations": 4,
146  "max_iterations": 1,
147  "convergence_length": 2,
148  }
149 
150 
151 def build_initial_parameters(param_num: int) -> np.ndarray:
152  return np.linspace(0.05, 0.05 * param_num, param_num, dtype=np.float64)
153 
154 
156  return {
157  "Jx": 1.0,
158  "Jy": 1.0,
159  "Jz": 1.0,
160  "h": 0.5,
161  }
162 
163 
165  return {
166  "python": sys.version.split()[0],
167  "numpy": np.__version__,
168  "qiskit": getattr(qiskit, "__version__", "unknown"),
169  "qiskit_aer": getattr(qiskit_aer, "__version__", "unknown"),
170  }
171 
172 
174  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
175  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
176 ):
177  return {
178  "absolute_energy_error": EXACT_REGIME_WORKFLOW_ERROR_TOL,
179  "rho_is_valid_tol": EXACT_REGIME_VALIDITY_TOL,
180  "trace_deviation": EXACT_REGIME_TRACE_TOL,
181  "observable_imag_abs": EXACT_REGIME_OBSERVABLE_IMAG_TOL,
182  "required_pass_rate": 1.0,
183  "required_workflow_qubits": list(qubit_sizes),
184  "fixed_parameter_sets_per_size": parameter_set_count,
185  }
186 
187 
189  param_num: int, count: int = EXACT_REGIME_PARAMETER_SET_COUNT
190 ):
191  base = np.linspace(0.05, 0.05 * param_num, param_num, dtype=np.float64)
192  parameter_sets = []
193  for idx in range(count):
194  shift = 0.07 * idx
195  scale = 1.0 + 0.025 * idx
196  params = np.mod(scale * base + shift, 2.0 * np.pi)
197  parameter_sets.append(
198  {
199  "parameter_set_id": f"set_{idx:02d}",
200  "parameter_vector": params,
201  }
202  )
203  return parameter_sets
204 
205 
207  try:
208  result = subprocess.run(
209  ["git", "rev-parse", "HEAD"],
210  cwd=REPO_ROOT,
211  capture_output=True,
212  text=True,
213  check=True,
214  )
215  return result.stdout.strip()
216  except Exception:
217  return "unknown"
218 
219 
221  *,
222  backend: str,
223  qbit_num: int,
224  topology,
225  density_noise,
226  ansatz: str = DEFAULT_ANSATZ,
227  layers: int = DEFAULT_LAYERS,
228  inner_blocks: int = DEFAULT_INNER_BLOCKS,
229  reference_backend: str | None = None,
230  hamiltonian: dict | None = None,
231  optimizer: str | None = None,
232 ):
233  metadata = {
234  "backend": backend,
235  "qbit_num": qbit_num,
236  "topology": topology,
237  "ansatz": ansatz,
238  "layers": layers,
239  "inner_blocks": inner_blocks,
240  "density_noise": density_noise,
241  }
242  if reference_backend is not None:
243  metadata["reference_backend"] = reference_backend
244  if hamiltonian is not None:
245  metadata["hamiltonian"] = hamiltonian
246  if optimizer is not None:
247  metadata["optimizer"] = optimizer
248  return metadata
249 
250 
252  missing_fields = [field for field in ARTIFACT_CORE_FIELDS if field not in payload]
253  if missing_fields:
254  raise ValueError(
255  "Artifact payload is missing required fields: {}".format(
256  ", ".join(missing_fields)
257  )
258  )
259 
260  if payload["backend"] not in SUPPORTED_BACKEND_LABELS:
261  raise ValueError(
262  "Artifact payload has unsupported backend label '{}'".format(
263  payload["backend"]
264  )
265  )
266 
267  if payload["status"] not in {"completed", "unsupported"}:
268  raise ValueError(
269  "Artifact payload has unsupported status '{}'".format(payload["status"])
270  )
271 
272 
273 def build_vqe(
274  qbit_num: int,
275  optimizer: str | None = None,
276  density_noise=None,
277 ):
278  topology = build_open_chain_topology(qbit_num)
279  hamiltonian, _ = generate_zz_xx_hamiltonian(
280  n_qubits=qbit_num,
281  h=0.5,
282  topology=topology,
283  Jz=1.0,
284  Jx=1.0,
285  Jy=1.0,
286  )
287  requested_density_noise = (
288  build_reference_noise() if density_noise is None else [dict(item) for item in density_noise]
289  )
290  vqe = Variational_Quantum_Eigensolver(
291  hamiltonian,
292  qbit_num,
294  backend=PRIMARY_BACKEND,
295  density_noise=requested_density_noise,
296  )
297  if optimizer is not None:
298  vqe.set_Optimizer(optimizer)
299  vqe.set_Ansatz(DEFAULT_ANSATZ)
300  vqe.Generate_Circuit(layers=DEFAULT_LAYERS, inner_blocks=DEFAULT_INNER_BLOCKS)
301  return vqe, hamiltonian, topology
302 
303 
305  bridge = vqe.describe_density_bridge()
306  noise_operations = [
307  op for op in bridge["operations"] if op["kind"] == PLANNER_OP_KIND_NOISE
308  ]
309  return {
310  "bridge_source_type": bridge["source_type"],
311  "bridge_parameter_count": bridge["parameter_count"],
312  "bridge_operation_count": bridge["operation_count"],
313  "bridge_gate_count": bridge["gate_count"],
314  "bridge_noise_count": bridge["noise_count"],
315  "bridge_operations": bridge["operations"],
316  "bridge_noise_sequence": [op["name"] for op in noise_operations],
317  "bridge_noise_targets": [op["target_qbit"] for op in noise_operations],
318  "bridge_noise_after_gate_indices": [
319  op["source_gate_index"] for op in noise_operations
320  ],
321  "bridge_noise_fixed_values": [op["fixed_value"] for op in noise_operations],
322  }
323 
324 
326  if "unsupported circuit source" in reason or "requires a generated HEA circuit" in reason:
327  category = "circuit_source"
328  if "custom_gate_structure" in reason:
329  first_condition = "custom_gate_structure"
330  bridge_source_type = "custom_gate_structure"
331  elif "binary_import" in reason:
332  first_condition = "binary_import"
333  bridge_source_type = "binary_import"
334  elif "generated HEA circuit" in reason:
335  first_condition = "generated_hea_required"
336  bridge_source_type = "unset"
337  else:
338  first_condition = "circuit_source"
339  bridge_source_type = "unset"
340  elif (
341  "only the HEA ansatz" in reason
342  or "first unsupported gate in density backend path" in reason
343  or "unsupported gate in density backend path" in reason
344  ):
345  category = "lowering_path"
346  if "only the HEA ansatz" in reason:
347  first_condition = "generated_hea_zyz"
348  bridge_source_type = "generated_hea_zyz"
349  elif "first unsupported gate in density backend path is " in reason:
350  first_condition = reason.split(
351  "first unsupported gate in density backend path is ", 1
352  )[1]
353  bridge_source_type = "generated_hea"
354  elif "unsupported gate in density backend path: " in reason:
355  first_condition = reason.split(
356  "unsupported gate in density backend path: ", 1
357  )[1]
358  bridge_source_type = "generated_hea"
359  else:
360  first_condition = "lowering_path"
361  bridge_source_type = "generated_hea"
362  elif "unsupported density-noise insertion" in reason or "after_gate_index" in reason:
363  category = "noise_insertion"
364  first_condition = "after_gate_index"
365  bridge_source_type = "generated_hea"
366  elif "Unsupported density-noise channel" in reason or "unsupported density-noise type" in reason:
367  category = "noise_type"
368  first_condition = "unsupported_density_noise_channel"
369  bridge_source_type = "unset"
370  else:
371  category = "workflow_execution"
372  first_condition = "workflow_execution"
373  bridge_source_type = "unknown"
374 
375  return {
376  "unsupported_category": category,
377  "first_unsupported_condition": first_condition,
378  "bridge_source_type": bridge_source_type,
379  "error_match_pass": category != "workflow_execution",
380  }
381 
382 
383 def build_exact_regime_bridge_metadata(vqe, *, execution_ready: bool):
384  bridge = vqe.describe_density_bridge()
385  gate_sequence = [
386  op["name"] for op in bridge["operations"] if op["kind"] == PLANNER_OP_KIND_GATE
387  ]
388  noise_sequence = [
389  op["name"] for op in bridge["operations"] if op["kind"] == PLANNER_OP_KIND_NOISE
390  ]
391 
392  source_pass = bridge["source_type"] == "generated_hea"
393  gate_pass = (
394  bool(gate_sequence)
395  and set(gate_sequence).issubset(REQUIRED_BRIDGE_GATE_NAMES)
396  and "U3" in gate_sequence
397  and (vqe.get_Qbit_Num() == 1 or "CNOT" in gate_sequence)
398  )
399  noise_pass = REQUIRED_BRIDGE_NOISE_NAMES.issubset(set(noise_sequence))
400  execution_ready = bool(execution_ready)
401 
402  return {
403  "bridge_source_type": bridge["source_type"],
404  "bridge_parameter_count": bridge["parameter_count"],
405  "bridge_operation_count": bridge["operation_count"],
406  "bridge_gate_count": bridge["gate_count"],
407  "bridge_noise_count": bridge["noise_count"],
408  "bridge_gate_sequence": gate_sequence,
409  "bridge_noise_sequence": noise_sequence,
410  "source_pass": source_pass,
411  "gate_pass": gate_pass,
412  "noise_pass": noise_pass,
413  "execution_ready": execution_ready,
414  "bridge_supported_pass": source_pass
415  and gate_pass
416  and noise_pass
417  and execution_ready,
418  }
419 
420 
422  topology = build_open_chain_topology(qbit_num)
423  hamiltonian, _ = generate_zz_xx_hamiltonian(
424  n_qubits=qbit_num,
425  h=0.5,
426  topology=topology,
427  Jz=1.0,
428  Jx=1.0,
429  Jy=1.0,
430  )
431  vqe = Variational_Quantum_Eigensolver(
432  hamiltonian,
433  qbit_num,
435  backend="state_vector",
436  density_noise=build_reference_noise(),
437  )
438  vqe.set_Ansatz(DEFAULT_ANSATZ)
439  vqe.Generate_Circuit(layers=DEFAULT_LAYERS, inner_blocks=DEFAULT_INNER_BLOCKS)
440  return vqe, hamiltonian, topology
441 
442 
443 def insert_reference_noise(base_circuit: QuantumCircuit, density_noise):
444  noisy_circuit = QuantumCircuit(base_circuit.num_qubits)
445  noise_by_gate = {}
446  for noise_spec in density_noise:
447  noise_by_gate.setdefault(noise_spec["after_gate_index"], []).append(noise_spec)
448 
449  for gate_index, instruction in enumerate(base_circuit.data):
450  qargs = [
451  noisy_circuit.qubits[base_circuit.find_bit(qubit).index]
452  for qubit in instruction.qubits
453  ]
454  cargs = [
455  noisy_circuit.clbits[base_circuit.find_bit(clbit).index]
456  for clbit in instruction.clbits
457  ]
458  noisy_circuit.append(instruction.operation, qargs, cargs)
459 
460  for noise_spec in noise_by_gate.get(gate_index, []):
461  target = noise_spec["target"]
462  channel = noise_spec["channel"]
463  if channel == "local_depolarizing":
464  noisy_circuit.append(
465  depolarizing_error(noise_spec["error_rate"], 1),
466  [noisy_circuit.qubits[target]],
467  )
468  elif channel == "amplitude_damping":
469  noisy_circuit.append(
470  amplitude_damping_error(noise_spec["gamma"]),
471  [noisy_circuit.qubits[target]],
472  )
473  elif channel == "phase_damping":
474  noisy_circuit.append(
475  phase_damping_error(noise_spec["lambda"]),
476  [noisy_circuit.qubits[target]],
477  )
478  else:
479  raise ValueError(f"Unsupported fixed-parameter channel: {channel}")
480 
481  noisy_circuit.save_density_matrix()
482  return noisy_circuit
483 
484 
485 def density_energy(hamiltonian, density_matrix):
486  energy = np.trace(hamiltonian.dot(density_matrix))
487  return float(np.real(energy)), float(np.imag(energy))
488 
489 
490 def trace_distance(rho1: np.ndarray, rho2: np.ndarray) -> float:
491  diff = rho1 - rho2
492  eigenvalues = np.linalg.eigvalsh(diff @ diff.conj().T)
493  return float(0.5 * np.sum(np.sqrt(np.maximum(eigenvalues, 0))))
494 
495 
496 def build_squander_density_from_qiskit_circuit(base_circuit, density_noise):
497  circuit = NoisyCircuit(base_circuit.num_qubits)
498  params = []
499  noise_by_gate = {}
500  for noise_spec in density_noise:
501  noise_by_gate.setdefault(noise_spec["after_gate_index"], []).append(noise_spec)
502 
503  for gate_index, instruction in enumerate(base_circuit.data):
504  qubit_indices = [
505  base_circuit.find_bit(qubit).index for qubit in instruction.qubits
506  ]
507  gate_name = instruction.operation.name
508 
509  if gate_name == "u":
510  theta, phi, lam = [float(value) for value in instruction.operation.params]
511  # Exported Qiskit circuits use the physical U3 theta, while the
512  # SQUANDER parametric path stores theta/2 internally.
513  circuit.add_U3(qubit_indices[0])
514  params.extend([theta / 2.0, phi, lam])
515  elif gate_name in {"cx", "cnot"}:
516  circuit.add_CNOT(qubit_indices[1], qubit_indices[0])
517  else:
518  raise ValueError(
519  f"Unsupported workflow gate in reconstruction: {gate_name}"
520  )
521 
522  for noise_spec in noise_by_gate.get(gate_index, []):
523  target = noise_spec["target"]
524  channel = noise_spec["channel"]
525  if channel == "local_depolarizing":
526  circuit.add_local_depolarizing(
527  target, error_rate=noise_spec["error_rate"]
528  )
529  elif channel == "amplitude_damping":
530  circuit.add_amplitude_damping(target, gamma=noise_spec["gamma"])
531  elif channel == "phase_damping":
532  circuit.add_phase_damping(target, lambda_param=noise_spec["lambda"])
533  else:
534  raise ValueError(
535  f"Unsupported workflow noise channel in reconstruction: {channel}"
536  )
537 
538  rho = DensityMatrix(base_circuit.num_qubits)
539  circuit.apply_to(np.asarray(params, dtype=np.float64), rho)
540  return rho
541 
542 
544  qbit_num: int,
545  parameter_set_id: str,
546  parameter_vector: np.ndarray,
547 ):
548  density_noise = build_reference_noise()
549  vqe, hamiltonian, topology = build_vqe(qbit_num)
550  vqe.set_Optimized_Parameters(parameter_vector)
551  bridge_metadata = build_exact_regime_bridge_metadata(vqe, execution_ready=True)
552 
553  case_start = time.perf_counter()
554  squander_start = time.perf_counter()
555  squander_energy = float(vqe.Optimization_Problem(parameter_vector))
556  squander_runtime_ms = (time.perf_counter() - squander_start) * 1000.0
557 
558  base_qiskit_circuit = vqe.get_Qiskit_Circuit()
560  base_qiskit_circuit, density_noise
561  )
562  squander_rho_np = np.asarray(squander_rho.to_numpy())
563  squ_trace = squander_rho.trace()
564  squ_trace_deviation = float(abs(squ_trace - 1.0))
565  squ_density_valid = bool(squander_rho.is_valid(tol=EXACT_REGIME_VALIDITY_TOL))
566  squ_purity = float(np.real(np.trace(squander_rho_np @ squander_rho_np)))
567  squ_energy_real_from_rho, squ_energy_imag = density_energy(
568  hamiltonian, squander_rho_np
569  )
570 
571  reference_start = time.perf_counter()
572  noisy_qiskit_circuit = insert_reference_noise(base_qiskit_circuit, density_noise)
573  simulator = AerSimulator(method="density_matrix")
574  result = simulator.run(noisy_qiskit_circuit, shots=1).result()
575  aer_rho = np.asarray(result.data()["density_matrix"])
576  reference_runtime_ms = (time.perf_counter() - reference_start) * 1000.0
577 
578  aer_energy_real, aer_energy_imag = density_energy(hamiltonian, aer_rho)
579  aer_trace = np.trace(aer_rho)
580  aer_purity = float(np.real(np.trace(aer_rho @ aer_rho)))
581  fidelity = float(
582  state_fidelity(
583  QiskitDensityMatrix(squander_rho_np), QiskitDensityMatrix(aer_rho)
584  )
585  )
586  density_max_diff = float(np.max(np.abs(squander_rho_np - aer_rho)))
587  density_trace_distance = trace_distance(squander_rho_np, aer_rho)
588 
589  energy_error = float(abs(squander_energy - aer_energy_real))
590  energy_pass = energy_error <= EXACT_REGIME_WORKFLOW_ERROR_TOL
591  density_valid_pass = squ_density_valid
592  trace_pass = squ_trace_deviation <= EXACT_REGIME_TRACE_TOL
593  observable_pass = abs(squ_energy_imag) <= EXACT_REGIME_OBSERVABLE_IMAG_TOL
594  workflow_completed = True
595  status = (
596  "pass"
597  if workflow_completed
598  and energy_pass
599  and density_valid_pass
600  and trace_pass
601  and observable_pass
602  and bridge_metadata["bridge_supported_pass"]
603  else "fail"
604  )
605 
606  artifact = build_case_metadata(
607  backend=PRIMARY_BACKEND,
608  qbit_num=qbit_num,
609  topology=topology,
610  density_noise=density_noise,
611  reference_backend=REFERENCE_BACKEND,
612  hamiltonian=build_hamiltonian_metadata(),
613  )
614  artifact.update(
615  {
616  "case_name": f"exact_regime_{qbit_num}q_{parameter_set_id}",
617  "status": status,
618  "workflow_completed": workflow_completed,
619  "parameter_set_id": parameter_set_id,
620  "parameter_vector": parameter_vector.tolist(),
621  "squander_energy": squander_energy,
622  "squander_energy_from_rho_real": squ_energy_real_from_rho,
623  "squander_energy_imag": squ_energy_imag,
624  "aer_energy_real": aer_energy_real,
625  "aer_energy_imag": aer_energy_imag,
626  "absolute_energy_error": energy_error,
627  "energy_pass": energy_pass,
628  "rho_is_valid": squ_density_valid,
629  "rho_is_valid_tol": EXACT_REGIME_VALIDITY_TOL,
630  "density_valid_pass": density_valid_pass,
631  "squander_trace_real": float(np.real(squ_trace)),
632  "squander_trace_imag": float(np.imag(squ_trace)),
633  "trace_deviation": squ_trace_deviation,
634  "trace_pass": trace_pass,
635  "observable_pass": observable_pass,
636  "squander_purity": squ_purity,
637  "aer_trace_real": float(np.real(aer_trace)),
638  "aer_trace_imag": float(np.imag(aer_trace)),
639  "aer_purity": aer_purity,
640  "state_fidelity": fidelity,
641  "density_max_diff": density_max_diff,
642  "density_trace_distance": density_trace_distance,
643  "squander_runtime_ms": squander_runtime_ms,
644  "reference_runtime_ms": reference_runtime_ms,
645  "total_case_runtime_ms": (time.perf_counter() - case_start) * 1000.0,
646  "process_peak_rss_kb": int(
647  resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
648  ),
649  **bridge_metadata,
651  }
652  )
653  return artifact
654 
655 
656 def capture_exact_regime_workflow_case(qbit_num: int, parameter_set: dict):
657  parameter_set_id = parameter_set["parameter_set_id"]
658  parameter_vector = np.asarray(parameter_set["parameter_vector"], dtype=np.float64)
659  try:
660  return run_exact_regime_workflow_case(qbit_num, parameter_set_id, parameter_vector)
661  except Exception as exc:
662  unsupported_reason = str(exc)
663  unsupported_metadata = classify_bridge_unsupported_reason(unsupported_reason)
664  noise_boundary_metadata = classify_noise_boundary_reason(
665  unsupported_reason
666  )
667  if noise_boundary_metadata["unsupported_category"] != "workflow_execution":
668  unsupported_metadata["unsupported_category"] = noise_boundary_metadata[
669  "unsupported_category"
670  ]
671  unsupported_metadata["first_unsupported_condition"] = (
672  noise_boundary_metadata["first_unsupported_condition"]
673  )
674  unsupported_metadata["noise_boundary_class"] = noise_boundary_metadata[
675  "noise_boundary_class"
676  ]
677  unsupported_metadata["failure_stage"] = noise_boundary_metadata[
678  "failure_stage"
679  ]
680  return {
681  "case_name": f"exact_regime_{qbit_num}q_{parameter_set_id}",
682  "status": "unsupported",
683  "backend": PRIMARY_BACKEND,
684  "reference_backend": REFERENCE_BACKEND,
685  "qbit_num": qbit_num,
686  "workflow_completed": False,
687  "parameter_set_id": parameter_set_id,
688  "parameter_vector": parameter_vector.tolist(),
689  **unsupported_metadata,
690  "unsupported_reason": unsupported_reason,
691  "source_pass": False,
692  "gate_pass": False,
693  "noise_pass": False,
694  "execution_ready": False,
695  "bridge_supported_pass": False,
696  "energy_pass": False,
697  "density_valid_pass": False,
698  "trace_pass": False,
699  "observable_pass": False,
701  }
702 
703 
705  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
706  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
707 ):
708  results = []
709  for qbit_num in qubit_sizes:
710  preview_vqe, _, _ = build_vqe(qbit_num)
711  parameter_sets = build_exact_regime_parameter_sets(
712  preview_vqe.get_Parameter_Num(), count=parameter_set_count
713  )
714  for parameter_set in parameter_sets:
715  results.append(capture_exact_regime_workflow_case(qbit_num, parameter_set))
716  return results
717 
718 
720  results,
721  qubit_sizes=EXACT_REGIME_WORKFLOW_QUBITS,
722  parameter_set_count: int = EXACT_REGIME_PARAMETER_SET_COUNT,
723  trace_result=None,
724 ):
725  support_tier_summary = build_support_tier_summary(results)
726  cases_per_qbit = {
727  str(qbit_num): sum(1 for result in results if result["qbit_num"] == qbit_num)
728  for qbit_num in qubit_sizes
729  }
730  passed = sum(1 for result in results if result["status"] == "pass")
731  unsupported = sum(1 for result in results if result["status"] == "unsupported")
732  total = len(results)
733  required_pass_rate = support_tier_summary["required_pass_rate"]
734  documented_10q_anchor_present = any(result["qbit_num"] == 10 for result in results)
735  documented_10q_anchor_required = 10 in qubit_sizes
736  required_counts_present = all(
737  cases_per_qbit[str(qbit_num)] >= parameter_set_count for qbit_num in qubit_sizes
738  )
739  supported_trace_completed = bool(
740  trace_result
741  and trace_result.get("workflow_completed", False)
742  and trace_result.get("bridge_supported_pass", False)
743  )
744  bridge_supported_cases = sum(
745  1 for result in results if result.get("bridge_supported_pass", False)
746  )
747  bundle_status = (
748  "pass"
749  if support_tier_summary["mandatory_baseline_completed"]
750  and required_counts_present
751  and (
752  not documented_10q_anchor_required or documented_10q_anchor_present
753  )
754  and (trace_result is None or supported_trace_completed)
755  else "fail"
756  )
757 
758  bundle = {
759  "suite_name": "exact_regime_workflow",
760  "status": bundle_status,
761  "backend": PRIMARY_BACKEND,
762  "reference_backend": REFERENCE_BACKEND,
764  qubit_sizes=qubit_sizes,
765  parameter_set_count=parameter_set_count,
766  ),
767  "software": build_software_metadata(),
768  "summary": {
769  "total_cases": total,
770  "passed_cases": passed,
771  "failed_cases": total - passed,
772  "unsupported_cases": unsupported,
773  "unsupported_status_cases": unsupported,
774  "bridge_supported_cases": bridge_supported_cases,
775  "pass_rate": required_pass_rate,
776  "required_workflow_qubits": list(qubit_sizes),
777  "fixed_parameter_sets_per_size": parameter_set_count,
778  "cases_per_qbit": cases_per_qbit,
779  "documented_10q_anchor_present": documented_10q_anchor_present,
780  "documented_10q_anchor_required": documented_10q_anchor_required,
781  "supported_trace_completed": supported_trace_completed,
782  "supported_trace_case_name": (
783  trace_result.get("case_name", "optimization_trace_4q")
784  if trace_result
785  else None
786  ),
787  "required_cases": support_tier_summary["required_cases"],
788  "required_passed_cases": support_tier_summary["required_passed_cases"],
789  "required_pass_rate": required_pass_rate,
790  "mandatory_baseline_case_count": support_tier_summary[
791  "mandatory_baseline_case_count"
792  ],
793  "mandatory_baseline_passed_cases": support_tier_summary[
794  "mandatory_baseline_passed_cases"
795  ],
796  "mandatory_baseline_completed": support_tier_summary[
797  "mandatory_baseline_completed"
798  ],
799  "support_tiers_present": support_tier_summary["support_tiers_present"],
800  "optional_cases_count_toward_mandatory_baseline": support_tier_summary[
801  "optional_cases_count_toward_mandatory_baseline"
802  ],
803  },
804  "cases": results,
805  }
807  return bundle
808 
809 
811  missing_fields = [
812  field for field in EXACT_REGIME_WORKFLOW_BUNDLE_FIELDS if field not in bundle
813  ]
814  if missing_fields:
815  raise ValueError(
816  "Exact-regime workflow bundle is missing required fields: {}".format(
817  ", ".join(missing_fields)
818  )
819  )
820 
821  required_qubits = bundle["thresholds"]["required_workflow_qubits"]
822  required_count = bundle["thresholds"]["fixed_parameter_sets_per_size"]
823  cases_per_qbit = bundle["summary"]["cases_per_qbit"]
824  for qbit_num in required_qubits:
825  if cases_per_qbit.get(str(qbit_num), 0) < required_count:
826  raise ValueError(
827  f"Exact-regime workflow bundle is missing required cases for {qbit_num} qubits"
828  )
829 
830 
831 def write_exact_regime_workflow_bundle(output_path: Path, bundle):
833  output_path.parent.mkdir(parents=True, exist_ok=True)
834  output_path.write_text(json.dumps(bundle, indent=2) + "\n", encoding="utf-8")
835 
836 
838  print("\n" + "=" * 78)
839  print(
840  " Exact-Regime Workflow Bundle [{} vs {}]".format(
841  bundle["backend"], bundle["reference_backend"]
842  )
843  )
844  print("=" * 78)
845  for qbit_num in bundle["summary"]["required_workflow_qubits"]:
846  count = bundle["summary"]["cases_per_qbit"][str(qbit_num)]
847  print(f" {qbit_num} qubits: {count} mandatory fixed-parameter cases recorded")
848  print(
849  " Pass rate: {}/{} ({:.0%})".format(
850  bundle["summary"]["passed_cases"],
851  bundle["summary"]["total_cases"],
852  bundle["summary"]["pass_rate"],
853  )
854  )
855  print(
856  " Documented 10-qubit anchor present:",
857  bundle["summary"]["documented_10q_anchor_present"],
858  )
859 
860 
862  *,
863  artifact_id,
864  artifact_class,
865  mandatory,
866  path,
867  status,
868  expected_statuses,
869  purpose,
870  generation_command,
871  summary=None,
872 ):
873  return {
874  "artifact_id": artifact_id,
875  "artifact_class": artifact_class,
876  "mandatory": mandatory,
877  "path": path,
878  "status": status,
879  "expected_statuses": list(expected_statuses),
880  "purpose": purpose,
881  "generation_command": generation_command,
882  "summary": {} if summary is None else dict(summary),
883  }
884 
885 
887  output_dir: Path,
888  *,
889  fixed_results,
890  trace_result,
891  unsupported_result,
892  micro_bundle,
893  workflow_bundle,
894 ):
895  output_dir = Path(output_dir)
896  base_validation_command = (
897  f"python benchmarks/density_matrix/workflow_evidence/exact_density_vqe_validation.py "
898  f"--output-dir {output_dir}"
899  )
900  workflow_command = (
901  f"python benchmarks/density_matrix/workflow_evidence/exact_density_vqe_validation.py "
902  f"--workflow-bundle --output-dir {output_dir}"
903  )
904  micro_validation_command = (
905  f"python benchmarks/density_matrix/validate_squander_vs_qiskit.py "
906  f"--output-dir {output_dir}"
907  )
908  validation_bundle_command = (
909  f"python benchmarks/density_matrix/workflow_evidence/exact_density_vqe_validation.py "
910  f"--publication-bundle --output-dir {output_dir}"
911  )
912 
913  artifacts = [
915  artifact_id="micro_validation_bundle",
916  artifact_class="micro_validation_bundle",
917  mandatory=True,
918  path=MICRO_VALIDATION_BUNDLE_FILENAME,
919  status=micro_bundle["status"],
920  expected_statuses=["pass"],
921  purpose="Local exactness and density-validity gate for mandatory 1 to 3 qubit microcases.",
922  generation_command=micro_validation_command,
923  summary={
924  "total_cases": micro_bundle["summary"]["total_cases"],
925  "passed_cases": micro_bundle["summary"]["passed_cases"],
926  "pass_rate": micro_bundle["summary"]["pass_rate"],
927  },
928  ),
930  artifact_id="exact_regime_workflow_bundle",
931  artifact_class="workflow_exact_regime_bundle",
932  mandatory=True,
933  path=EXACT_REGIME_WORKFLOW_BUNDLE_FILENAME,
934  status=workflow_bundle["status"],
935  expected_statuses=["pass"],
936  purpose="Workflow-scale exactness evidence across the mandatory 4/6/8/10 exact regime.",
937  generation_command=workflow_command,
938  summary={
939  "total_cases": workflow_bundle["summary"]["total_cases"],
940  "passed_cases": workflow_bundle["summary"]["passed_cases"],
941  "pass_rate": workflow_bundle["summary"]["pass_rate"],
942  "documented_10q_anchor_present": workflow_bundle["summary"][
943  "documented_10q_anchor_present"
944  ],
945  },
946  ),
948  artifact_id="fixed_parameters_4q",
949  artifact_class="fixed_parameter_case",
950  mandatory=True,
951  path="fixed_parameters_4q.json",
952  status=fixed_results[0]["status"],
953  expected_statuses=["completed"],
954  purpose="Supported fixed-parameter 4-qubit anchor exactness evidence.",
955  generation_command=base_validation_command,
956  summary={
957  "qbit_num": fixed_results[0]["qbit_num"],
958  "absolute_energy_error": fixed_results[0].get("absolute_energy_error"),
959  },
960  ),
962  artifact_id="fixed_parameters_6q",
963  artifact_class="fixed_parameter_case",
964  mandatory=True,
965  path="fixed_parameters_6q.json",
966  status=fixed_results[1]["status"],
967  expected_statuses=["completed"],
968  purpose="Supported fixed-parameter 6-qubit anchor exactness evidence.",
969  generation_command=base_validation_command,
970  summary={
971  "qbit_num": fixed_results[1]["qbit_num"],
972  "absolute_energy_error": fixed_results[1].get("absolute_energy_error"),
973  },
974  ),
976  artifact_id="optimization_trace_4q",
977  artifact_class="optimization_trace",
978  mandatory=True,
979  path="optimization_trace_4q.json",
980  status=trace_result["status"],
981  expected_statuses=["completed"],
982  purpose="Reproducible bounded 4-qubit optimization trace for the exact noisy anchor workflow.",
983  generation_command=base_validation_command,
984  summary={
985  "optimizer": trace_result.get("optimizer"),
986  "parameter_count": trace_result.get("parameter_count"),
987  "workflow_completed": trace_result.get("workflow_completed"),
988  "initial_energy": trace_result.get("initial_energy"),
989  "final_energy": trace_result.get("final_energy"),
990  },
991  ),
993  artifact_id="unsupported_state_vector_density_noise",
994  artifact_class="unsupported_case",
995  mandatory=True,
996  path="unsupported_state_vector_density_noise.json",
997  status=unsupported_result["status"],
998  expected_statuses=["unsupported"],
999  purpose="Structured negative evidence for backend-mismatch and mixed-state-only unsupported behavior.",
1000  generation_command=base_validation_command,
1001  summary={
1002  "unsupported_category": unsupported_result.get("unsupported_category"),
1003  "unsupported_reason": unsupported_result.get("unsupported_reason"),
1004  },
1005  ),
1006  ]
1007 
1008  mandatory_artifacts = [artifact for artifact in artifacts if artifact["mandatory"]]
1009  present_count = 0
1010  status_match_count = 0
1011  for artifact in mandatory_artifacts:
1012  if (output_dir / artifact["path"]).exists():
1013  present_count += 1
1014  if artifact["status"] in artifact["expected_statuses"]:
1015  status_match_count += 1
1016 
1017  bundle_status = (
1018  "pass"
1019  if present_count == len(mandatory_artifacts)
1020  and status_match_count == len(mandatory_artifacts)
1021  else "fail"
1022  )
1023 
1024  bundle = {
1025  "suite_name": "exact_density_validation",
1026  "status": bundle_status,
1027  "backend": PRIMARY_BACKEND,
1028  "reference_backend": REFERENCE_BACKEND,
1029  "software": build_software_metadata(),
1030  "provenance": {
1031  "generation_command": validation_bundle_command,
1032  "working_directory": str(REPO_ROOT),
1033  "git_revision": get_git_revision(),
1034  },
1035  "summary": {
1036  "mandatory_artifact_count": len(mandatory_artifacts),
1037  "present_artifact_count": present_count,
1038  "status_match_count": status_match_count,
1039  "missing_artifact_count": len(mandatory_artifacts) - present_count,
1040  "mismatched_status_count": len(mandatory_artifacts) - status_match_count,
1041  },
1042  "artifacts": artifacts,
1043  }
1044  validate_exact_density_validation_bundle(bundle, output_dir)
1045  return bundle
1046 
1047 
1048 def validate_exact_density_validation_bundle(bundle, bundle_dir: Path):
1049  missing_fields = [field for field in EXACT_DENSITY_VALIDATION_BUNDLE_FIELDS if field not in bundle]
1050  if missing_fields:
1051  raise ValueError(
1052  "Exact-density validation bundle is missing required fields: {}".format(
1053  ", ".join(missing_fields)
1054  )
1055  )
1056 
1057  artifact_ids = {artifact["artifact_id"] for artifact in bundle["artifacts"]}
1058  required_ids = {
1059  "micro_validation_bundle",
1060  "exact_regime_workflow_bundle",
1061  "fixed_parameters_4q",
1062  "fixed_parameters_6q",
1063  "optimization_trace_4q",
1064  "unsupported_state_vector_density_noise",
1065  }
1066  if required_ids - artifact_ids:
1067  raise ValueError(
1068  "Exact-density validation bundle is missing required artifact IDs: {}".format(
1069  ", ".join(sorted(required_ids - artifact_ids))
1070  )
1071  )
1072 
1073  for artifact in bundle["artifacts"]:
1074  artifact_path = bundle_dir / artifact["path"]
1075  if artifact["mandatory"] and not artifact_path.exists():
1076  raise ValueError(
1077  f"Exact-density validation bundle is missing artifact file: {artifact['path']}"
1078  )
1079  if artifact["status"] not in artifact["expected_statuses"]:
1080  raise ValueError(
1081  f"Exact-density validation artifact {artifact['artifact_id']} has unexpected status {artifact['status']}"
1082  )
1083 
1084 
1085 def write_exact_density_validation_bundle(output_path: Path, bundle):
1086  validate_exact_density_validation_bundle(bundle, output_path.parent)
1087  output_path.parent.mkdir(parents=True, exist_ok=True)
1088  output_path.write_text(json.dumps(bundle, indent=2) + "\n", encoding="utf-8")
1089 
1090 
1092  print("\n" + "=" * 78)
1093  print(
1094  " Exact-Density Validation Bundle [{} vs {}]".format(
1095  bundle["backend"], bundle["reference_backend"]
1096  )
1097  )
1098  print("=" * 78)
1099  print(
1100  " Mandatory artifacts present: {}/{}".format(
1101  bundle["summary"]["present_artifact_count"],
1102  bundle["summary"]["mandatory_artifact_count"],
1103  )
1104  )
1105  print(
1106  " Status matches: {}/{}".format(
1107  bundle["summary"]["status_match_count"],
1108  bundle["summary"]["mandatory_artifact_count"],
1109  )
1110  )
1111  print(" Git revision:", bundle["provenance"]["git_revision"])
1112 
1113 
1115  output_dir = Path(output_dir)
1116  output_dir.mkdir(parents=True, exist_ok=True)
1117 
1118  fixed_results = [
1119  capture_case(
1120  f"fixed_parameters_{qbit_num}q",
1121  lambda qbit_num=qbit_num: run_fixed_parameter_case(qbit_num),
1122  )
1123  for qbit_num in FIXED_PARAMETER_QUBITS
1124  ]
1125  trace_result = capture_case("optimization_trace_4q", run_optimization_trace)
1126  unsupported_base_metadata = build_case_metadata(
1127  backend="state_vector",
1128  qbit_num=4,
1129  topology=build_open_chain_topology(4),
1130  density_noise=build_reference_noise(),
1131  hamiltonian=build_hamiltonian_metadata(),
1132  )
1133  unsupported_result = capture_case(
1134  "unsupported_state_vector_density_noise",
1135  run_unsupported_state_vector_density_noise_case,
1136  base_metadata=unsupported_base_metadata,
1137  )
1138 
1139  for result in fixed_results:
1140  write_json(output_dir / f"{result['case_name']}.json", result)
1141  write_json(output_dir / "optimization_trace_4q.json", trace_result)
1142  write_json(
1143  output_dir / "unsupported_state_vector_density_noise.json",
1144  unsupported_result,
1145  )
1146 
1147  micro_results = run_micro_validation()
1148  micro_bundle = build_micro_validation_bundle(micro_results)
1149  write_micro_validation_bundle_file(output_dir / MICRO_VALIDATION_BUNDLE_FILENAME, micro_bundle)
1150 
1151  workflow_results = run_exact_regime_workflow_matrix()
1152  workflow_bundle = build_exact_regime_workflow_bundle(workflow_results)
1154  output_dir / EXACT_REGIME_WORKFLOW_BUNDLE_FILENAME, workflow_bundle
1155  )
1156 
1157  validation_bundle = build_exact_density_validation_bundle(
1158  output_dir,
1159  fixed_results=fixed_results,
1160  trace_result=trace_result,
1161  unsupported_result=unsupported_result,
1162  micro_bundle=micro_bundle,
1163  workflow_bundle=workflow_bundle,
1164  )
1165  write_exact_density_validation_bundle(output_dir / EXACT_DENSITY_VALIDATION_BUNDLE_FILENAME, validation_bundle)
1166  return validation_bundle
1167 
1168 
1169 def run_fixed_parameter_case(qbit_num: int):
1170  vqe, hamiltonian, topology = build_vqe(qbit_num)
1171  params = build_initial_parameters(vqe.get_Parameter_Num())
1172  vqe.set_Optimized_Parameters(params)
1173  bridge_metadata = build_reference_bridge_metadata(vqe)
1174 
1175  squander_energy = float(vqe.Optimization_Problem(params))
1176 
1177  noisy_qiskit_circuit = insert_reference_noise(
1178  vqe.get_Qiskit_Circuit(),
1180  )
1181  simulator = AerSimulator(method="density_matrix")
1182  result = simulator.run(noisy_qiskit_circuit, shots=1).result()
1183  aer_rho = np.asarray(result.data()["density_matrix"])
1184  aer_energy_real, aer_energy_imag = density_energy(hamiltonian, aer_rho)
1185 
1186  trace_val = np.trace(aer_rho)
1187  purity = float(np.real(np.trace(aer_rho @ aer_rho)))
1188  artifact = build_case_metadata(
1189  backend=PRIMARY_BACKEND,
1190  qbit_num=qbit_num,
1191  topology=topology,
1192  density_noise=build_reference_noise(),
1193  reference_backend=REFERENCE_BACKEND,
1194  hamiltonian=build_hamiltonian_metadata(),
1195  )
1196  artifact.update(
1197  {
1198  "status": "completed",
1199  "parameter_vector": params.tolist(),
1200  "squander_energy": squander_energy,
1201  "aer_energy_real": aer_energy_real,
1202  "aer_energy_imag": aer_energy_imag,
1203  "absolute_energy_error": abs(squander_energy - aer_energy_real),
1204  "aer_trace_real": float(np.real(trace_val)),
1205  "aer_trace_imag": float(np.imag(trace_val)),
1206  "aer_purity": purity,
1207  **bridge_metadata,
1208  }
1209  )
1210  return artifact
1211 
1212 
1214  vqe, _, topology = build_vqe(4, optimizer="COSINE")
1215  initial_parameters = build_initial_parameters(vqe.get_Parameter_Num())
1216  vqe.set_Optimized_Parameters(initial_parameters)
1217  bridge_metadata = build_exact_regime_bridge_metadata(vqe, execution_ready=True)
1218 
1219  trace_start = time.perf_counter()
1220  initial_energy = float(vqe.Optimization_Problem(initial_parameters))
1221  vqe.Start_Optimization()
1222  final_parameters = np.asarray(vqe.get_Optimized_Parameters(), dtype=np.float64)
1223  final_energy = float(vqe.Optimization_Problem(final_parameters))
1224 
1225  artifact = build_case_metadata(
1226  backend=PRIMARY_BACKEND,
1227  qbit_num=4,
1228  topology=topology,
1229  density_noise=build_reference_noise(),
1230  hamiltonian=build_hamiltonian_metadata(),
1231  optimizer="COSINE",
1232  )
1233  artifact.update(
1234  {
1235  "initial_parameters": initial_parameters.tolist(),
1236  "final_parameters": final_parameters.tolist(),
1237  "initial_energy": initial_energy,
1238  "final_energy": final_energy,
1239  "energy_improvement": initial_energy - final_energy,
1240  "optimizer_config": build_optimizer_config(),
1241  "parameter_count": int(initial_parameters.size),
1242  "workflow_completed": True,
1243  "trace_kind": "bounded_optimization_trace",
1244  "total_trace_runtime_ms": (time.perf_counter() - trace_start) * 1000.0,
1245  "process_peak_rss_kb": int(
1246  resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
1247  ),
1248  "status": "completed",
1249  **bridge_metadata,
1251  "counts_toward_mandatory_baseline": False,
1252  "required_validation_trace": True,
1253  }
1254  )
1255  return artifact
1256 
1257 
1260  parameters = build_initial_parameters(vqe.get_Parameter_Num())
1261  artifact = build_case_metadata(
1262  backend="state_vector",
1263  qbit_num=4,
1264  topology=topology,
1265  density_noise=build_reference_noise(),
1266  hamiltonian=build_hamiltonian_metadata(),
1267  )
1268  artifact.update(
1269  {
1270  "parameter_vector": parameters.tolist(),
1271  "energy": float(vqe.Optimization_Problem(parameters)),
1272  "status": "completed",
1273  }
1274  )
1275  return artifact
1276 
1277 
1278 def capture_case(case_name: str, case_callable, base_metadata=None):
1279  base_metadata = {} if base_metadata is None else dict(base_metadata)
1280  try:
1281  result = dict(base_metadata)
1282  result.update(case_callable())
1283  result.setdefault("status", "completed")
1284  result["case_name"] = case_name
1285  except Exception as exc:
1286  result = dict(base_metadata)
1287  result.update(
1288  {
1289  "case_name": case_name,
1290  "status": "unsupported",
1291  "unsupported_category": "phase2_support_matrix",
1292  "unsupported_reason": str(exc),
1293  }
1294  )
1295 
1297  return result
1298 
1299 
1300 def write_json(output_path: Path, payload):
1301  validate_artifact_payload(payload)
1302  output_path.parent.mkdir(parents=True, exist_ok=True)
1303  output_path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
1304 
1305 
1306 def main():
1307  parser = argparse.ArgumentParser(description=__doc__)
1308  parser.add_argument(
1309  "--output-dir",
1310  type=Path,
1311  default=None,
1312  help="Optional directory for JSON evidence artifacts.",
1313  )
1314  parser.add_argument(
1315  "--workflow-bundle",
1316  action="store_true",
1317  help="Run the workflow-scale exact-regime validation matrix and emit the bundle.",
1318  )
1319  parser.add_argument(
1320  "--publication-bundle",
1321  action="store_true",
1322  help="Run the full exact-density validation bundle workflow.",
1323  )
1324  args = parser.parse_args()
1325 
1326  if args.publication_bundle:
1327  if args.output_dir is None:
1328  raise ValueError(
1329  "Exact-density validation bundle generation requires --output-dir"
1330  )
1331  validation_bundle = generate_exact_density_validation_bundle(args.output_dir)
1333  if validation_bundle["status"] != "pass":
1334  raise SystemExit(1)
1335  return
1336 
1337  if args.workflow_bundle:
1338  workflow_results = run_exact_regime_workflow_matrix()
1339  trace_result = capture_case("optimization_trace_4q", run_optimization_trace)
1340  workflow_bundle = build_exact_regime_workflow_bundle(
1341  workflow_results, trace_result=trace_result
1342  )
1343  print_exact_regime_workflow_summary(workflow_bundle)
1344  if trace_result["status"] == "completed":
1345  print(
1346  " Workflow supported trace [{}]:".format(trace_result["backend"]),
1347  trace_result["trace_kind"],
1348  "bridge_pass =",
1349  trace_result["bridge_supported_pass"],
1350  )
1351 
1352  if args.output_dir is not None:
1354  args.output_dir / EXACT_REGIME_WORKFLOW_BUNDLE_FILENAME,
1355  workflow_bundle,
1356  )
1357  write_json(args.output_dir / OPTIMIZATION_TRACE_ARTIFACT_FILENAME, trace_result)
1358 
1359  if workflow_bundle["status"] != "pass":
1360  raise SystemExit(1)
1361  return
1362 
1363  fixed_results = [
1364  capture_case(
1365  f"fixed_parameters_{qbit_num}q",
1366  lambda qbit_num=qbit_num: run_fixed_parameter_case(qbit_num),
1367  )
1368  for qbit_num in FIXED_PARAMETER_QUBITS
1369  ]
1370  trace_result = capture_case("optimization_trace_4q", run_optimization_trace)
1371  unsupported_base_metadata = build_case_metadata(
1372  backend="state_vector",
1373  qbit_num=4,
1374  topology=build_open_chain_topology(4),
1375  density_noise=build_reference_noise(),
1376  hamiltonian=build_hamiltonian_metadata(),
1377  )
1378  unsupported_result = capture_case(
1379  "unsupported_state_vector_density_noise",
1380  run_unsupported_state_vector_density_noise_case,
1381  base_metadata=unsupported_base_metadata,
1382  )
1383 
1384  for result in fixed_results:
1385  if result["status"] == "completed":
1386  print(
1387  "Fixed-parameter case [{}]:".format(result["backend"]),
1388  result["qbit_num"],
1389  "qubits, |E_sq - E_aer| =",
1390  f"{result['absolute_energy_error']:.6e}",
1391  )
1392  else:
1393  print(
1394  "Fixed-parameter case [{}]:".format(result["backend"]),
1395  result["status"],
1396  result["case_name"],
1397  result["unsupported_reason"],
1398  )
1399 
1400  if trace_result["status"] == "completed":
1401  print(
1402  "Optimization trace [{}]:".format(trace_result["backend"]),
1403  "initial =",
1404  f"{trace_result['initial_energy']:.6e}",
1405  "final =",
1406  f"{trace_result['final_energy']:.6e}",
1407  )
1408  else:
1409  print(
1410  "Optimization trace [{}]:".format(trace_result["backend"]),
1411  trace_result["status"],
1412  trace_result["unsupported_reason"],
1413  )
1414 
1415  print(
1416  "Unsupported backend-mismatch case [{}]:".format(unsupported_result["backend"]),
1417  unsupported_result["status"],
1418  unsupported_result.get("unsupported_reason", ""),
1419  )
1420 
1421  if args.output_dir is not None:
1422  for result in fixed_results:
1423  write_json(args.output_dir / f"{result['case_name']}.json", result)
1424  write_json(args.output_dir / "optimization_trace_4q.json", trace_result)
1425  write_json(
1426  args.output_dir / "unsupported_state_vector_density_noise.json",
1427  unsupported_result,
1428  )
1429 
1430 
1431 if __name__ == "__main__":
1432  main()
def density_energy(hamiltonian, density_matrix)
def build_support_tier_summary(cases)
def _build_validation_bundle_artifact_entry(artifact_id, artifact_class, mandatory, path, status, expected_statuses, purpose, generation_command, summary=None)
def classify_noise_boundary_reason
def build_required_case_classification()
def build_squander_density_from_qiskit_circuit(base_circuit, density_noise)