pub struct DistributedStatevectorBackend { /* private fields */ }distributed only.Expand description
Distributed state vector backend over an Arc-shared DistributedContext.
Implementations§
Source§impl DistributedStatevectorBackend
impl DistributedStatevectorBackend
Sourcepub fn new(context: Arc<DistributedContext>, seed: u64) -> Self
pub fn new(context: Arc<DistributedContext>, seed: u64) -> Self
Create a backend bound to the given rank context and RNG seed.
Sourcepub fn set_relabel(&mut self, enabled: bool)
pub fn set_relabel(&mut self, enabled: bool)
Enable or disable qubit relabeling for this backend instance, overriding
the PRISM_DIST_RELABEL default. With relabeling off, every gate on a
global qubit uses the direct per-gate exchange paths.
Sourcepub fn exchange_messages(&self) -> u64
pub fn exchange_messages(&self) -> u64
Number of sendrecv messages this rank has issued since init.
Cost proxy for this backend. One host cannot measure real network
latency, so routing changes are evaluated against this count. Counts
gate and relabel exchanges; the query paths take &self and cannot
record theirs.
Sourcepub fn exchange_amplitudes(&self) -> u64
pub fn exchange_amplitudes(&self) -> u64
Total amplitudes this rank has sent across all exchanges since init.
Sourcepub fn sample_state_indices(
&mut self,
num_shots: usize,
seed: u64,
) -> Result<Vec<u64>>
pub fn sample_state_indices( &mut self, num_shots: usize, seed: u64, ) -> Result<Vec<u64>>
Sample num_shots computational basis indices in circuit qubit order
without gathering the dense state or probability vector on any rank.
Relabeled qubits are first restored to their circuit positions with bounded exchanges, so each rank owns a contiguous slice in circuit order. Each rank then builds a cumulative distribution for its local slice. One gather shares a single mass value from each rank. Every rank assigns each shot to an owning rank from the same seeded draw stream, so every rank knows the owner sequence. Each owner samples its local distribution for its shots, one variable-count gather concatenates the owned indices in rank order, and each rank scatters them back into shot order. Buffers scale with the rank count and shot count, not the global state size.
Collective: every rank must call this with identical num_shots and
seed. The result is identical on every rank and reproduces the dense
sampling path draw for draw, independent of the rank count, except
when accumulated rounding differences move a draw across an interval
edge in the cumulative distribution.
Trait Implementations§
Source§impl Backend for DistributedStatevectorBackend
impl Backend for DistributedStatevectorBackend
Source§fn init_from_amplitudes(
&mut self,
amplitudes: Vec<Complex64>,
num_classical_bits: usize,
) -> Result<()>
fn init_from_amplitudes( &mut self, amplitudes: Vec<Complex64>, num_classical_bits: usize, ) -> Result<()>
Load this rank’s shard from the full 2^n vector.
Every rank receives the whole vector and keeps the 2^(n - p) amplitudes
from rank * 2^(n - p), the identity layout init establishes; a map
left permuted by an earlier relabeled run is reset, not written into.
Collective: every rank must call it with an identical vector.
Source§fn sample_basis_states(
&mut self,
num_shots: usize,
seed: u64,
) -> Result<BasisSamples>
fn sample_basis_states( &mut self, num_shots: usize, seed: u64, ) -> Result<BasisSamples>
Trait-level entry to DistributedStatevectorBackend::sample_state_indices,
so a caller holding a dyn Backend gets the same rank-local draw the
shot route takes instead of falling back to the dense vector.
Collective: every rank must call it with identical num_shots and
seed.
Source§fn pauli_expectations(&self, observables: &[Vec<PauliTerm>]) -> Result<Vec<f64>>
fn pauli_expectations(&self, observables: &[Vec<PauliTerm>]) -> Result<Vec<f64>>
Evaluate each observable on the sharded state with no dense gather.
A Z factor on a rank bit is a constant sign for the whole slice, so an
observable whose X and Y factors are all local costs one Allreduce and
no transfer. X and Y factors on rank bits displace the bra by the same
rank offset for every amplitude, so however many there are they name one
partner rank, and one slice exchange covers them. That is the direct
route rather than a relabel because relabeling mutates the state, which
a &self query cannot do.
Collective: every rank must call it with identical observables.
Source§fn apply_1q_matrix(
&mut self,
qubit: usize,
matrix: &[[Complex64; 2]; 2],
) -> Result<()>
fn apply_1q_matrix( &mut self, qubit: usize, matrix: &[[Complex64; 2]; 2], ) -> Result<()>
Apply a 2x2 matrix to one circuit qubit across the rank split, on the same
route apply_gate takes for a one-qubit gate: relabel a non-diagonal
target into a local position when a victim exists, apply locally when the
physical position is local, otherwise exchange with the partner rank.
Collective when the target is global, so every rank must call it with the same qubit.
Source§fn name(&self) -> &'static str
fn name(&self) -> &'static str
Source§fn as_any(&self) -> Option<&dyn Any>
fn as_any(&self) -> Option<&dyn Any>
&dyn Backend, so Backend::overlap_sq
can recognize its own representation on the other side of the inner
product. An implementor that wants the fast paths writes Some(self);
the default hides the concrete type, which costs only the dense route.Source§fn resolved(&self) -> ResolvedBackend
fn resolved(&self) -> ResolvedBackend
Backend::name.Source§fn supports_fused_gates(&self) -> bool
fn supports_fused_gates(&self) -> bool
Gate::Fused variants. Read moreSource§fn supports_qft_block(&self) -> bool
fn supports_qft_block(&self) -> bool
Gate::QftBlock. Read moreSource§fn supports_pauli_rotation(&self) -> bool
fn supports_pauli_rotation(&self) -> bool
Gate::PauliRot. Read moreSource§fn apply_instructions(&mut self, instructions: &[Instruction]) -> Result<()>
fn apply_instructions(&mut self, instructions: &[Instruction]) -> Result<()>
Source§fn init(&mut self, num_qubits: usize, num_classical_bits: usize) -> Result<()>
fn init(&mut self, num_qubits: usize, num_classical_bits: usize) -> Result<()>
Source§fn supports_initial_state(&self) -> bool
fn supports_initial_state(&self) -> bool
Backend::init_from_amplitudes can start this backend from a
caller-supplied state.Source§fn apply(&mut self, instruction: &Instruction) -> Result<()>
fn apply(&mut self, instruction: &Instruction) -> Result<()>
Source§fn classical_results(&self) -> &[bool]
fn classical_results(&self) -> &[bool]
Source§fn probabilities(&self) -> Result<Vec<f64>>
fn probabilities(&self) -> Result<Vec<f64>>
Source§fn num_qubits(&self) -> usize
fn num_qubits(&self) -> usize
Source§fn export_statevector(&self) -> Result<Vec<Complex64>>
fn export_statevector(&self) -> Result<Vec<Complex64>>
Source§fn qubit_probability(&self, qubit: usize) -> Result<f64>
fn qubit_probability(&self, qubit: usize) -> Result<f64>
Source§fn supports_native_sampling(&self) -> bool
fn supports_native_sampling(&self) -> bool
Backend::sample_basis_states draws from this backend’s own
representation. Read moreSource§fn supports_pauli_expectation(&self) -> bool
fn supports_pauli_expectation(&self) -> bool
Backend::pauli_expectations evaluates observables on this
backend’s own representation.Source§fn reset(&mut self, qubit: usize) -> Result<()>
fn reset(&mut self, qubit: usize) -> Result<()>
Source§fn exactness(&self) -> Exactness
fn exactness(&self) -> Exactness
Source§fn placement(&self) -> Placement
fn placement(&self) -> Placement
gpu feature is on.Source§fn block_probabilities(&self) -> Option<Probabilities>
fn block_probabilities(&self) -> Option<Probabilities>
2^n Kronecker expansion
Backend::probabilities would materialize. Read moreSource§fn apply_region(&mut self, region: &GuardedRegion) -> Result<()>
fn apply_region(&mut self, region: &GuardedRegion) -> Result<()>
Source§fn fusion_state_qubits(&self, num_qubits: usize) -> usize
fn fusion_state_qubits(&self, num_qubits: usize) -> usize
n-qubit
circuit. Read moreSource§fn reduced_density_matrix_1q(
&self,
_qubit: usize,
) -> Result<[[Complex64; 2]; 2]>
fn reduced_density_matrix_1q( &self, _qubit: usize, ) -> Result<[[Complex64; 2]; 2]>
Source§fn supports_two_qubit_kraus(&self) -> bool
fn supports_two_qubit_kraus(&self) -> bool
NoiseChannel::Kraus2q
branch, which needs both Backend::reduced_density_matrix_2q and a
Gate::Fused2q kernel. Checked before a shot starts, so an incapable
backend is named at dispatch rather than part way through a trajectory.Source§fn reduced_density_matrix_2q(
&self,
_q0: usize,
_q1: usize,
) -> Result<[[Complex64; 4]; 4]>
fn reduced_density_matrix_2q( &self, _q0: usize, _q1: usize, ) -> Result<[[Complex64; 4]; 4]>
Source§fn schmidt_values(&mut self, _subsystem: &[usize]) -> Result<Vec<f64>>
fn schmidt_values(&mut self, _subsystem: &[usize]) -> Result<Vec<f64>>
subsystem and its
complement: descending, numerically zero values dropped, squares summing
to 1 whatever norm the representation carries. Read moreSource§fn entanglement_entropy(&mut self, subsystem: &[usize]) -> Result<f64>
fn entanglement_entropy(&mut self, subsystem: &[usize]) -> Result<f64>
subsystem in nats: -sum p ln p over
p = s^2 / sum s^2 for the Backend::schmidt_values s, which is
where the default reads it from.Source§fn reduced_density_matrix(
&mut self,
_subsystem: &[usize],
) -> Result<Vec<Complex64>>
fn reduced_density_matrix( &mut self, _subsystem: &[usize], ) -> Result<Vec<Complex64>>
subsystem, row major with side 2^k for
k qubits: rho[t * 2^k + t'] is <t|rho|t'>, where bit i of t
is the state of subsystem[i], so subsystem[0] is the lowest bit as
q[0] is in a basis index. Trace one whatever norm the representation
carries; Hermitian to rounding. Read moreAuto Trait Implementations§
impl !Freeze for DistributedStatevectorBackend
impl !RefUnwindSafe for DistributedStatevectorBackend
impl !Sync for DistributedStatevectorBackend
impl !UnwindSafe for DistributedStatevectorBackend
impl Send for DistributedStatevectorBackend
impl Unpin for DistributedStatevectorBackend
impl UnsafeUnpin for DistributedStatevectorBackend
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more