From 491baf2bfb857513a3f0b24a1fd335f5bcb37578 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Sun, 8 Feb 2026 18:48:28 +0300 Subject: [PATCH] [lab4] Removed const size from Layer trait --- lab4/src/algo/layer.rs | 12 +++--- lab4/src/algo/layer_impl.rs | 58 ++++++++++++++++----------- lab4/src/algo/layers_union.rs | 67 +++++++++++++++++++++++++++++++ lab4/src/algo/mod.rs | 2 +- lab4/src/algo/net.rs | 74 ----------------------------------- 5 files changed, 109 insertions(+), 104 deletions(-) create mode 100644 lab4/src/algo/layers_union.rs delete mode 100644 lab4/src/algo/net.rs diff --git a/lab4/src/algo/layer.rs b/lab4/src/algo/layer.rs index e18b50c..8c961cc 100644 --- a/lab4/src/algo/layer.rs +++ b/lab4/src/algo/layer.rs @@ -1,9 +1,9 @@ -pub trait Layer { +pub trait Layer { type InputType; type OutputType; - fn compute( - &self, - input_data: &[Self::InputType; PrevLayerSize], - ) -> [Self::OutputType; CurrentLayerSize]; -} \ No newline at end of file + fn compute(&self, input_data: &[Self::InputType], output_data: &mut [Self::OutputType]); + + fn input_size(&self) -> usize; + fn output_size(&self) -> usize; +} diff --git a/lab4/src/algo/layer_impl.rs b/lab4/src/algo/layer_impl.rs index 9175092..546ba32 100644 --- a/lab4/src/algo/layer_impl.rs +++ b/lab4/src/algo/layer_impl.rs @@ -1,43 +1,51 @@ use crate::algo::layer::Layer; -use crate::algo::net::LayersConnect; +use crate::algo::layers_union::LayersUnion; use std::iter::Sum; use std::marker::PhantomData; -use std::ops::{Add, Mul}; +use std::ops::Add; struct Neuron { input_weights: [f64; PrevLayerSize], } -pub trait ApplyWeight { - type Output; - fn apply_weight(&self, w: f64) -> Self::Output; +pub trait ApplyWeight { + fn apply_weight(&self, w: f64) -> Output; +} + +impl ApplyWeight for f64 { + fn apply_weight(&self, w: f64) -> f64 { + return *self * w; + } } pub struct LayerImpl< const PrevLayerSize: usize, const CurrentLayerSize: usize, - InputType: ApplyWeight, - ActivationType: Sum<::Output>, + InputType: ApplyWeight, + WeightedType, + ActivationType: Sum, ActivationFunction: Fn(ActivationType) -> OutputType, OutputType, > { neurons: [Neuron; CurrentLayerSize], activation_function: ActivationFunction, - __phantom: PhantomData<(InputType, ActivationType, OutputType)>, + __phantom: PhantomData<(InputType, WeightedType, ActivationType, OutputType)>, } impl< const PrevLayerSize: usize, const CurrentLayerSize: usize, - InputType: ApplyWeight, - ActivationType: Sum<::Output>, + InputType: ApplyWeight, + WeightedType, + ActivationType: Sum, ActivationFunction: Fn(ActivationType) -> OutputType, OutputType, -> Layer +> Layer for LayerImpl< PrevLayerSize, CurrentLayerSize, InputType, + WeightedType, ActivationType, ActivationFunction, OutputType, @@ -46,45 +54,49 @@ impl< type InputType = InputType; type OutputType = OutputType; - fn compute(&self, input_data: &[InputType; PrevLayerSize]) -> [OutputType; CurrentLayerSize] { - let mut output: [OutputType; CurrentLayerSize] = - std::array::from_fn(|_| unsafe { std::mem::uninitialized::() }); + fn compute(&self, input_data: &[InputType], output_data: &mut [OutputType]) { for (i, n) in self.neurons.iter().enumerate() { let P = input_data .iter() .zip(n.input_weights) .map(|(x, w)| x.apply_weight(w)) .sum(); - output[i] = (self.activation_function)(P); + output_data[i] = (self.activation_function)(P); } + } - return output; + fn input_size(&self) -> usize { + return PrevLayerSize; + } + + fn output_size(&self) -> usize { + return CurrentLayerSize; } } impl< const PrevPrevLayerSize: usize, const PrevLayerSize: usize, - const CurrentLayerSize: usize, - PrevLayerInputType: ApplyWeight, - PrevLayerActivationType: Sum<::Output>, + PrevLayerInputType: ApplyWeight, + PrevLayerWeightedType, + PrevLayerActivationType: Sum, PrevLayerActivationFunction: Fn(PrevLayerActivationType) -> PrevLayerOutputType, PrevLayerOutputType, - CurrentLayer: Layer, + CurrentLayer: Layer, > Add for LayerImpl< PrevPrevLayerSize, PrevLayerSize, PrevLayerInputType, + PrevLayerWeightedType, PrevLayerActivationType, PrevLayerActivationFunction, PrevLayerOutputType, > { - type Output = - LayersConnect; + type Output = LayersUnion; fn add(self, rhs: CurrentLayer) -> Self::Output { - return LayersConnect::join(self, rhs); + return LayersUnion::join(self, rhs); } } diff --git a/lab4/src/algo/layers_union.rs b/lab4/src/algo/layers_union.rs new file mode 100644 index 0000000..b619f6a --- /dev/null +++ b/lab4/src/algo/layers_union.rs @@ -0,0 +1,67 @@ +use crate::algo::layer::Layer; +use std::ops::Add; + +pub struct LayersUnion< + PrevLayer: Layer, + CurrentLayer: Layer, +> { + prev_layer: PrevLayer, + current_layer: CurrentLayer, +} + +impl> + LayersUnion +{ + pub fn join(l1: PrevLayer, l2: CurrentLayer) -> Self { + assert_eq!(l1.output_size(), l2.input_size()); + return Self { + prev_layer: l1, + current_layer: l2, + }; + } +} + +impl> Layer + for LayersUnion +{ + type InputType = PrevLayer::InputType; + type OutputType = CurrentLayer::OutputType; + + fn compute(&self, input_data: &[Self::InputType], output_data: &mut [Self::OutputType]) { + let mut intermediate_data_s = + vec![0u8; self.prev_layer.output_size() * size_of::()] + .into_boxed_slice(); + + let intermediate_data; + unsafe { + intermediate_data = std::slice::from_raw_parts_mut( + intermediate_data_s.as_mut_ptr().cast::(), + self.prev_layer.output_size(), + ) + } + self.prev_layer.compute(input_data, intermediate_data); + self.current_layer.compute(intermediate_data, output_data); + } + + fn input_size(&self) -> usize { + return self.prev_layer.input_size(); + } + + fn output_size(&self) -> usize { + return self.current_layer.output_size(); + } +} + +impl< + PrevLayer: Layer, + CurrentLayer: Layer, + NextLayer: Layer, +> Add + for LayersUnion +{ + type Output = LayersUnion; + + fn add(self, rhs: NextLayer) -> Self::Output { + return LayersUnion::join(self, rhs); + } +} diff --git a/lab4/src/algo/mod.rs b/lab4/src/algo/mod.rs index 4013c1b..5f0c50a 100644 --- a/lab4/src/algo/mod.rs +++ b/lab4/src/algo/mod.rs @@ -1,3 +1,3 @@ mod layer; -mod net; +mod layers_union; mod layer_impl; diff --git a/lab4/src/algo/net.rs b/lab4/src/algo/net.rs deleted file mode 100644 index e08d745..0000000 --- a/lab4/src/algo/net.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::algo::layer::Layer; -use std::ops::{Add}; - -pub(super) struct LayersConnect< - const PrevPrevLayerSize: usize, - const PrevLayerSize: usize, - const CurrentLayerSize: usize, - PrevLayer: Layer, - CurrentLayer: Layer, -> { - prev_layer: PrevLayer, - current_layer: CurrentLayer, -} - -impl< - const PrevPrevLayerSize: usize, - const PrevLayerSize: usize, - const CurrentLayerSize: usize, - PrevLayer: Layer, - CurrentLayer: Layer, -> LayersConnect -{ - pub fn join(l1: PrevLayer, l2: CurrentLayer) -> Self { - return Self { - prev_layer: l1, - current_layer: l2, - }; - } -} - -impl< - const PrevPrevLayerSize: usize, - const PrevLayerSize: usize, - const CurrentLayerSize: usize, - PrevLayer: Layer, - CurrentLayer: Layer, -> Layer - for LayersConnect -{ - type InputType = PrevLayer::InputType; - type OutputType = CurrentLayer::OutputType; - - fn compute( - &self, - input_data: &[Self::InputType; PrevPrevLayerSize], - ) -> [Self::OutputType; CurrentLayerSize] { - let intermediate_data = self.prev_layer.compute(input_data); - return self.current_layer.compute(&intermediate_data); - } -} - -impl< - const PrevPrevLayerSize: usize, - const PrevLayerSize: usize, - const CurrentLayerSize: usize, - const NextLayerSize: usize, - PrevLayer: Layer, - CurrentLayer: Layer, - NextLayer: Layer, -> Add - for LayersConnect< - PrevPrevLayerSize, - PrevLayerSize, - CurrentLayerSize, - PrevLayer, - CurrentLayer, - > -{ - type Output = LayersConnect; - - fn add(self, rhs: NextLayer) -> Self::Output { - return LayersConnect::join(self, rhs) - } -}