pub struct CoordCircuit { /* private fields */ }Expand description
A quantum circuit whose qubits are addressed by 2-D lattice coordinates rather than dense integer indices.
Operations live in CircuitBody blocks (the entry body plus any bodies
referenced by Op::Repeat), stored flat and referenced by BodyId.
Measurement records are allocated through an internal MeasRegistry, so
every measurement has a stable id independent of qubit index. A
coordinate-to-index layout for the Stim FFI boundary is derived on demand
via Self::build_coord_to_index.
Implementations§
Source§impl CoordCircuit
impl CoordCircuit
Sourcepub fn new() -> CoordCircuit
pub fn new() -> CoordCircuit
Creates an empty circuit with one entry body.
Sourcepub fn qubits(&self) -> HashSet<IVec2, FxBuildHasher>
pub fn qubits(&self) -> HashSet<IVec2, FxBuildHasher>
The set of every qubit coordinate touched by any body or measurement record.
Sourcepub const fn entry_body(&self) -> BodyId
pub const fn entry_body(&self) -> BodyId
The id of the top-level body operations are appended to.
Sourcepub fn set_entry_body(&mut self, body: BodyId) -> Result<(), CircuitError>
pub fn set_entry_body(&mut self, body: BodyId) -> Result<(), CircuitError>
Select an allocated body as the entry without renumbering body ids.
§Errors
Returns CircuitError::InvalidCircuitBody if body is not allocated.
Sourcepub fn entry_top_level_repeats(&self) -> Vec<u32>
pub fn entry_top_level_repeats(&self) -> Vec<u32>
The repetition counts of the top-level Op::Repeats in the entry
body, in order. Used to classify memory-padding templates: a one-round
template has none, a looped template has exactly one.
Sourcepub fn body_count(&self) -> usize
pub fn body_count(&self) -> usize
The number of circuit bodies, including repeat bodies.
Sourcepub fn body(&self, id: BodyId) -> Option<&CircuitBody>
pub fn body(&self, id: BodyId) -> Option<&CircuitBody>
Borrows the body with the given id, or None if it is not allocated.
Sourcepub fn body_mut(&mut self, id: BodyId) -> Option<&mut CircuitBody>
pub fn body_mut(&mut self, id: BodyId) -> Option<&mut CircuitBody>
Mutably borrows the body with the given id, or None if it is not
allocated.
Sourcepub fn meas_registry(&self) -> &MeasRegistry
pub fn meas_registry(&self) -> &MeasRegistry
Borrows the measurement registry backing this circuit’s ids.
Sourcepub fn reserve_measurement_id(&mut self, qubit: IVec2) -> u32
pub fn reserve_measurement_id(&mut self, qubit: IVec2) -> u32
Allocates and returns a fresh measurement id for qubit.
Sourcepub fn remap_measurement_ids(
&mut self,
remap: &HashMap<u32, u32, FxBuildHasher>,
)
pub fn remap_measurement_ids( &mut self, remap: &HashMap<u32, u32, FxBuildHasher>, )
Rewrites every measurement id through remap, in both the registry and
every op that references a measurement. Ids absent from remap are left
unchanged.
Sourcepub fn add_body(&mut self, body: CircuitBody) -> BodyId
pub fn add_body(&mut self, body: CircuitBody) -> BodyId
Sourcepub fn build_coord_to_index(&self) -> HashMap<IVec2, u32, FxBuildHasher>
pub fn build_coord_to_index(&self) -> HashMap<IVec2, u32, FxBuildHasher>
Build a deterministic coord-to-index layout for the Stim FFI boundary. Indices are assigned by sorting coordinates by (x, y).
§Panics
Panics if the qubit-index space is exhausted.
Sourcepub fn num_qubits(&self) -> u32
pub fn num_qubits(&self) -> u32
The number of distinct qubit coordinates in the circuit.
§Panics
Panics if the qubit count exceeds u32::MAX.
Sourcepub fn num_measurements(&self) -> u32
pub fn num_measurements(&self) -> u32
The number of allocated measurement records.
Sourcepub fn push_repeat(&mut self, body: BodyId, repetitions: u32)
pub fn push_repeat(&mut self, body: BodyId, repetitions: u32)
Appends a Op::Repeat of body to the entry body.
Sourcepub fn do_gate(
&mut self,
gate: GateType,
targets: impl IntoIterator<Item = IVec2>,
) -> Result<(), CircuitError>
pub fn do_gate( &mut self, gate: GateType, targets: impl IntoIterator<Item = IVec2>, ) -> Result<(), CircuitError>
Appends a gate acting on targets to the entry body.
Empty targets is a no-op. Two-qubit gates consume targets pairwise.
§Errors
Returns CircuitError::InvalidGateTargetCount if a two-qubit gate is
given an odd number of targets.
Sourcepub fn measure(
&mut self,
basis: PauliBasis,
targets: impl IntoIterator<Item = IVec2>,
) -> Vec<u32>
pub fn measure( &mut self, basis: PauliBasis, targets: impl IntoIterator<Item = IVec2>, ) -> Vec<u32>
Appends a noiseless single-qubit measurement of each target in basis,
returning one freshly allocated measurement id per target (in target
order). crate::NoiseModel::noisy_circuit can add measurement noise.
Empty targets is a no-op returning an empty vector; duplicate targets
each receive a distinct id.
Sourcepub fn measure_pauli_products(
&mut self,
products: impl IntoIterator<Item = PauliMap>,
) -> Result<Vec<u32>, CircuitError>
pub fn measure_pauli_products( &mut self, products: impl IntoIterator<Item = PauliMap>, ) -> Result<Vec<u32>, CircuitError>
Append a multi-Pauli-product measurement (Op::MPP): each product is
measured jointly and produces one record, keyed by the product’s
representative coordinate (see PauliMap::representative_coord) so
records stay consistent across cloning. Empty products are rejected.
§Errors
Returns CircuitError::EmptyPauliProduct without modifying the circuit
if any product is empty.
Sourcepub fn expanded_measurement_columns(
&self,
) -> Result<ExpandedMeasurementColumns, CircuitError>
pub fn expanded_measurement_columns( &self, ) -> Result<ExpandedMeasurementColumns, CircuitError>
The output column each measurement id lands in once every
Op::Repeat is unrolled, together with the total number of records
the unrolled circuit emits.
Backends address measurement records by position, but this circuit
names them by id and hides repetition behind Repeat, so the two
spaces only line up after unrolling. Self::flatten also unrolls,
but it rewrites the circuit and mints fresh ids to do so; a caller that
only wants “which record does this id land in” pays neither cost here.
A measurement inside a loop occurs once per iteration; the column
reported is its last occurrence, matching the latest-occurrence
rule both Self::flatten and the Stim emission frame use, so an id
read from outside a loop resolves to the same record everywhere.
§Errors
Returns CircuitError::InvalidCircuitBody on a dangling or
self-recursive body reference, and
MeasurementFrameError::EmittedMeasurementCountOverflow when the
unrolled circuit would emit more than u32::MAX records, or
MeasurementFrameError::MeasurementCountOutOfRange if one operation
already contains more than u32::MAX records.
§Examples
let qubit = ivec2(0, 0);
let mut circuit = CoordCircuit::new();
let looped = circuit.reserve_measurement_id(qubit);
let body = circuit.add_body(CircuitBody::from_ops(vec![Op::Measure {
basis: PauliBasis::Z,
qubits: vec![qubit],
measurements: vec![looped],
flip_probability: 0.0,
}]));
circuit.push_repeat(body, 3);
let columns = circuit.expanded_measurement_columns()?;
assert_eq!(columns.count(), 3);
assert_eq!(columns.column(looped), Some(2), "the last of three occurrences");Sourcepub fn has_repeats(&self) -> bool
pub fn has_repeats(&self) -> bool
Whether any body contains an Op::Repeat.
Sourcepub fn flatten(&mut self) -> Result<Vec<FlattenEvent>, CircuitError>
pub fn flatten(&mut self) -> Result<Vec<FlattenEvent>, CircuitError>
Unroll every Op::Repeat into a single straight-line entry body,
returning the replay trace side-table owners need to translate
loop-relative annotations (see FlattenEvent).
Measurement-id semantics mirror the emission frame’s
latest-occurrence rule: every unrolled occurrence of a measurement gets
a fresh id except the last, which keeps the original id, so
references from outside the loop (which always meant “the latest
occurrence”) stay valid without any remap. ConditionalPauli
measurement controls are rewritten to the occurrence emitted most
recently before them. Zero-repetition repeats are dropped.
A circuit without repeats is returned untouched with an empty trace.
§Errors
CircuitError::InvalidCircuitBody on a dangling or self-recursive
body reference, CircuitError::FlattenMeasurementIdOverflow when the
unrolled circuit would need more than u32::MAX measurement ids, or
CircuitError::FlattenResourceLimit when expansion exceeds the default
FlattenLimits.
Sourcepub fn flatten_with_limits(
&mut self,
limits: FlattenLimits,
) -> Result<Vec<FlattenEvent>, CircuitError>
pub fn flatten_with_limits( &mut self, limits: FlattenLimits, ) -> Result<Vec<FlattenEvent>, CircuitError>
Self::flatten with an explicit allowance for expanded work.
The shared body DAG is counted before the circuit is changed. Rejected expansions leave both operations and measurement identities untouched.
§Errors
Returns the same body, id-space, and resource errors as Self::flatten.
Sourcepub fn check_flatten_limits(
&self,
limits: FlattenLimits,
) -> Result<usize, CircuitError>
pub fn check_flatten_limits( &self, limits: FlattenLimits, ) -> Result<usize, CircuitError>
Check expansion without changing the circuit and return its work cost. A caller flattening several circuits can charge the returned cost to one shared allowance before materializing any of them.
§Errors
Returns the same body, id-space, and resource errors as Self::flatten.
Sourcepub fn has_moments_conflict(&self) -> bool
pub fn has_moments_conflict(&self) -> bool
Checks if there are any operations that act on the same qubit within the same moment. A repeat does not imply a tick, including between its iterations.
Trait Implementations§
Source§impl Clone for CoordCircuit
impl Clone for CoordCircuit
Source§fn clone(&self) -> CoordCircuit
fn clone(&self) -> CoordCircuit
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more