Skip to main content

embedded_nn/
types.rs

1//! Core types and parameter structures for `embedded-nn`.
2
3/// Error types for `embedded-nn` operations.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Error {
6    /// One or more input arguments/dimensions are invalid or incompatible.
7    ArgumentError,
8    /// Function or operation is not implemented for the given configuration.
9    NoImplementation,
10    /// Execution or calculation error.
11    Failure,
12}
13
14impl core::fmt::Display for Error {
15    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16        match self {
17            Error::ArgumentError => write!(f, "Invalid or incompatible arguments"),
18            Error::NoImplementation => write!(f, "No implementation available"),
19            Error::Failure => write!(f, "Operation failure"),
20        }
21    }
22}
23
24/// Result type alias for `embedded-nn`.
25pub type Result<T> = core::result::Result<T, Error>;
26
27/// Dimensions for 4D Tensors (Batch, Height, Width, Channels / Output Channels).
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub struct Dims {
30    /// Batch size or generic dimension `n`.
31    pub n: i32,
32    /// Height `h`.
33    pub h: i32,
34    /// Width `w`.
35    pub w: i32,
36    /// Channels `c`.
37    pub c: i32,
38}
39
40impl Dims {
41    /// Creates a new 4D Dims structure.
42    pub const fn new(n: i32, h: i32, w: i32, c: i32) -> Self {
43        Self { n, h, w, c }
44    }
45
46    /// Computes total number of elements.
47    pub const fn total_size(&self) -> usize {
48        (self.n * self.h * self.w * self.c) as usize
49    }
50}
51
52/// Tile or kernel spatial dimensions (Width, Height).
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
54pub struct Tile {
55    /// Width `w`.
56    pub w: i32,
57    /// Height `h`.
58    pub h: i32,
59}
60
61impl Tile {
62    /// Creates a new Tile structure.
63    pub const fn new(w: i32, h: i32) -> Self {
64        Self { w, h }
65    }
66}
67
68/// Quantized activation clamping range (min, max).
69#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub struct Activation {
71    /// Minimum clamping threshold.
72    pub min: i32,
73    /// Maximum clamping threshold.
74    pub max: i32,
75}
76
77impl Activation {
78    /// Creates a new Activation clamping range.
79    pub const fn new(min: i32, max: i32) -> Self {
80        Self { min, max }
81    }
82
83    /// Returns an unconstrained range for int8 (-128 to 127).
84    pub const fn int8_unconstrained() -> Self {
85        Self {
86            min: i8::MIN as i32,
87            max: i8::MAX as i32,
88        }
89    }
90
91    /// Returns an unconstrained range for int16 (-32768 to 32767).
92    pub const fn int16_unconstrained() -> Self {
93        Self {
94            min: i16::MIN as i32,
95            max: i16::MAX as i32,
96        }
97    }
98}
99
100/// Per-tensor quantization parameters.
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub struct PerTensorQuantParams {
103    /// Requantization multiplier (Q31).
104    pub multiplier: i32,
105    /// Requantization shift.
106    pub shift: i32,
107}
108
109impl PerTensorQuantParams {
110    /// Creates new per-tensor quantization parameters.
111    pub const fn new(multiplier: i32, shift: i32) -> Self {
112        Self { multiplier, shift }
113    }
114}
115
116/// Per-channel quantization parameters.
117#[derive(Debug, Clone, PartialEq, Eq)]
118pub struct PerChannelQuantParams<'a> {
119    /// Per-channel multipliers.
120    pub multiplier: &'a [i32],
121    /// Per-channel shifts.
122    pub shift: &'a [i32],
123}
124
125impl<'a> PerChannelQuantParams<'a> {
126    /// Creates new per-channel quantization parameters.
127    pub const fn new(multiplier: &'a [i32], shift: &'a [i32]) -> Self {
128        Self { multiplier, shift }
129    }
130}
131
132/// Unified quantization parameters (either per-tensor or per-channel).
133#[derive(Debug, Clone)]
134pub enum QuantParams<'a> {
135    /// Per-tensor quantization parameters.
136    PerTensor(PerTensorQuantParams),
137    /// Per-channel quantization parameters.
138    PerChannel(PerChannelQuantParams<'a>),
139}
140
141/// Parameters for Convolution layer operations.
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub struct ConvParams {
144    /// Input zero point offset (-zero_point).
145    pub input_offset: i32,
146    /// Output zero point offset (+zero_point).
147    pub output_offset: i32,
148    /// Stride (width, height).
149    pub stride: Tile,
150    /// Padding (width, height).
151    pub padding: Tile,
152    /// Dilation (width, height).
153    pub dilation: Tile,
154    /// Output activation range.
155    pub activation: Activation,
156}
157
158/// Parameters for Depthwise Convolution layer operations.
159#[derive(Debug, Clone, Copy, PartialEq, Eq)]
160pub struct DwConvParams {
161    /// Input zero point offset (-zero_point).
162    pub input_offset: i32,
163    /// Output zero point offset (+zero_point).
164    pub output_offset: i32,
165    /// Channel multiplier.
166    pub ch_mult: i32,
167    /// Stride (width, height).
168    pub stride: Tile,
169    /// Padding (width, height).
170    pub padding: Tile,
171    /// Dilation (width, height).
172    pub dilation: Tile,
173    /// Output activation range.
174    pub activation: Activation,
175}
176
177/// Parameters for Fully Connected (Linear) layer operations.
178#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179pub struct FcParams {
180    /// Input zero point offset (-zero_point).
181    pub input_offset: i32,
182    /// Filter zero point offset (-zero_point).
183    pub filter_offset: i32,
184    /// Output zero point offset (+zero_point).
185    pub output_offset: i32,
186    /// Output activation range.
187    pub activation: Activation,
188}
189
190/// Parameters for Pooling operations.
191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192pub struct PoolParams {
193    /// Stride (width, height).
194    pub stride: Tile,
195    /// Padding (width, height).
196    pub padding: Tile,
197    /// Output activation range.
198    pub activation: Activation,
199}
200
201/// Parameters for Softmax operation.
202#[derive(Debug, Clone, Copy, PartialEq, Eq)]
203pub struct SoftmaxParams {
204    /// Input scale for fixed-point exponential calculation.
205    pub input_scale: i32,
206    /// Minimum input difference threshold.
207    pub diff_min: i32,
208}
209
210/// Context for scratchpad buffers (optional).
211#[derive(Debug)]
212pub struct Context<'a> {
213    /// Scratch buffer slice.
214    pub buf: Option<&'a mut [u8]>,
215}
216
217impl<'a> Context<'a> {
218    /// Creates a context without scratch memory.
219    pub const fn empty() -> Self {
220        Self { buf: None }
221    }
222
223    /// Creates a context with given scratch buffer.
224    pub fn new(buf: &'a mut [u8]) -> Self {
225        Self { buf: Some(buf) }
226    }
227}