scpn-quantum-control treats differentiability as a product surface, not a hidden implementation detail. The goal is to make coupled-oscillator quantum control trainable, testable, and explainable across quantum gradients, classical program AD, compiler-backed kernels, and future ML-framework adapters.
The differentiable lane is where optimisation-heavy teams get practical value: a bounded route from objectives to gradient diagnostics that is explicit about what is analytic, approximate, stochastic, and unsupported.
In practical terms, this means:
- training and convergence evidence can be produced without waiting on hardware;
- optimisation routes can be compared against finite-difference and multi-framework references;
- unsupported or blocked cases stay visible in the API evidence contract.
- finite-difference result artefacts carry an explicit diagnostic-only claim boundary so they cannot be promoted as analytic, parameter-shift, native-framework, whole-program AD, provider, hardware, or production benchmark evidence.
This section is intentionally conservative. It prefers explicit fail-closed boundaries over hidden fallback because enterprises depend on predictable failure modes.
A useful quantum-control framework must answer four questions quickly:
- Can the objective produce a gradient?
- Is that gradient analytic, approximate, stochastic, or unsupported?
- Does the gradient help an optimiser converge on a known problem?
- Can another tool or framework reproduce the same derivative?
This repository now documents those questions directly. Current support is deliberately bounded so users can trust the surfaces that are advertised.
The canonical grad(...) and value_and_grad(...) dispatcher implementation
lives in scpn_quantum_control.differentiable_canonical_api. The legacy
scpn_quantum_control.differentiable facade and package root continue to
re-export those functions as the stable user import path.
Whole-program dispatch now follows the same pattern:
whole_program_value_and_grad(...) and whole_program_grad(...) are owned by
scpn_quantum_control.whole_program_ad_api and re-exported by the facade.
The generated Differentiable Support Matrix is the canonical public snapshot for current Program AD registry rows and quantum-gradient planner audit cases. The table below provides workflow context; it is not a separately maintained numeric source of truth.
The generated Differentiable Reviewer Evidence page maps the five DP-015 criticisms and seven DP-030 evidence-package rows to scoped reproduction commands or stable public roadmap gaps. A passing bounded row does not promote provider, hardware, compiler, or performance claims.
| Surface | Status | Evidence route |
|---|---|---|
| Unified differentiable API | Available through scpn_quantum_control.differentiable_api for value, gradient, Jacobian, Hessian, support, diagnostics, compile, local conformance benchmark, transform-algebra, and GUI/audit-dashboard status reports using one JSON-ready evidence envelope. Local conformance benchmark evidence is built by scpn_quantum_control.differentiable_benchmark_report and wrapped by the facade without changing payload keys or promoting non-isolated evidence. Transform-algebra evidence is built by scpn_quantum_control.differentiable_transform_algebra and keeps finite differences diagnostic, with unsupported custom-rule, structured-container, complex-valued objective, and nondifferentiable rows blocked. Dashboard status rows label executable, metadata-only, diagnostic, conformance-backed, planned, blocked, and unsupported routes without promoting Program AD metadata, bounded program_ad_effect_ir.v1 round-trip parsing, higher-order transform evidence, Rust/LLVM compiler paths, provider routes, hardware routes, or local conformance rows beyond their evidence class. |
Differentiable API |
| Parameter-shift gradients | Available for callable scalar objectives, structured PhaseVQE gradients, local gradient-descent VQE examples, metric-aware natural-gradient descent, multi-start optimizer comparison evidence, known-ground-state convergence certificates across natural-gradient, Adam, L-BFGS-B, seeded SPSA, and COBYLA, compatible composed phase-control objectives through scpn_quantum_control.phase, declared finite-spectrum phase plans through plan_generalised_parameter_shift(...), exact shifted-evaluation gradients through value_and_generalised_parameter_shift_grad(...), and finite-shot uncertainty records that must reconstruct their published gradient and covariance from plus/minus shifted samples while keeping standard errors, covariance diagonals, confidence radii, and interval bounds consistent. |
Quantum Gradients, Variational Methods |
| Objective evidence | Available for composed phase-control objectives through finite-difference agreement, compatibility-gate checks, and local training certificates. Synchronisation-specific losses are available for Kuramoto order-parameter targets, pairwise phase-locking, and disjoint cluster-synchronisation objectives over explicit phase vectors. Bounded open-system objectives are available through run_open_system_objective_suite(), which evaluates Lindblad density-matrix and seeded MCWF trajectory-ensemble objectives with trace, Hermiticity, positivity, trajectory-shape, and same-seed replay certificates. Bounded coupling time-series recovery is available through run_coupling_recovery_suite(), which recovers known Kuramoto phase couplings and XY pair-energy couplings from deterministic synthetic clean, noisy, and missing-data records. Bounded synchronisation witnesses are available through run_sync_witness_suite(), which computes harmonic Kuramoto order parameters and exact Vietoris-Rips persistent homology (Betti curves and dimension-0/1 persistence diagrams) over deterministic synchronised, desynchronised, and clustered phase clouds with bootstrap uncertainty. These objective rows remain local finite-difference, recovery, or topological-witness evidence, not provider, hardware, adjoint-Lindblad, stochastic-gradient, benchmark-promotion, arbitrary partial-observation inference, phase-tomography, high-dimensional-manifold, or standalone oscillatools ownership claims. |
Differentiable API, Quantum Gradients, Lindblad, Open-System Hardware |
| Objective execution planning | Available for composed objectives through fail-closed routing between pure parameter-shift, hybrid term-gradient, hardware-blocked, and unsupported backend routes. | Differentiable API, Quantum Gradients |
| Gradient support matrix | Generated from executable planner audit cases, including supported and fail-closed combinations with explicit alternatives and claim boundaries. | Differentiable Support Matrix, Differentiable API, Quantum Gradients |
| Reviewer evidence index | Generated from typed DP-015/030 rows; validates commands, repository paths, changelog markers, support-matrix counts, capability-manifest surfaces, and public open-gap pointers. | Differentiable Reviewer Evidence, Differentiable Roadmap |
| Unified readiness ledger | Available through run_differentiable_readiness_audit() as one JSON-ready reviewer ledger aggregating support, transform, QNode, provider, hardware-policy, and provider hardware-preparation audits. |
Differentiable API, Quantum Gradients |
| Transform nesting governance | Available for bounded first-order, value-and-gradient, deterministic local Hessian, nested-grad Hessian, tape, scalar local JVP/VJP, scalar local jacfwd/jacrev, deterministic native vector-output Jacobian execution, native manual vmap(grad), exact custom JVP/VJP rules under eager vmap, program-AD grad(vmap(f)) over trace-aware leaves, JVP/VJP over vmap of whole-program AD gradients, local Hessian over a whole-program AD scalar objective, JVP/VJP over whole-program AD Hessian transforms, and provider-callback QNode transforms with finite-shot uncertainty propagation, with fail-closed framework vectorization, adapter-nesting, malformed-provider, finite-shot curvature, and hardware boundaries. |
Differentiable API, Quantum Gradients |
| Transform-algebra metamorphic gate | Available through run_transform_algebra_audit() and differentiable_api("transform_algebra_report") for local deterministic checks covering grad(vmap(f)), vmap(grad(f)), jacrev/jacfwd, Hessian symmetry, JVP/VJP duality, linearity, chain rule, phase-periodic parameter-shift wraparound, finite-difference diagnostic boundaries, dtype promotion, broadcasting, deterministic replay, masked parameters, sparse parameters, complex-step real-objective evidence, and batched observables. Custom JVP/VJP registration, structured containers, complex-valued objective semantics, and nondifferentiable cusps remain fail-closed until their exact contracts exist. |
Differentiable API |
| QFI/FSS finite-size evidence | Available through differentiable_qfi_fss_report() and differentiable_api("qfi_fss_report") for local dense exact Kuramoto-XY gap-minimum scans with BKT and inverse-size fit residual diagnostics, strict finite-size/coupling-grid validation, JSON-ready payloads, and explicit non-hardware/non-performance/non-thermodynamic-limit claim boundaries. |
Differentiable API, Analysis API |
| Provider-gradient readiness | Available as an executable support matrix for deterministic callbacks, finite-shot callbacks, multi-frequency rules, hardware-blocked routes, unknown backends, malformed samples, and policy-bound hardware-preparation evidence. | Differentiable API, Quantum Gradients |
| Hardware-gradient policy readiness | Available as a fail-closed dry-run policy layer for provider/backend allowlists, shot and evaluation budgets, evidence IDs, and live-ticket gating before hardware-gradient job preparation. Provider preparation records, a provider hardware-preparation audit suite, and an aggregate provider/hardware safety gate can be generated without executing QPU jobs; promotion readiness requires a UTC-fresh DifferentiableProviderHardwareEvidenceChain tying live ticket, provider/backend/job/circuit, allowlist, shot budget, raw-count replay, calibration, statevector comparison, and isolated benchmark artefacts together. |
Differentiable API, Quantum Gradients |
| Compiler/program AD | Available for supported scalar, vector, and matrix primitives with registry contracts, lowering reports, native executable kernels on bounded paths, verified whole-program determinant lowering through 19x19, inverse/vector-solve/matrix-RHS solve lowering through 7x7 with a shared native factorisation helper for 5x5 through 7x7, 2x2 matrix_power(..., 2) and 2x2 multi_dot native lowering, trace-aware eager vmap slicing/stacking inside whole-program objectives, fail-closed finite/dtype/shape checks, trainable-mask zeroing at derivative result boundaries including whole-program forward and adjoint result containers, deterministic program_ad_effect_ir.v1 metadata parsing, metadata-only phi records for runtime and source-level control joins backed by program_ad_control_phi_metadata_contracts, deterministic alias/effect metadata summaries and static alias-lattice readiness reports over emitted Program AD IR, generated ProgramADAdjointStep executable replay metadata with finite local pullback scales, cotangent-flow rows, reverse effect-order rows, executed runtime control/phi row bindings, blocked non-executed phi inputs, IR-format provenance, replay-count provenance on supported scalar adjoint generation results, construction-time supported WholeProgramADResult replay validation against the captured stabilized IR, attached adjoint gradient, and forward gradient, program_adjoint_replay_gradient() execution of the generated step stream for caller-visible replay, and an execution-gating whole-program frontend report with explicit Python-semantics diagnostics. Python scalar abs() and NumPy absolute-value tracing share the registered fail-closed zero-cusp policy. np.sign and np.heaviside have registered derivative-losing elementwise contracts that fail closed before trace execution. Product, interpolation, signal, and stencil primitives (np.inner, np.outer, np.matmul, np.tensordot, np.einsum, np.interp, np.convolve, np.correlate, and np.gradient) have registry-backed conformance through structured_numeric_primitive_contracts; static-grid np.interp, static rank-1 np.convolve/np.correlate, and static scalar/coordinate-spacing np.gradient Program AD IR have compact Rust value+gradient replay, while dynamic interpolation grids, dynamic signal metadata, singular stencil spacing, and LLVM/JIT executable promotion remain fail-closed. Cumulative primitives (np.cumsum, np.cumprod, and np.diff) have registry-backed conformance and compact Program AD Rust value+gradient replay through cumulative_primitive_contracts; dynamic axis promotion and LLVM/JIT executable promotion remain fail-closed. Assembly primitives (np.zeros_like, np.ones_like, np.full_like, np.hstack, np.vstack, np.column_stack, and np.dstack) have registry-backed conformance through assembly_primitive_contracts; dynamic shape assembly and Rust/LLVM executable promotion remain fail-closed. Reduction primitives (np.sum, np.prod, np.mean, np.var, np.std, np.trapezoid, np.max, np.min, np.median, scalar-q np.quantile, and scalar-q np.percentile) have registry-backed conformance through reduction_primitive_contracts; dynamic axes, dynamic q, tie boundaries, zero-variance standard deviation, and Rust/LLVM executable promotion remain fail-closed. Shape primitives (np.reshape, np.ravel, np.transpose, np.expand_dims, np.squeeze, np.swapaxes, np.moveaxis, np.repeat, np.atleast_1d, np.atleast_2d, np.atleast_3d, np.tile, np.roll, np.rot90, np.flip, np.flipud, and np.fliplr) have registry-backed conformance through shape_primitive_contracts; dynamic shape arguments, invalid axes, and Rust/LLVM executable promotion remain fail-closed. Broadcast primitives (np.broadcast_to, np.broadcast_arrays, and binary elementwise rank broadcasting) have registry-backed conformance through broadcast_primitive_contracts; dynamic output shapes, incompatible shapes, subclass propagation, and Rust/LLVM executable promotion remain fail-closed. np.sort has a registered strict-total-order selection contract for bounded trace dispatch; equal values fail closed. np.select, np.piecewise, np.choose, np.compress, and np.extract have registered static selection-fold contracts with shape, dtype, mask/selector/branch metadata, batching, lowering metadata, and fail-closed dynamic-mask/dynamic-selector boundaries. np.argmax, np.argmin, trace-array .argmax()/.argmin(), and np.argsort have registered integer-output selection contracts that validate shape, dtype, static-axis/kind, batching, and lowering metadata before failing closed as nondifferentiable selectors. np.take_along_axis, np.delete, np.pad, and np.insert have registered static indexing/gather/assembly contracts with direct JVP/VJP factories and conformance row indexing_static_gather_contracts; dynamic indices, dynamic insertion values, non-constant padding modes, and Rust/LLVM executable promotion remain fail-closed. np.flipud and np.fliplr have registered rank-checked fixed-axis shape contracts. np.zeros_like, np.ones_like, and np.full_like have registered reference-shape/scalar-fill assembly contracts for derivative-preserving constant arrays. np.hstack, np.vstack, np.column_stack, and np.dstack have registered static-shape assembly contracts with fixed-shape direct JVP/VJP factories. np.var/np.std and trace-array .var()/.std() have registered static axis/ddof reduction contracts with positive-denominator and zero-variance standard-deviation boundaries. np.max/np.min and trace-array .max()/.min() have registered unique-selector reduction contracts. np.median, scalar-q np.quantile, and scalar-q np.percentile have registered order-statistic reduction contracts with static q/axis/method validation and strict-order selection boundaries. Emitted alias metadata distinguishes mutation-version edges from bounded local scalar rebinding, bounded expression-rebinding aliases, local object-attribute aliases, branch-local control-path alias blockers, local list-alias rebinding/mutation metadata, bounded loop-carried scalar state metadata, supported executed array-view aliases for reshape, ravel, basic slicing, take, transpose, squeeze, expand_dims, atleast rank promotion, swapaxes, moveaxis, repeat source reuse, tile source reuse, roll, rot90, flip, flipud, and fliplr, plus static rank-1 slice-mutation source indices for supported Program AD views. Native determinant traces at 20x20+, inverse/solve traces at 8x8+, matrix-RHS solves with more than four RHS columns, and shape-changing linalg fail closed before native compilation; wider rectangular multi_dot lowering remains verified only through MLIR-runtime executable rules; native LLVM/JIT promotion for linalg-array kernels fails closed until independently verified executable kernels exist. Rust Program AD value+gradient replay now supports opcode-bearing static diag gather/scatter nodes, static diagflat construction nodes, and static vector- and matrix-RHS solve output nodes, static integer matrix_power output nodes, and still fails closed for malformed metadata, invalid diagonal shapes/indices, non-square matrix-power inputs, non-finite operands, singular negative powers, and dynamic-power claims. Norm and linalg conditioning diagnostics report zero-norm, rank-threshold, repeated-spectrum, and ill-conditioned boundaries before callers rely on sensitive direct derivative rules. Closures, default arguments, keyword-only parameters, *args, **kwargs, generator expressions, and plain list comprehensions without dynamic filters are reported as accepted semantics; filtered comprehensions, set/dict comprehensions, captured object/dataclass attributes, recursion, async functions, await expressions, async iteration, generator functions, context managers, exception control flow, decorators, and source-unavailable objectives fail closed before execution. Phi records remain provenance only; generated adjoint steps execute only the supported scalar reverse-adjoint step stream; static alias-lattice reports are bounded to emitted Program AD IR and record mutation effects, non-executed phi inputs, branch-local control-path aliases, frontend unsupported Python semantics with source-region/bytecode diagnostic provenance, and captured/global object-attribute roots/details as static object-model blockers, not mutation adjoints, arbitrary dynamic-Python frontend lowering, non-executed branch adjoints, captured/global object-attribute alias sets, full reverse-mode compiler AD, or arbitrary executable compiler lowering. |
Differentiable API, Quickstart |
| Primitive registry | The live registry identities, families, derivative, batching, lowering, shape, dtype, static-argument, nondifferentiability, effect, and dispatch facets are rendered from executable state rather than copied into this guide. The optional Rust metadata mirror remains overlap and provenance evidence only; it does not promote executable Rust/LLVM, hardware, or performance support. | Differentiable Support Matrix, scpn_quantum_control.program_ad_registry, scpn_quantum_control.program_ad_rust_bridge |
| Reverse replay and program traces | Available for supported captured operations with source/bytecode feature reports, a first-class bytecode/source frontend execution gate through compile_whole_program_frontend(), bytecode basic blocks, source regions, source-bytecode line maps with source-relative and absolute CPython line coordinates, symbol-scope entries, deterministic frontend digests, and named Python-semantics accept/reject diagnostics. The static frontend implementation lives in scpn_quantum_control.whole_program_frontend with scpn_quantum_control.differentiable kept as the compatibility facade. whole_program_value_and_grad() requires the report to be frontend_ready, attaches the accepted report to WholeProgramADResult.frontend_report, and rejects hard gaps before objective execution with the frontend digest plus source/region/bytecode diagnostics. Unsupported-semantics diagnostics also bind fail-closed constructs to source-relative lines, optional absolute file lines, source-region IDs, and bytecode offsets when available. program_ad_ir_roundtrip_conformance is backed by program_ad_ir_roundtrip_contracts, checking stable program_ad_effect_ir.v1 parser reconstruction of emitted SSA/effect/control/phi metadata. program_ad_control_phi_metadata is backed by program_ad_control_phi_metadata_contracts, checking runtime/source control-region and ProgramADPhiNode provenance against analytic and adjoint references. program_ad_reverse_adjoint_replay is backed by program_adjoint_replay_provenance_contracts, checking construction-time WholeProgramADResult executable step-stream parity, program_adjoint_replay_gradient() caller-visible replay parity, ProgramADAdjointResult gradient parity, generated ProgramADAdjointStep rows, finite local pullback scales, cotangent-flow rows, reverse effect-order rows, replay node/effect/runtime control/phi row bindings, and blocked non-executed phi inputs against program_ad_effect_ir.v1. Unsupported arbitrary Python, executable compiler lowering, non-executed branch adjoints, full reverse-mode compiler AD, Rust/LLVM executable lowering, hardware, and performance promotion remain fail-closed. |
Support reports and module-specific tests |
| Finite-difference diagnostics | Available for scalar gradients, vector Jacobians, JVP/VJP contractions, Hessians, and HVPs as local smooth-objective diagnostics. Result artefacts expose claim_boundary metadata and remain non-promotional evidence, not analytic, parameter-shift, native-framework, whole-program AD, provider, hardware, or production benchmark claims. |
scpn_quantum_control.differentiable, Quantum Gradients |
| JAX, PyTorch, TensorFlow adapters | Optional parameter-shift value-and-gradient bridges, bounded phase-QNN native framework routes, deterministic registered local Phase-QNode statevector value-and-gradient plus flat, PyTree, pmap/sharding native-transform, and AOT/export value-route diagnostics for JAX, including PyTree Hessian symmetry evidence, one-row-per-local-device sharding checks, and jax.export serialization replay metadata, deterministic registered local Phase-QNode statevector, torch.func.grad/jacrev/vmap, non-fullgraph torch.compile transform lowering, torch_phase_qnode_compile_boundary_audit(...) boundary diagnostics, run_torch_autograd_function_audit(...) bounded custom torch.autograd.Function backward and SGD integration evidence, run_torch_module_state_audit(...) bounded module/optimizer state replay, run_torch_module_device_state_audit(...) bounded CPU/CUDA-smoke-gated device-state replay, run_torch_module_checkpoint_audit(...) bounded weights-only CPU checkpoint replay, run_torch_long_lived_checkpoint_matrix(...) bounded checkpoint matrix diagnostics, run_torch_training_loop_matrix(...) bounded multi-scenario training-loop matrix diagnostics, run_torch_module_export_audit(...) bounded torch.export save/load value replay, run_torch_export_shape_matrix(...) bounded static export-shape matrix diagnostics, run_torch_dynamic_shape_export_audit(...) bounded input-driven dynamic-batch export replay, and run_torch_aot_autograd_export_audit(...) bounded local AOTAutograd forward/backward FX graph persistence for PyTorch, plus fail-closed ML parity and PyTorch module/transform/compiler/device maturity audits are available for supported phase objectives. TensorFlow is explicitly scoped by run_tensorflow_maintenance_decision() as a bounded compatibility-only surface for declared phase-QNN tensor, GradientTape, tf.function, XLA-request, and Keras-layer routes; broad Graph/XLA parity and arbitrary Phase-QNode TensorFlow lowering remain blocked. Native framework autodiff through provider, finite-shot, dynamic-circuit, higher-order custom-autograd transforms, incompatible CUDA/device, registered PyTorch fullgraph torch.compile, dynamic-shape compile promotion, cross-runtime AOTAutograd execution, dynamic-shape AOTAutograd export, dynamic feature-width export promotion, cross-runtime checkpoint/export portability, external long-lived checkpoint corpus promotion, hardware, persistent cross-platform JAX export execution, exported VJPs, and arbitrary-simulator routes remains open. |
Differentiable Roadmap, Quantum Gradients |
| Gradient tape | MVP available for supported phase parameter-shift records, plus QNode-style tape records for deterministic, seeded finite-shot, and provider-boundary evidence. Finite-shot QNode records now serialize per-term/per-parameter shifted-sample provenance, shot counts, variances, trainable masks, and contribution records for local stochastic replay; the shared stochastic result contract rejects inconsistent shifted-sample contributions before confidence-policy metadata is accepted. Arbitrary Python and programme-IR tape semantics remain open. | Quantum Gradients, Differentiable Roadmap |
| Registered Phase-QNode circuit family | Available for the declared local gate/observable subset with arbitrary-depth registered circuit builders, deterministic depth/resource profiles, registered GHZ-chain and hardware-efficient multi-qubit templates, controlled-H/S/T plus Toffoli/CCZ/Fredkin gates, exact Toffoli/Fredkin operation-list decompositions, statevector execution, density-matrix execution with bounded single-qubit Kraus channels, analytic parameter-shift gradients for pure-state routes, framework parity rows, native JAX statevector value-and-gradient plus flat, PyTree, and pmap/sharding native-transform lowering rows with Hessian symmetry evidence, native PyTorch statevector, torch.func, non-fullgraph torch.compile transform lowering rows, and PyTorch compile-boundary diagnostics, verified SCPN MLIR-runtime lowering adapters, and affinity-labelled benchmark metadata. Unsupported gates, observables, provider paths, dynamic routes, native LLVM/JIT lowering, registered PyTorch fullgraph torch.compile promotion, dynamic-shape compile promotion, registered Phase-QNode AOTAutograd/export persistence, incompatible CUDA/device routes, noisy-channel gradients/metrics, finite-shot native framework lowering, and interpreter fallback success claims fail closed with support reports. |
Differentiable API, Benchmark Harness |
| QNN/QGNN/QSNN training lane | A bounded phase-QNN binary classifier, QNN-specific finite-difference gradient verification, deterministic multi-seed convergence envelopes, bounded loss-landscape grids, seeded finite-shot gradient uncertainty and noisy-convergence evidence, named external-gradient agreement records, dedicated caller-supplied framework-gradient agreement checks, deterministic convergence-suite evidence, conformance-suite evidence with unsuitable-scenario records, non-isolated optimizer-baseline comparisons across parameter-shift, finite-difference, SGD, Adam, L-BFGS-B, diagonal-Fisher natural-gradient, seeded SPSA, and derivative-free grid routes, QSNN parameter-shift training evidence, and a registered medium QNN/QGNN/QSNN/Kuramoto-XY training evidence suite are available locally; arbitrary QNN/QGNN/QSNN stacks and production convergence notebooks remain planned. | Differentiable API, Quantum Gradients |
The verified SCPN MLIR-runtime boundary serializes structured Phase-QNode observables without erasing their coefficients, terms, operator pairs, or dense matrix payloads. Custom-rule executables bind their available JVP/VJP callbacks at compilation and expose no closure for a missing direction. These guarantees are exercised through real public compiler calls; they do not alter the Rust or native LLVM numerical kernels, benchmark inputs, or performance claims.
Rust polyglot parity includes scpn_quantum_engine::program_ad_ir, a
serde-backed program_ad_effect_ir.v1 metadata parser with the PyO3
program_ad_effect_ir_metadata_summary(...) export, a bounded scalar forward
interpreter exposed as program_ad_effect_ir_interpret_forward(...), and a
bounded scalar value+gradient replay exposed as
program_ad_effect_ir_interpret_value_and_gradient(...). The
program_ad_registry_metadata_mirror(...) export validates the Python
registry-dispatch coverage snapshot and returns deterministic family/facet
counts plus conservative primitive-name overlap with existing bounded Rust
scalar/static-linalg plus compact interpolation, compact signal, compact stencil, compact cumulative, elementwise/static-structural, static diag/diagflat, static vector- and matrix-RHS solve, static matrix_power, fixed multi_dot,
2x2 distinct symmetric eigvalsh, 2x2 distinct symmetric eigh
eigenvalues/nonzero-offdiagonal eigenvectors, 2x2 real-distinct eigvals,
2x2 real-simple eig eigenvalue/eigenvector replay,
static rank-2 distinct-positive svd(..., compute_uv=False) singular-value replay,
constant-full-rank rank-1/Nx2/2xN pinv replay.
Rust
value+gradient replay executes opcode-bearing scalar, bounded elementwise
shaped-array, compact interpolation, compact signal, compact stencil, compact cumulative, and bounded static structural
program_ad_effect_ir.v1 rows at
the explicit operation boundary, including scalar-to-array broadcasting, adjoint
broadcast reduction, static reshape/ravel, broadcast_to, reversed-axis
transpose, static-axis concatenate/stack, compact signal: rows, compact stencil:gradient rows, compact cumsum/cumprod/diff rows, static-axis
sum/mean/prod/var/std/max/min/median reductions, scalar-q
quantile/percentile reductions, compact static-grid trapezoid
reductions with dx/x/xfull metadata, scalar all-axis
sum/mean/prod/var/std/max/min/median plus scalar-q
quantile/percentile and compact static-grid trapezoid objective closure,
static np.diag gather/scatter replay, static on-diagonal np.diagflat
construction replay, static vector- and matrix-RHS np.linalg.solve output replay, static integer-exponent np.linalg.matrix_power output replay,
fixed-signature np.linalg.multi_dot output replay, bounded 2x2 distinct
symmetric np.linalg.eigvalsh output replay, bounded 2x2 distinct symmetric
np.linalg.eigh eigenvalue and nonzero-offdiagonal eigenvector replay,
bounded 2x2 real-distinct np.linalg.eigvals output replay, bounded 2x2
real-simple np.linalg.eig eigenvalue/eigenvector replay, bounded static rank-2
distinct-positive np.linalg.svd(..., compute_uv=False) singular-value
output replay, constant-full-rank rank-1/Nx2/2xN np.linalg.pinv output
replay, static source-map
index_map:<sN|cVALUE,...> indexing, inert source alias_analysis:assignment_binding
and expression_rebinding_alias metadata attached by local static-gather temporaries, and executed runtime branch metadata when
matched by runtime phi provenance. Legacy opcode-free metadata, unsafe aliases,
mutation, non-lowered dynamic indexing semantics, dynamic axes, dynamic trapezoid-grid metadata, dynamic q/method
metadata, dynamic ddof/correction metadata, zero-variance std gradients,
remaining broad linalg/spectral adjoints beyond the bounded 2x2 eigvalsh,
eigh, eigvals, real-simple eig, static vector- and matrix-RHS solve, static integer matrix_power, static rank-2 SVD singular-value,
rank-1/Nx2/2xN pinv, diag, and on-diagonal diagflat boundaries,
unsafe source-level aliases and non-executed branch semantics, general Program AD execution,
LLVM/JIT lowering, hardware execution, provider execution, and performance
promotion remain fail-closed.
Native LLVM/JIT promotion is also guarded by LLVMJITClaimGate: the committed
llvm-jit-claim-gate-20260704 artifact attaches bounded executable lowering
and correctness evidence but remains blocked until crash-safety tests, isolated
benchmark artifact IDs, rollback policy, and fallback policy are attached.
Program AD static alias-lattice reports preserve unknown alias-edge provenance
as ProgramADUnknownAliasEdge rows and attach the unknown_alias_edge_kinds
blocker before readiness promotion. This is still metadata-only fail-closed
evidence, not unknown dynamic alias promotion, Rust replay support for unknown
alias kinds, executable compiler lowering, or a performance claim.
Static alias-lattice reports also expose parseable source-to-view aliases as
ProgramADViewAliasProvenance rows with operation, view id, output index,
source, target, and version metadata. Malformed view_alias markers are
reported through malformed_view_alias_edges and block readiness instead of
being inferred from raw member strings or promoted to compiler alias semantics.
Parseable local list construction, local-name rebinding, and indexed
list-mutation source aliases are retained as ProgramADListAliasProvenance
rows with list name, target kind, source, target, and version metadata.
Malformed list_alias markers are reported through
malformed_list_alias_edges and block readiness instead of being promoted from
raw member strings.
Parseable loop-carried scalar state aliases are retained as
ProgramADLoopCarriedStateProvenance rows with state name, entry label,
backedge label, source, target, and version metadata. Malformed
loop_carried_state markers are reported through
malformed_loop_carried_state_edges and block readiness instead of being
promoted from raw member strings or loop phi labels.
Parseable local-name and expression rebinding aliases are retained as
ProgramADRebindingAliasProvenance rows with binding kind, local source name
or expression line/label, target name, source, target, and version metadata.
Malformed local_rebinding_alias and expression_rebinding_alias markers are
reported through malformed_rebinding_alias_edges and block readiness instead
of being inferred from raw member strings or promoted to compiler alias
semantics.
Parseable branch-local control-path aliases are retained as
ProgramADControlPathAliasProvenance rows with source branch arm, target
label, source line, and version metadata. Malformed control_path_alias
markers are reported through malformed_control_path_alias_edges and block
readiness alongside the non-executed branch-semantics blocker.
Registered deterministic Phase-QNode JAX value routes now also expose
AOT/export diagnostics through jax_phase_qnode_aot_export_audit(...). The
audit records local jax.jit(...).lower(...), StableHLO/compiler metadata,
jax.export serialization, and deserialized replay value agreement, but it is
not exported VJP support, persistent cross-platform execution, provider,
hardware, isolated benchmark, or performance promotion evidence.
Python integration is isolated in
scpn_quantum_control.program_ad_rust_bridge, which owns the typed wrapper
dataclasses, native-extension fail-closed handling, JSON payload validation,
registry metadata mirror result, NumPy input normalisation, bounded
static np.diag gather/scatter replay, static on-diagonal np.diagflat
construction replay, static vector- and matrix-RHS np.linalg.solve output replay, static integer-exponent np.linalg.matrix_power output replay,
fixed-signature np.linalg.multi_dot linalg-array output replay, bounded
2x2 distinct symmetric np.linalg.eigvalsh spectral replay, bounded 2x2
distinct symmetric np.linalg.eigh eigenvalue and nonzero-offdiagonal
eigenvector replay, bounded 2x2 real-distinct np.linalg.eigvals
spectral replay, and bounded 2x2 real-simple np.linalg.eig eigenvalue/eigenvector
replay, plus bounded 2x2 distinct-positive
np.linalg.svd(..., compute_uv=False) singular-value replay and
constant-full-rank rank-1/Nx2/2xN np.linalg.pinv output replay. The legacy
differentiable-programming facade continues to re-export those bridge symbols.
Python compiler interchange lowers captured program_ad_effect_ir.v1 records
into deterministic scpn_diff.program_ad_ssa,
scpn_diff.program_ad_effect, scpn_diff.program_ad_alias_edge,
scpn_diff.program_ad_control_region, and scpn_diff.program_ad_phi
operations through compile_whole_program_ad_trace_to_mlir(...). The
program_ad_mlir_interchange_contracts row validates that metadata lowering as
local conformance only; executable Rust, LLVM, JIT, provider, hardware, and
performance promotion remain blocked.
The differentiable Phase-QNode lane is a promotion candidate until the committed claim
ledger, isolated CI benchmark artefact, and external comparison rows all pass.
The ledger is committed at
data/differentiable_phase_qnode/claim_ledger.json with a reviewer summary in
data/differentiable_phase_qnode/claim_ledger.md.
load_differentiable_claim_ledger(...) validates the canonical schema,
artefact identity, licence metadata, non-empty unique claim identities, exact
runtime field types, and non-blank unique surface/evidence collections. It does
not coerce arbitrary JSON values into strings. A missing legacy
benchmark_artifact_ids field falls back to the evidence IDs, while an
explicit empty benchmark list stays empty so promotion validation can reject
it. When an artefact-status mapping is supplied, even an empty mapping is
authoritative: every promoted evidence and benchmark ID must map to passed.
The public-safe wording table is generated from that ledger at
data/differentiable_phase_qnode/public_claim_table_20260616.md. Use
render_public_claim_table(...) and validate_public_claim_table(...) when a
release note, README, package description, or reviewer response needs
claim-boundary language. The renderers live in the focused
differentiable_claim_rendering satellite; table cells and code spans contain
embedded line breaks, pipes, and backticks, and committed ledger, public-table,
and support-alignment Markdown must reproduce byte-for-byte. Public promotional
wording remains blocked unless every row is promoted, and checks are
case-insensitive without a candidate-marker bypass. The claim rows carry the
satellite source and test paths into the capability manifest, Rust/Python
inventory, architecture map, support-alignment evidence, and external checksum
bundle. Every current row is a bounded candidate, so the table blocks hardware,
provider, QPU, GPU, production-performance, and isolated_affinity claims until
promoted evidence exists.
run_differentiable_baseline_scorecard() adds the category scorecard that keeps
the promotion discussion tied to named external baselines: JAX transforms,
PyTorch autograd/compile, PennyLane QNode/device/plugin breadth, Qiskit Runtime
provider gradients, Catalyst compiler workflows, Enzyme compiler AD, Rust
Program AD, provider/hardware gradients, benchmark promotion, docs/API
maintainability, and adoption/licensing. The committed artefacts live at
data/differentiable_phase_qnode/differentiable_baseline_scorecard_20260620.json
and data/differentiable_phase_qnode/differentiable_baseline_scorecard_20260620.md.
The external-comparison evidence now attaches a dedicated Catalyst
compiler-workflow profile to Catalyst rows so qjit/MLIR/QIR workflow scope,
compiled differentiation, control-flow coverage, finite-shot limits, and
unsupported provider routes are recorded before any Catalyst parity wording is
considered.
Every current category remains behind_baseline; the scorecard is governance
evidence only and does not promote performance, provider, QPU, GPU, hardware,
or isolated_affinity claims.
audit_differentiable_promotion_language() is the release-blocking
public-language gate for that scorecard. It scans the public differentiable
surfaces used by CI and fails when unbounded category-leadership, exceedance,
production-performance, or promotion-ready wording appears without a matching
ready scorecard row and promoted claim-ledger rows. Bounded candidate-status
wording remains allowed so roadmap and reviewer documentation can describe
the governance lane without upgrading claims.
run_competitive_baseline_refresh() records the official upstream source
streams used to refresh that scorecard. The committed artefacts live at
data/differentiable_phase_qnode/differentiable_competitive_baseline_refresh_20260627.json
and
data/differentiable_phase_qnode/differentiable_competitive_baseline_refresh_20260627.md.
audit_competitive_baseline_promotion_gate() validates the refresh window and
combines it with the public-language audit, so promotion wording remains blocked
unless fresh upstream baseline evidence, ready scorecard rows, and promoted
claim-ledger rows all agree.
run_differentiable_rust_python_inventory() adds the rustification surface
inventory required before broad Rust migration. It classifies each current
differentiable route as rust_backed, python_reference, metadata_only,
compiler_native_not_rust, provider_blocked, hardware_blocked, or
deprecate_before_promotion; records owner modules, tests, docs, benchmark
status, mypy targets, docstring status, Rust parity, and polyglot status; and
keeps every row non-promotional until matching claim-ledger, benchmark, and
provider/hardware evidence exists. The committed artefacts live at
data/differentiable_phase_qnode/differentiable_rust_python_inventory_20260620.json
and
data/differentiable_phase_qnode/differentiable_rust_python_inventory_20260620.md.
The module-specific test reproduces both files byte-for-byte from the public
inventory serialization and Markdown renderer. The external-validation
manifest gate separately verifies their committed SHA-256 digests and sizes.
Call validate_differentiable_rust_python_inventory() before treating the map
as governance evidence. It fails closed on unknown runtime status values,
blank blockers, stale schema or aggregate counts, duplicate surface IDs,
classification-count drift, unknown claim-ledger rows, absent evidence paths,
unexplained provider/hardware blocks, and Rust-backed parity-complete candidates
whose benchmark evidence remains not_run. This validation does not upgrade a
row or promote Rust, polyglot, provider, hardware, or benchmark claims.
The Rust Program AD inventory row includes a dedicated deterministic
panic-boundary corpus that exercises malformed or unsupported IR through the
public Rust forward and value+gradient replay APIs. That corpus is fail-closed
reliability evidence only. The companion program_ad_ir cargo-fuzz target
build-checks the same public parser, forward replay, and value+gradient replay
boundary with seed inputs under
scpn_quantum_engine/fuzz/corpus/program_ad_ir/; sustained fuzz campaign
artifacts, Miri, sanitizer, executable registry, LLVM/JIT, provider, hardware,
and performance promotion remain blocked until separate artifacts exist.
run_differentiable_architecture_map() connects that inventory to the
scorecard as six Rustification routing layers: public API facade, QNode
framework bridges, Program AD core, compiler/native execution, provider and
hardware boundary, and benchmark/claim governance. The committed artefacts live
at data/differentiable_phase_qnode/differentiable_architecture_map_20260627.json
and data/differentiable_phase_qnode/differentiable_architecture_map_20260627.md.
The map fails closed unless its schema, artifact identity, claim boundary, six
ordered layer IDs, counts, and readiness agree. Validation first checks the
upstream inventory and scorecard, then requires every inventory surface and
every scorecard category to be routed, requires each layer to match the routing
derived from the current inventory, and rejects missing, absolute, or
parent-traversing source/test/docs paths. Layer construction also rejects blank
or duplicate routing entries and blank blockers. A byte-parity regression locks
the committed JSON and Markdown to the public serializer and renderer; the
external-validation bundle pins their checksums. The map remains routing
evidence only and does not promote Rust, LLVM/JIT, provider, hardware, GPU,
performance, or isolated_affinity claims.
The current public technical report is
Differentiable External-Validation Technical Report.
It summarizes the comparison package, provider-family status, reproducibility
artefacts, and promotion blockers without upgrading any row beyond bounded
candidate evidence.
validate_differentiable_support_surface_alignment() checks that each ledger
row still points to existing implementation, test, and documentation surfaces
and that source/test/docs paths are present in the generated capability
manifest. The manifest must be a contained top-level JSON object; absolute,
parent-traversing, ambiguous, Windows-style, and symlink-escaping claim paths
fail before dereference. This is a consistency gate only; it does not promote
hardware, provider, or performance claims. The committed rerun artefacts live at
data/differentiable_phase_qnode/differentiable_support_surface_alignment_20260627.json
and
data/differentiable_phase_qnode/differentiable_support_surface_alignment_20260627.md;
load_differentiable_support_surface_alignment() reloads the JSON evidence and
render_differentiable_support_surface_alignment_markdown() renders the
reviewer summary.
run_differentiable_hardening_slice_gate(...) records the required closeout
checklist for each differentiable hardening slice: focused Ruff formatting and
linting, mypy over changed source targets, module-specific pytest targets,
the repository test-quality audit, claim-ledger validation, and benchmark
classification smoke cases. It also verifies that GitHub-hosted runners remain
functional_non_isolated, incomplete isolated-runner metadata remains a
hard_gap, complete self-hosted isolated metadata is the only
isolated_affinity path, and silent accelerator fallback remains a hard gap.
The gate is planning and classification evidence only; it does not run shell
commands or promote benchmark artefacts.
CI, local preflight, and the pre-push hook enforce a separate strict-mypy
ratchet over the differentiable API, claim-ledger, benchmark-evidence,
hardening-gate, QNN/QGNN/QSNN training and evidence satellites,
objective/domain evidence, optimizer-baseline, backend selection, parameter-shift/VQE foundations,
structured-ansatz/methodology/benchmark/Kuramoto/UPDE solver foundations,
typed trajectory-result containers,
layered ADAPT-VQE,
Trotter-error bounds,
framework-overlay, external-validation, Phase-QNode, gradient, provider/hardware-gradient safety, framework-bridge,
transform-nesting, external-comparison, XY compiler, and PennyLane import
modules that have been closed module-by-module. That ratchet is
module-specific governance; repository-wide mypy --strict remains open until
the rest of the codebase is migrated.
run_differentiable_module_hardening_audit() discovers the differentiable
module promotion scope from the committed patterns, compares it with the
registered hardening map, and verifies that every module has module-specific
tests plus declared fail-closed diagnostic surfaces. This closes the local
module-inventory portion of the hardening lane. CI, local preflight, and the
pre-push hook also enforce a scoped NumPy-style Ruff docstring ratchet for this
audit module, run_differentiable_hardening_slice_gate(...), and their
module-specific tests. Formal proof, provider execution, hardware execution,
isolated benchmark promotion, and repository-wide docstring enforcement remain
separate evidence gates.
Optional framework parity uses an explicit CPU-only overlay instead of the
repository jax extra, because that extra resolves to jax[cuda12].
run_phase_qnode_framework_parity_suite() now exposes explicit scenarios:
the default single_qubit_ry_rx_pauli_z compatibility row and
registered_two_qubit_entangling_statevector, which executes a registered
two-qubit entangling Phase-QNode statevector tensor path across installed JAX,
PyTorch, TensorFlow, and PennyLane backends. Both routes remain local parity
evidence only; they do not promote provider execution, finite-shot sampling,
hardware gradients, or unrestricted simulator-autodiff claims.
PYTHONPATH=src:. python scripts/install_differentiable_framework_overlay.py \
--overlay-path "${XDG_CACHE_HOME:-$HOME/.cache}/scpn-qc-framework-site-py312" \
--manifest-path /tmp/scpn-qc-framework-overlay.json \
--installThe generated manifest prints the exact PYTHONPATH for parity runs, records
package versions when verification succeeds, and lists only CPU wheels:
jax[cpu], torch, tensorflow-cpu, and pennylane. The installer rejects
relative overlay targets, filesystem-root targets, and existing non-directory
targets before invoking pip; use an absolute directory path on the working
ext4 disk for reproducible framework-overlay evidence.
The external-validation package also has an exact environment lock manifest at
data/differentiable_phase_qnode/external_validation_environment_lock_20260616.json
with a reviewer summary at
data/differentiable_phase_qnode/external_validation_environment_lock_20260616.md.
build_external_validation_environment_lock() records SHA-256 digests, byte
sizes, line counts, and pinned-package counts for the runtime, development,
Python 3.11-3.13 CI, CPU framework overlay, and Python 3.9 Enzyme runner
lockfiles. validate_external_validation_environment_lock() rechecks those
digests against the current checkout. This is reproducibility evidence only:
the artefact remains functional_non_isolated and does not promote hardware,
provider, GPU, QPU, production-performance, or isolated_affinity benchmark
claims.
run_differentiable_dependency_environment_map() groups that lock evidence into
runtime, development, CI Python matrix, CPU framework overlay, and Enzyme runner
profiles. The generated map is committed at
data/differentiable_phase_qnode/differentiable_dependency_environment_map_20260627.json
with a reviewer summary at
data/differentiable_phase_qnode/differentiable_dependency_environment_map_20260627.md.
Call validate_differentiable_dependency_environment_map() before consuming a
map as evidence. It fails closed when the schema, canonical profile order,
aggregate counts, readiness flags, lock membership, filesystem paths, pin
counts, or blocker state disagree with the supplied environment lock. Supplying
an environment_lock to either public function reuses already captured
evidence without rebuilding or upgrading its classification; only the
validator certifies its invariants.
The Enzyme runner remains a hard-gap profile until configured native
Enzyme/LLVM/MLIR runner artefacts pass; the map is dependency provenance only
and does not promote framework parity, Enzyme parity, provider execution,
hardware execution, GPU execution, production-performance, or isolated
benchmark claims.
The reproducible artefact-bundle manifest is committed at
data/differentiable_phase_qnode/external_validation_artifact_bundle_20260616.json
with a reviewer summary at
data/differentiable_phase_qnode/external_validation_artifact_bundle_20260616.md.
build_external_validation_artifact_bundle() records SHA-256 digests for the
claim ledger, public claim table, environment lock, domain dataset closure,
identical-circuit comparison, PyTorch maturity audit, isolated benchmark batch
plan, and local benchmark evidence files.
validate_external_validation_artifact_bundle() rechecks those digests against
the current checkout. The bundle is checksum provenance only and remains
functional_non_isolated.
run_differentiable_isolated_benchmark_plan() produces the reserved-host batch
plan at
data/differentiable_phase_qnode/differentiable_isolated_benchmark_plan_20260627.json
with a reviewer summary at
data/differentiable_phase_qnode/differentiable_isolated_benchmark_plan_20260627.md.
The plan covers the current local benchmark bundle, Phase-QNode affinity row,
identical-circuit comparison, domain dataset closure, PyTorch maturity audit,
Enzyme/MLIR maturity audit, and the compiler-promotion batch gate. Each row
records the required self-hosted, linux, and isolated-benchmark runner
labels, a taskset plus chrt rerun command, expected output paths, source
classifications, and host blockers. The compiler row now calls
scripts/run_compiler_isolated_benchmark_evidence.py, which wraps native
whole-program AD execution evidence with BenchmarkIsolationMetadata and writes
compiler_isolated_benchmark_evidence_*.json/.md. Those files become
attachable only when the reserved host reports isolated_affinity metadata and
the embedded native compiler evidence executes beyond scalar replay within its
gradient tolerance. The compiler row remains blocked until those reserved-host
artifact IDs are attached. The current workstation is not promoted by this plan:
high observed load and non-reserved affinity keep promotion_ready=False, and
the committed source artefacts remain functional_non_isolated or hard_gap
until a validated isolated runner emits isolated_affinity outputs.
CI, local preflight, and the pre-push hook now include the external-validation module and its module-specific tests in the scoped NumPy-style Ruff docstring ratchet alongside the module-hardening audit and hardening-slice gate surfaces. That ratchet covers the manifest builders, checksum validators, renderer contracts, and fail-closed drift branches while repository-wide docstring enforcement remains open rollout debt.
The operator-intercepted whole-program trace-value runtime has a separate
permanent quality gate. CI and the default local gate share the same ordered
source/test cohort for strict MyPy and NumPy docstrings, then run one explicit
58-file Program-AD/whole-program trace cohort with branch telemetry and require
exact 100% statement and branch coverage for
whole_program_trace_values.py. The responsibility-specific protocol,
operator, selection, signal, linear-algebra, and shape tests are individually
below the module-size threshold. The gate validates Python trace dispatch and
compact IR generation; it does not relabel the existing bounded Rust replay or
LLVM lowering surfaces, and it does not create a new benchmark or performance
claim.
Differentiable CI reproducibility is split into explicit sparse, full, optional
GPU-contract, scheduled metadata, and isolated-runner lanes. The sparse and full
CPU profiles run across Python 3.11, 3.12, and 3.13 using the pinned
per-version Linux requirement locks. Full profiles build the CPU-only framework
overlay for jax[cpu], torch, tensorflow-cpu, and pennylane; sparse
profiles keep the baseline dependency surface. The same workflow runs the
module-specific test-quality audit after the differentiable parity tests, so
new differentiable tests cannot be hidden in a generic coverage bucket. The
manual optional GPU lane runs GPU request/fail-closed contract tests on a
GitHub-hosted runner and uploads a functional_non_isolated JSON record; it is
not live GPU, provider, QPU, or production-performance evidence.
Benchmark artefacts written by
scripts/run_differentiable_benchmark_evidence.py are CI evidence only.
External comparison artefacts written by
write_differentiable_external_comparison(...) record row payloads,
dependency versions, toolchain metadata, failure classes, and local Python/host
metadata, but they are still classified as functional_non_isolated. Every row
also records closure_status and closure_reason: passing rows are
implemented, dependency or runner gaps remain implementation_path, and
unsupported batching, transform, dtype, or device routes are
permanent_boundary rows with the boundary reason copied into the artefact.
The artefact summary includes hard_gap_closure_counts, so no hard-gap row can
land without a recorded implementation path or permanent-boundary reason.
The benchmark evidence script writes diff-qnode-external-comparison.json
beside the benchmark bundle and records that artefact's ID in the bundle, so CI
artifacts retain the complete comparison evidence chain without upgrading local
correctness rows into performance claims.
GitHub-hosted runners are classified as functional_non_isolated; production
performance wording requires a self-hosted runner labelled
isolated-benchmark, explicit CPU affinity, observed process affinity that
matches the requested CPU set, host-load context, governor or frequency
context, and no concurrent heavy jobs. The remote CI job is the benchmark gate:
the repository may not promote the claim unless that job uploads an artefact
classified as isolated_affinity. Unconfigured Enzyme and Catalyst tooling is
recorded as dependency_missing hard-gap evidence, not a hidden success. When
SCPN_ENZYME_RUNNER or SCPN_CATALYST_RUNNER is configured with the matching
tooling present, it must be an absolute path to an executable file. The external
comparison row sends a strict JSON request, enforces a timeout, records runner
toolchain metadata, and accepts success only when value and gradient match the
SCPN analytic reference. Invalid runner paths stay dependency_missing hard
gaps with explicit metadata rather than being executed. Accelerator benchmark
claims are also fail-closed: the benchmark evidence bundle always records
explicit accelerator metadata. CPU-only runs are labelled CPU-only; CUDA or ROCm
requested through
SCPN_BENCH_ACCELERATOR_BACKEND must expose matching visible-device metadata
(SCPN_BENCH_ACCELERATOR_DEVICE_IDS, CUDA_VISIBLE_DEVICES,
ROCR_VISIBLE_DEVICES, HIP_VISIBLE_DEVICES, or JAX CUDA device discovery)
or the artefact is classified as hard_gap with
silent_accelerator_fallback.
Self-hosted runner preparation is explicit:
PYTHONPATH=src:. python tools/setup_isolated_benchmark_runner.py \
--repo anulum/scpn-quantum-controlThe helper prints the labels, runner directory, runner version, and download
URL without mutating the host. The installer validates the repository slug,
runner label tokens, dotted numeric runner version, HTTPS scheme, GitHub host,
and actions/runner release path before any archive download. Add --install
only on the reserved Linux x64 benchmark host. A claim is still not promoted
until the CI artefact itself reports isolated_affinity. If the repository has no registered
self-hosted runner with the isolated-benchmark label, the benchmark gate is
not executable and the claim remains unpromoted.
| Goal | Recommended path |
|---|---|
| Train a small VQE objective | phase.param_shift -> Quantum Gradients -> Variational Methods |
| Train and verify a bounded QNN classifier | phase.qnn_training -> train_parameter_shift_qnn_classifier(...) -> verify_parameter_shift_qnn_classifier_gradient(...) -> estimate_parameter_shift_qnn_finite_shot_gradient(...) -> run_parameter_shift_qnn_conformance_suite(...) -> run_parameter_shift_qnn_convergence_suite(...) -> run_parameter_shift_qnn_multi_seed_convergence_suite(...) -> run_parameter_shift_qnn_loss_landscape_suite(...) -> run_parameter_shift_qnn_finite_shot_convergence_suite(...) -> run_parameter_shift_qnn_framework_agreement_suite(...).conformance_table for same-circuit SCPN/JAX/PyTorch/TensorFlow/PennyLane/Qiskit exact-state rows and blocked finite-shot/provider/hardware rows -> run_torch_autograd_function_audit(...) for bounded custom-autograd backward and SGD integration -> run_torch_module_state_audit(...) for bounded PyTorch module/optimizer state replay -> run_torch_module_device_state_audit(...) for bounded PyTorch CPU/CUDA-smoke-gated state replay -> run_torch_module_checkpoint_audit(...) for bounded PyTorch weights-only CPU checkpoint replay -> run_torch_long_lived_checkpoint_matrix(...) for bounded PyTorch checkpoint matrix diagnostics -> run_torch_training_loop_matrix(...) for bounded PyTorch training-loop matrix diagnostics -> run_torch_module_export_audit(...) for bounded PyTorch torch.export save/load value replay -> run_torch_export_shape_matrix(...) for bounded PyTorch static export-shape matrix diagnostics -> run_torch_dynamic_shape_export_audit(...) for bounded PyTorch dynamic-batch export replay -> run_torch_aot_autograd_export_audit(...) for bounded PyTorch AOTAutograd FX gradient replay -> run_parameter_shift_qnn_optimizer_benchmark_suite(...) -> Quantum Gradients |
| Execute and compare a registered Phase-QNode | phase.qnode_circuit -> execute_phase_qnode_circuit(...) -> parameter_shift_phase_qnode_gradient(...) -> run_phase_qnode_framework_parity_suite() -> jax_phase_qnode_value_and_grad(...) -> jax_phase_qnode_native_transform_audit(...) / jax_phase_qnode_pytree_transform_audit(...) / jax_phase_qnode_sharding_transform_audit(...) / torch_phase_qnode_value_and_grad(...) / torch_phase_qnode_transform_audit(...) / torch_phase_qnode_compile_boundary_audit(...) / run_torch_ecosystem_maturity_audit(...) -> lower_phase_qnode_circuit_to_mlir(...) -> compile_phase_qnode_circuit_to_mlir_runtime(...) |
| Inspect compiler-backed AD | differentiable_compile_report(...) -> Quickstart differentiable primitive path -> Differentiable API |
| Follow the complete differentiable tutorial | examples/23_differentiable_api_workflow.py, examples/24_differentiable_benchmark_reproduction.py -> Differentiable Tutorials |
| Build a custom primitive | CustomDerivativeRule -> CustomDerivativeRegistry -> primitive contract tests |
| Decide whether a gradient stack can run | explain_differentiability(...), differentiable_support_report(...), run_transform_algebra_audit(...), plan_gradient_support(...), plan_gradient_transform_nesting(...), plan_quantum_gradient_backend(...), run_phase_qnode_tape_readiness_suite(), run_provider_gradient_readiness_audit(...), run_hardware_gradient_policy_readiness_suite(), run_provider_hardware_gradient_preparation_audit(), and run_differentiable_readiness_audit() |
| Prepare ML-framework integration | Follow Differentiable Roadmap until adapter tests land |
A differentiable workflow should be treated as production-ready only when all of these checks are true:
| Check | Required evidence |
|---|---|
| Mathematical derivative contract | Parameter-shift, analytic derivative, adjoint replay, or compiler-AD rule is named and registered. |
| Shape and dtype contract | Primitive registry or support matrix admits the target tensor rank, dtype, backend, and static arguments. |
| Verification | Finite-difference, analytic, or independent framework agreement is recorded for a small representative case. |
| Optimiser behaviour | Descent or convergence diagnostics exist for the target objective class. |
| Backend policy | Simulator, finite-shot simulator, hardware, or adapter route declares shot, variance, budget, evidence-ID, ticket, and blocked-state policy. |
| Documentation | Unsupported or unsuitable scenarios are listed with alternatives and no silent fallback. |
This is the current standard for claiming enterprise-grade differentiable behaviour in this repository. Anything below that bar is documented as staged, experimental, or unsupported.
explain_differentiability(...) is the first inspection call for unsupported
or ambiguous routes. It returns a fail-closed diagnostic report with the exact
blocked reasons, suggested alternatives, bounded framework dependency rows,
device capability rows, backend planning rows, and the underlying support-plan
payload. It is intentionally non-executing planning evidence: no objective,
provider callback, hardware job, or performance benchmark is run by the
diagnostic.
- Fail closed when a derivative mode is unsupported.
- Separate exact, approximate, finite-shot, and roadmap gradient modes.
- Do not silently treat analytic classical penalties as parameter-shift quantum terms.
- Keep shape, dtype, backend, and primitive support inspectable.
- Treat PennyLane finite-shot metadata as non-coercive: analytic mode is
shots=None, and finite-shot mode requires an explicit positive integer before plugin/device dispatch. - Constrain generated PennyLane QNode exports to canonical interfaces (
auto,autograd,jax,tf,torch) and documented QNode diff methods (adjoint,backprop,best,device,finite-diff,hadamard,parameter-shift,spsa) before device/QNode construction. - Require PennyLane provider-plugin artefact
execution_modevalues to be provider-scoped while still rejecting hardware/QPU execution modes. Provider execution artefacts must also carry explicit PennyLaneinterfaceanddiff_methodmetadata, canonical interface values (auto,autograd,jax,tf,torch) and documented QNode diff methods (adjoint,backprop,best,device,finite-diff,hadamard,parameter-shift,spsa) rather than undocumented aliases, plusshot_policy="analytic"withshots=Noneorshot_policy="finite_shot"with a positive shot count, before the provider route can pass. - Keep PennyLane plugin-matrix route evidence canonical: statuses are
passed,blocked, orfailed, and route metadata is control-clean. - Pair PennyLane provider-gradient parity evidence to the same provider execution artefact, circuit fingerprint, backend, PennyLane interface, diff method, and shot policy before marking provider-gradient parity as passed.
- Require ticketed live hardware, allowlist, shot-budget, raw-count, calibration digest, calibration capture/expiry timestamps, and metadata evidence before PennyLane hardware-plugin execution can pass. Reject stale calibration at the review cutoff and keep promotion blocked until isolated benchmark evidence exists.
- Use
PennyLaneProviderEvidenceBundlewhen reviewing PennyLane provider execution, provider-gradient parity, and optional hardware evidence as one attachment. Bundles must cite UTC capture and expiry timestamps, cannot be mixed with individual provider artefacts, and fail closed when the expiry is stale for the review cutoff. - Split Qiskit Runtime evidence into no-submit primitive metadata and live QPU EstimatorV2/SamplerV2 artefacts; live QPU evidence must carry ticket, backend-allowlist, shot-budget, ISA/transpiled-circuit, Runtime result, and metadata digests before the live-ticket gate can pass. Build those live-QPU artefacts from captured Runtime metadata with the no-submit Qiskit helper; raw-count replay and calibration/statevector comparison artefacts must be attached to the same Runtime QPU provider/backend/circuit/live-ticket chain before their gates can pass. Use the provider evidence bundle when attaching Runtime QPU, raw-count, calibration, and isolated benchmark artefacts together; the bundle must include UTC capture and expiry timestamps, and the audit rejects stale bundles before readiness can pass. Omitting the isolated benchmark ID keeps benchmark promotion blocked. Attach provider-gradient workflow artefacts for the complete parameter-shift, finite-difference, LCU, SPSA, QGT, and QFI method set before the Qiskit maturity audit can pass the provider-gradient workflow gate.
- Compare gradients against finite differences, analytic references, and cross-framework references where practical.
- Document failed or unsuitable scenarios because they are research evidence.
The next differentiable-programming implementation rounds should prioritise:
- larger registered Phase-QNode parity families beyond the current arbitrary-depth registered local subset with controlled-gate decomposition coverage;
- inverse-coupling differentiable objectives that extend the current bounded ground-state optimizer, open-system objective, and phase-QNN convergence evidence;
- native framework agreement beyond the registered Phase-QNode parity family, registered JAX/PyTorch statevector lowering, and bounded QNN records;
- broader PennyLane adapter round-trip tests beyond caller-supplied framework-gradient agreement checks;
- broader QNN/QGNN/QSNN convergence notebooks beyond the bounded local phase-QNN conformance, deterministic convergence, deterministic multi-seed, bounded loss-landscape, seeded finite-shot, named optimizer-baseline suites, QSNN tests, and registered medium evidence suite;
- public tutorials for Kuramoto-XY VQE gradients and coupling learning beyond the current unified differentiable API tutorial;
- executable implementations for still-blocked framework-native nested routes where the physics contract is clear; native vector-output Jacobian, provider-callback QNode transforms, and manual
vmap(grad)now have bounded local evidence.
Unsupported does not mean ignored. Current public boundaries include:
- arbitrary Python/NumPy program AD beyond supported trace operations;
- full native compiler AD for every MLIR/LLVM/JIT path;
- complete gradient tape semantics beyond supported phase parameter-shift and QNode-style phase records;
- first-path namespace routes outside
scpn_quantum_control.diffandscpn.diffwhen they bypassDifferentiableCircuitDiagnostics,ShotPolicy, and explicit fail-closed JIT explanation metadata; - public JAX/PyTorch/TensorFlow adapters beyond the documented bounded-model and deterministic registered statevector routes;
- hardware gradient jobs without hardware-gradient policy approval, required evidence IDs, and live-execution ticketing where applicable;
- provider callbacks that omit finite-shot variance or shifted-sample provenance;
- unsupported gate, observable, transform, adapter, or backend combinations returned by
plan_gradient_support(...); - unsupported transform nesting returned by
plan_gradient_transform_nesting(...); - arbitrary quantum neural architectures beyond the bounded local phase-QNN classifier, its QNN-specific gradient verifier, deterministic multi-seed envelope, bounded loss-landscape scans, finite-shot simulator evidence, conformance, convergence, framework-agreement, and named optimizer-baseline suites, and declared QSNN training routes;
- gates without registered generator spectra;
- dynamic topology changes that invalidate parameter indexing;
- static dense native determinant traces at
20x20and wider until a stronger determinant-partial helper is verified; - wide native quotient-linalg traces beyond the documented support profile.
See Differentiable Roadmap for the staged closure plan.