API reference¶
Everything below imports from deltakit_maestro. Most code needs only
MaestroBackend; the Guide explains how it runs each circuit.
Backend¶
- class MaestroBackend(simulator_type=maestro.SimulatorType.QCSim, simulation_type=None, max_bond_dimension=32, **config)¶
Maestro simulator backend for Deltakit circuits.
- Parameters:
simulator_type (maestro.SimulatorType) – Maestro engine;
SimulatorType.Gpufor GPU.simulation_type (maestro.SimulationType | None) –
Stabilizer,MatrixProductState,Statevector,TensorNetwork, …None(default) picks per run:Stabilizerunless the run has coherent noise, thenMatrixProductState.Stabilizersamples Pauli noise on Pauli frames;T1decay, which is not a Pauli channel, it runs shot by shot. Any other value runs everything with that type.max_bond_dimension (int) – MPS/TTN bond dimension χ.
**config – Further
maestro.SimulatorConfigfields, exceptseed: pass that tosimulateorcompile_sampler, since undersinter.collectevery worker would draw the same shots.fixed_backenddefaults toTrue, so the simulation type above is the one that runs;Falselets Maestro replace it, e.g. sample a Clifford circuit on Pauli frames instead of an MPS.
Noise keyword arguments (
p_1q,p_2q,readout_error,t1,coherent) on the methods below override or extend the rates read from the circuit; seebuild_noise_model.- simulate(circuit, shots, noise_type='pauli', seed=None, **noise)¶
Run
shotsand return raw measurements plus detection events.- Return type:
- compile_sampler(circuit, noise_type='pauli', decoder='pymatching', seed=None, **noise)¶
MaestroCompiledSamplerfor measurement or detection-event sampling.decoderis compiled against the task’s DEM and used by.sample();.sample_detection_events()and.sample_measurements()ignore it. Passdecoder='vacuous'(orNone) for undecoded logical error statistics. Shots come back in random order, so any slice of them is a fair sample.- Return type:
- as_sinter_task(circuit, noise_type='pauli', json_metadata=None, **noise)¶
Circuit + matching DEM as a
sinter.Task.For
'pauli'and'full'without explicit Pauli overrides (p_1q,p_2q,readout_error), the noisy Stim circuit is kept intact so Maestro executes its in-circuit Pauli channels and measurement flips directly. Otherwise the gate noise is stripped (strip_gate_noise) and theNoiseModelreplaces it; idle, reset and measurement noise stay in the circuit. TheNoiseModellayers travel injson_metadata['noise']so the sampler can rebuild them in each worker.The DEM is that of
twirled_circuit, so the decoder knows the noise that is simulated. For'none'there is no such noise and the input circuit’s own DEM is used. The DEM is decomposed into graphlike errors for matching decoders where it can be; where it can’t, as for bivariate bicycle codes, it is left whole for decoders such as BP-OSD.- Return type:
Task
- sinter_decoders(decoder='pymatching')¶
custom_decoders=forsinter.collectoveras_sinter_tasktasks.
- twirled_circuit(circuit, noise_type='pauli', **noise)¶
Stim circuit carrying the Pauli twirl of the noise that is simulated.
Its DEM is the one
as_sinter_taskgives the decoder. Sampling it (simulateorcompile_samplerwith the default'pauli', which runs a circuit’s own noise as it is) gives the Pauli-twirled baseline to compare a coherent run against. For'pauli'without overrides it is the input circuit.- Return type:
Circuit
- config_for(noise_type='pauli', **noise)¶
The
maestro.SimulatorConfiga run with this noise uses.A run is Clifford, so
Stabilizer, unless it has coherent noise. For'coherent'and'full'the strength iscoherent, else the circuit’sp_2q. Without either keyword that rate is unknown here, so it is taken to be nonzero and the answer isMatrixProductState; the sampler itself knows the circuit and decides exactly.The type is pinned (
fixed_backend=True) unlessfixed_backendwas passed to the backend: unpinned, Maestro runs any Clifford circuit on Pauli frames whatever the type, so a noiseless MPS check of χ would never see truncation. A pinnedStabilizerstill uses frames.- Return type:
SimulatorConfig
- class SimulationResult(measurements, detection_events, observable_flips, metadata=<factory>)¶
Output of
MaestroBackend.simulate.- measurements¶
(shots, num_measurements)uint8, Stim record order.- Type:
- detection_events¶
(shots, num_detectors)bool.- Type:
- observable_flips¶
(shots, num_observables)bool.- Type:
- SINTER_DECODER = 'maestro'¶
The decoder name that
MaestroBackend.as_sinter_task()gives its tasks.MaestroBackend.sinter_decoders()maps it to the Maestro sampler.
Noise translation¶
The steps MaestroBackend takes with a noisy circuit, for using them
directly. The guide’s Noise page explains them.
- to_stim(circuit)¶
Deltakit
Circuit(or anything Stim-like) → nativestim.Circuit.- Return type:
Circuit
- noise_params_from_stim(noisy)¶
Read the gate and readout error rates out of a noisy Stim circuit.
The gate rates are those of the depolarizing that
strip_gate_noiseremoves. Warns if the circuit has several rates for one of them, since a single rate replaces them all.
- strip_gate_noise(noisy, readout=False)¶
noisywithout the depolarizing that follows its gates.A
DEPOLARIZE1orDEPOLARIZE2target is gate noise if its qubit’s latest operation was a gate of the same arity that no noise has followed yet. Deltakit puts it after the nextTICK, merged with the idle noise of the other qubits, so the targets of one instruction are split: gate noise goes, idle noise stays. Resets, measurements and every other noise channel stay too. Returns a flattened circuit.- Parameters:
noisy (Circuit) – The Stim circuit.
readout (bool) – Also remove measurement flips
M(p), for when aNoiseModelsupplies the readout error instead.
- Return type:
Circuit
- build_noise_model(circuit, noise_type='pauli', *, p_1q=0.0, p_2q=0.0, readout_error=0.0, t1=0.0, coherent=None)¶
Build a
maestro.NoiseModelforcircuit.- Parameters:
circuit (Circuit) – Stim circuit; supplies the qubit count and the two-qubit gate pairs that carry two-qubit depolarizing.
noise_type (str) – How gate errors are realised.
'pauli': stochastic depolarizing.'coherent': isotropic coherent over-rotations (ε = 2·arcsin√p about a body diagonal after every gate).'full': both.'none': no noise at all.p_1q (float) – Depolarizing probability after single-qubit gates.
p_2q (float) – Two-qubit depolarizing probability after two-qubit gates.
readout_error (float) – Symmetric measurement flip probability.
t1 (float) – Per-gate
T1decay probability γ.DensityMatrixandMatrixProductOperatorapply amplitude damping γ; every other simulation type resets the qubit to|0⟩with probability γ.coherent (float | None) – Infidelity of the coherent over-rotation, applied per qubit after every gate, one- or two-qubit. Defaults to
p_2q.
- Return type:
- pauli_twirl_circuit(circuit, noise_type='pauli', *, p_1q=0.0, p_2q=0.0, readout_error=0.0, t1=0.0, coherent=None, amplitude_damping=False)¶
circuitplus the Pauli twirl ofbuild_noise_model’s layers.Takes the same arguments as
build_noise_modeland places each channel where Maestro injects it: after every gate exceptI, which Maestro runs as an idle. The circuit’s own Stim noise is kept. The twirl is exact for the Pauli layers; the coherent over-rotation twirls toDEPOLARIZE1(coherent).T1decay γ twirls toPAULI_CHANNEL_1(γ/4, γ/4, γ/4), the reset to|0⟩with probability γ that Maestro’s pure-state simulation types run.- Parameters:
amplitude_damping (bool) – Twirl
T1as amplitude damping γ instead, toPAULI_CHANNEL_1(γ/4, γ/4, (1-√(1-γ))²/4), asDensityMatrixandMatrixProductOperatorsimulate it.- Return type:
Circuit
- NOISE_TYPES = ('pauli', 'coherent', 'full', 'none')¶
The values
noise_typetakes.
- NOISE_KEYS = ('p_1q', 'p_2q', 'readout_error', 't1', 'coherent')¶
The noise keywords that override or extend the rates read from a circuit.