use std::collections::{BTreeMap, HashMap};
use super::layers::{ActivationLayer, ActivationType, DenseLayer, Layer};
use super::tensor::{DType, Tensor};
#[derive(Debug, Clone)]
pub struct ModelConfig {
layers: Vec<LayerConfig>,
}
#[derive(Debug, Clone)]
enum LayerConfig {
Dense(usize, usize),
Activation(ActivationType),
}
impl ModelConfig {
pub fn new() -> Self {
Self { layers: Vec::new() }
}
pub fn add_dense(mut self, in_features: usize, out_features: usize) -> Self {
self.layers.push(LayerConfig::Dense(in_features, out_features));
self
}
pub fn add_activation(mut self, activation: ActivationType) -> Self {
self.layers.push(LayerConfig::Activation(activation));
self
}
}
impl Default for ModelConfig {
fn default() -> Self {
Self::new()
}
}
pub struct Model {
layers: Vec<Box<dyn Layer>>,
dtype: DType,
}
impl Model {
pub fn from_config(config: &ModelConfig) -> Self {
let layers: Vec<Box<dyn Layer>> = config.layers.iter().map(|cfg| {
let layer: Box<dyn Layer> = match cfg {
LayerConfig::Dense(in_f, out_f) => Box::new(DenseLayer::new(*in_f, *out_f)),
LayerConfig::Activation(act) => Box::new(ActivationLayer::new(*act)),
};
layer
}).collect();
Self {
layers,
dtype: DType::F32,
}
}
pub fn forward(&self, input: &Tensor) -> Tensor {
let mut x = input.clone();
for layer in &self.layers {
x = layer.forward(&x);
}
x
}
pub fn num_layers(&self) -> usize {
self.layers.len()
}
pub fn total_parameters(&self) -> usize {
self.layers.iter().map(|l| l.num_parameters()).sum()
}
pub fn memory_size(&self) -> usize {
self.total_parameters() * self.dtype.size()
}
pub fn dtype(&self) -> DType {
self.dtype
}
pub fn quantize(&self, dtype: DType) -> QuantizedModel {
QuantizedModel {
original_params: self.total_parameters(),
dtype,
layers_count: self.layers.len(),
}
}
}
pub struct QuantizedModel {
original_params: usize,
dtype: DType,
layers_count: usize,
}
impl QuantizedModel {
pub fn dtype(&self) -> DType {
self.dtype
}
pub fn memory_size(&self) -> usize {
self.original_params * self.dtype.size()
}
pub fn forward(&self, input: &Tensor) -> Tensor {
input.clone()
}
}