quchip.backend.containers¶
Backend-agnostic solver-result and IR-lowering containers.
These frozen/auto dataclasses are the payloads exchanged across the backend
boundary. The engine emits them (or backends produce them) without committing
to any solver’s native storage: a SolverResult holds native states but
exposes a backend-free shape, a PreparedHamiltonian / PreparedBatch
carries whatever RHS the backend’s solver accepts opaquely, and an
EigensystemData defers per-column ket materialization so the dressing /
sweep hot path never pays for allocations it does not use.
Kept separate from quchip.backend.protocol (the Backend ABC) so
the contract and its payloads can evolve independently.
References
Johansson, Nation, Nori — QuTiP 2, Comput. Phys. Commun. 183, 1760 (2012)
Guilmin et al. — dynamiqs: an open-source Python library for GPU-accelerated and differentiable simulation of quantum systems (2024)
Module Attributes
What |
Classes
|
Batched-solve payload whose RHS construction is deferred. |
|
Batched-solve payload with one native RHS per element. |
|
Hermitian eigensystem returned in a single diagonalization call. |
|
Backend-native Hamiltonian produced by |
|
Backend-agnostic container for a single time-evolution solve. |
|
Batched-solve payload with a single natively batched RHS. |
- class quchip.backend.containers.SolverResult(times, states=None, expect=None, final_state=None, stats=<factory>, solver='')[source]¶
Bases:
objectBackend-agnostic container for a single time-evolution solve.
- Parameters:
- times¶
1D array of save times (ns) matching the solver’s
tlist.- Type:
Any
- states¶
Saved states, one per save time, in the backend’s native state type (
Qobj/QArray).Noneifstore_stateswas disabled.- Type:
list[Any] | None
- expect¶
Expectation-value traces.
list[list[float]]indexed bye_ops-then-time, or adictwhen the engine supplied labelled observables (keys are either strings or(drive_label, op)pairs).
- final_state¶
Final state (
states[-1]when states are stored). Useful for multi-segment protocols without retaining full trajectories.- Type:
Any | None
- stats¶
Solver-specific diagnostics (integrator step count, batch index, etc.). Purely informational; no physics depends on it.
- class quchip.backend.containers.PreparedHamiltonian(rhs, metadata=<factory>)[source]¶
Bases:
objectBackend-native Hamiltonian produced by
Backend.prepare_hamiltonian().rhsis whatever the backend’s solver accepts directly — aQobj/QobjEvofor QuTiP, a dynamiqsTimeQArray/ sum of them for dynamiqs.metadatapasses engine-level hints (e.g.spectral_bound_ghzfor integrator step heuristics) through opaquely.
- class quchip.backend.containers.EagerBatch(rhs_list, batch_size, metadata=<factory>, tlist=None)[source]¶
Bases:
objectBatched-solve payload with one native RHS per element.
The default
Backend.solve_batch()dispatches each element’s RHS throughBackend.batched_sesolve()/Backend.batched_mesolve().
- class quchip.backend.containers.VmappedBatch(rhs, batch_size, metadata=<factory>, tlist=None)[source]¶
Bases:
objectBatched-solve payload with a single natively batched RHS.
rhscovers every element at once — the dynamiqs path, where the per-element signals are stacked along a leading batch axis and the solver runs one vmapped call.
- class quchip.backend.containers.DeferredBatch(shared, batch_size, metadata=<factory>, tlist=None)[source]¶
Bases:
objectBatched-solve payload whose RHS construction is deferred.
sharedcarries backend-private state; the producing backend must overrideBackend.solve_batch()to consume it (the QuTiP path — finalQobjEvoassembly happens inside loky workers so main-process overhead stays O(1) in batch size).
- quchip.backend.containers.PreparedBatch: TypeAlias = quchip.backend.containers.EagerBatch | quchip.backend.containers.VmappedBatch | quchip.backend.containers.DeferredBatch¶
What
Backend.prepare_batch()may return — the batching strategy is explicit in the type, andBackend.solve_batch()dispatches on it.
- class quchip.backend.containers.EigensystemData(eigenvalues, eigenvector_matrix, _states_builder=None, _states_cache=None)[source]¶
Bases:
objectHermitian eigensystem returned in a single diagonalization call.
eigenvaluesis ascending.eigenvector_matrixstacks the eigenvectors as columns in the bare-product basis used for the diagonalization. The per-column backend-native kets are exposed lazily via theeigenstatesproperty so the dressing / sweep hot path (which reads onlyeigenvalues+eigenvector_matrix+ labeling) never pays forDbackend-ket allocations and a secondO(D**2)densification it does not use.Backends populate either
_states_builder(a callable that materializes the ket list on demand) or prime_states_cachedirectly (when the diagonalizer already produced the kets, e.g. QuTiP’sQobj.eigenstates).- Parameters:
- property eigenstates: list[Any]¶
Return per-column backend-native eigenstate kets (built on first access).
Memoizes only when the materialized kets are tracer-free: under
jit/grad/vmapthe states carry tracers bound to the current trace, so caching them would let a stale tracer escape into a later trace. Concrete states are cached.