ruvector_cnn/layers/
mod.rs1pub mod activation;
12pub mod batchnorm;
13pub mod conv;
14pub mod linear;
15pub mod pooling;
16
17pub mod quantized_conv2d;
19pub mod quantized_depthwise;
20pub mod quantized_linear;
21pub mod quantized_pooling;
22pub mod quantized_residual;
23
24pub use activation::{Activation, ActivationType, HardSwish, ReLU, ReLU6, Sigmoid, Swish};
25pub use batchnorm::{BatchNorm, BatchNorm2d};
26pub use conv::{Conv2d, DepthwiseSeparableConv};
27pub use linear::Linear;
28pub use pooling::{AvgPool2d, GlobalAvgPool, GlobalAvgPool2d, MaxPool2d};
29
30pub use quantized_conv2d::QuantizedConv2d;
32pub use quantized_depthwise::QuantizedDepthwiseConv2d;
33pub use quantized_linear::QuantizedLinear;
34pub use quantized_pooling::{QuantizedAvgPool2d, QuantizedMaxPool2d};
35pub use quantized_residual::QuantizedResidualAdd;
36
37use crate::{CnnResult, Tensor};
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41pub struct TensorShape {
42 pub n: usize,
44 pub c: usize,
46 pub h: usize,
48 pub w: usize,
50}
51
52impl TensorShape {
53 pub fn new(n: usize, c: usize, h: usize, w: usize) -> Self {
55 Self { n, c, h, w }
56 }
57
58 pub fn numel(&self) -> usize {
60 self.n * self.c * self.h * self.w
61 }
62
63 pub fn spatial_size(&self) -> usize {
65 self.h * self.w
66 }
67
68 pub fn channel_size(&self) -> usize {
70 self.c * self.h * self.w
71 }
72}
73
74impl std::fmt::Display for TensorShape {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(f, "[{}, {}, {}, {}]", self.n, self.c, self.h, self.w)
77 }
78}
79
80pub fn conv_output_size(input: usize, kernel: usize, stride: usize, padding: usize, dilation: usize) -> usize {
82 let effective_kernel = dilation * (kernel - 1) + 1;
83 (input + 2 * padding - effective_kernel) / stride + 1
84}
85
86pub trait Layer {
88 fn forward(&self, input: &Tensor) -> CnnResult<Tensor>;
90
91 fn name(&self) -> &'static str;
93
94 fn num_params(&self) -> usize {
96 0
97 }
98}
99
100pub fn conv2d_3x3(
109 input: &[f32],
110 weights: &[f32],
111 in_channels: usize,
112 out_channels: usize,
113 height: usize,
114 width: usize,
115) -> Vec<f32> {
116 let out_h = height; let out_w = width;
118 let mut output = vec![0.0f32; out_h * out_w * out_channels];
119
120 crate::simd::scalar::conv_3x3_scalar(
121 input,
122 weights,
123 &mut output,
124 height,
125 width,
126 in_channels,
127 out_channels,
128 1, 1, );
131
132 output
133}
134
135pub fn batch_norm(
139 input: &[f32],
140 gamma: &[f32],
141 beta: &[f32],
142 mean: &[f32],
143 var: &[f32],
144 epsilon: f32,
145) -> Vec<f32> {
146 let mut output = vec![0.0f32; input.len()];
147 let channels = gamma.len();
148
149 crate::simd::batch_norm_simd(
150 input,
151 &mut output,
152 gamma,
153 beta,
154 mean,
155 var,
156 epsilon,
157 channels,
158 );
159
160 output
161}
162
163pub fn hard_swish(input: &[f32]) -> Vec<f32> {
167 let mut output = vec![0.0f32; input.len()];
168 crate::simd::scalar::hard_swish_scalar(input, &mut output);
169 output
170}
171
172pub fn relu(input: &[f32]) -> Vec<f32> {
174 let mut output = vec![0.0f32; input.len()];
175 crate::simd::relu_simd(input, &mut output);
176 output
177}
178
179pub fn relu6(input: &[f32]) -> Vec<f32> {
181 let mut output = vec![0.0f32; input.len()];
182 crate::simd::relu6_simd(input, &mut output);
183 output
184}
185
186pub fn global_avg_pool(input: &[f32], channels: usize) -> Vec<f32> {
190 let spatial_size = input.len() / channels;
191 let mut output = vec![0.0f32; channels];
192
193 for i in 0..input.len() {
195 let c = i % channels;
196 output[c] += input[i];
197 }
198
199 let inv_spatial = 1.0 / spatial_size as f32;
201 for o in output.iter_mut() {
202 *o *= inv_spatial;
203 }
204
205 output
206}
207
208pub use conv::Conv2dBuilder;
210
211impl Activation {
216 pub fn relu() -> Self {
218 Self::new(ActivationType::ReLU)
219 }
220
221 pub fn relu6() -> Self {
223 Self::new(ActivationType::ReLU6)
224 }
225
226 pub fn hard_swish() -> Self {
228 Self::new(ActivationType::HardSwish)
229 }
230
231 pub fn hard_sigmoid() -> Self {
233 Self::new(ActivationType::Sigmoid)
234 }
235
236 pub fn identity() -> Self {
238 Self::new(ActivationType::Identity)
239 }
240}