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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Stable diagnostics for reference-solver admission and execution.
use std::fmt;
use sim_lib_interference_core::InterferenceError;
/// A reference solve failed without returning a partial field.
#[derive(Clone, Debug, PartialEq)]
pub enum ReferenceSolveError {
/// Sampling, work, or another request-wide preflight check failed.
Request {
/// Exact core diagnostic that refused the request.
cause: Box<InterferenceError>,
},
/// A sampling cell could not be represented by the checked plane.
CellGeometry {
/// Zero-based row.
row: usize,
/// Zero-based column.
column: usize,
/// Exact geometry diagnostic.
cause: Box<InterferenceError>,
},
/// One canonical source could not be evaluated at one sampling cell.
SourceAtCell {
/// Stable source identity.
source_id: String,
/// Zero-based row.
row: usize,
/// Zero-based column.
column: usize,
/// Exact propagation diagnostic.
cause: Box<InterferenceError>,
},
/// Compensated component accumulation became non-finite.
NonFiniteAccumulation {
/// Stable source identity after whose contribution the failure arose.
source_id: String,
/// Zero-based row.
row: usize,
/// Zero-based column.
column: usize,
/// Component plane (`real` or `imaginary`).
component: &'static str,
/// Rejected accumulated value.
value: f64,
},
/// Host storage could not be reserved for a complete component plane.
AllocationFailed {
/// Component plane whose reservation failed.
component: &'static str,
/// Requested cell count.
cells: usize,
},
}
impl From<InterferenceError> for ReferenceSolveError {
fn from(cause: InterferenceError) -> Self {
Self::Request {
cause: Box::new(cause),
}
}
}
impl fmt::Display for ReferenceSolveError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Request { cause } => {
write!(formatter, "reference solve request refused: {cause}")
}
Self::CellGeometry { row, column, cause } => write!(
formatter,
"sampling cell ({row}, {column}) has invalid geometry: {cause}"
),
Self::SourceAtCell {
source_id,
row,
column,
cause,
} => write!(
formatter,
"source `{source_id}` failed at sampling cell ({row}, {column}): {cause}"
),
Self::NonFiniteAccumulation {
source_id,
row,
column,
component,
value,
} => write!(
formatter,
"{component} accumulation became non-finite after source \
`{source_id}` at sampling cell ({row}, {column}): {value:?}"
),
Self::AllocationFailed { component, cells } => write!(
formatter,
"could not reserve {cells} f64 cells for the {component} component plane"
),
}
}
}
impl std::error::Error for ReferenceSolveError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Request { cause }
| Self::CellGeometry { cause, .. }
| Self::SourceAtCell { cause, .. } => Some(cause.as_ref()),
Self::NonFiniteAccumulation { .. } | Self::AllocationFailed { .. } => None,
}
}
}