1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Recoverable validation errors at the quantum API boundary.
/// Errors detected before dispatching invalid quantum operations to Burn.
#[derive(Debug, thiserror::Error, Clone, PartialEq)]
pub enum Error {
/// A local dimension was less than two, or a register was empty.
#[error("invalid register dimensions: {0}")]
InvalidDimensions(String),
/// A size product exceeded the host's address space.
#[error("dimension or allocation size overflow")]
Overflow,
/// A configured allocation budget would be exceeded.
#[error("{resource} requires {required} elements, limit is {limit}")]
ResourceLimit {
/// Resource being allocated.
resource: &'static str,
/// Required element count.
required: usize,
/// Configured maximum.
limit: usize,
},
/// Tensor, matrix, batch, or parameter shape mismatch.
#[error("shape mismatch: {0}")]
Shape(String),
/// Target wires were invalid or repeated.
#[error("invalid wires: {0}")]
Wires(String),
/// A basis digit or index was out of range.
#[error("basis index out of range")]
Basis,
/// A scalar, matrix, or state violated a mathematical invariant.
#[error("invalid quantum value: {0}")]
InvalidValue(String),
/// Inputs were on different hardware devices or had different dtypes.
#[error("incompatible tensor devices, dtypes, or autodiff contexts")]
TensorContext,
/// Operation requires a capability the engine does not implement.
#[error("unsupported operation: {0}")]
Unsupported(String),
/// Tensor readback could not be decoded.
#[error("tensor readback failed: {0}")]
Readback(String),
}
/// Quantum API result.
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) fn checked_product(values: impl IntoIterator<Item = usize>) -> Result<usize> {
values
.into_iter()
.try_fold(1usize, |n, d| n.checked_mul(d).ok_or(Error::Overflow))
}
pub(crate) fn tolerance(value: f64) -> Result<()> {
if value.is_finite() && value > 0.0 && value < 1.0 {
Ok(())
} else {
Err(Error::InvalidValue(
"tolerance must be finite and in (0, 1)".into(),
))
}
}