use crate::tensor::{Device, Tensor};
use super::param::{Buffer, Param};
pub trait Module: Send + Sync {
fn forward(&self, input: &Tensor) -> Tensor;
fn named_parameters(&self) -> Vec<(String, Param)> {
Vec::new()
}
fn named_buffers(&self) -> Vec<(String, Buffer)> {
Vec::new()
}
fn set_training(&self, _training: bool) {}
fn parameters(&self) -> Vec<Param> {
self.named_parameters()
.into_iter()
.map(|(_, p)| p)
.collect()
}
fn num_parameters(&self) -> usize {
self.parameters().iter().map(|p| p.numel()).sum()
}
fn to_device(&self, device: Device) {
for (_, p) in self.named_parameters() {
p.to_device(device);
}
for (_, b) in self.named_buffers() {
b.to_device(device);
}
}
fn freeze(&self) {
for (_, p) in self.named_parameters() {
p.freeze();
}
}
fn unfreeze(&self) {
for (_, p) in self.named_parameters() {
p.unfreeze();
}
}
fn trainable_parameters(&self) -> Vec<Param> {
self.parameters()
.into_iter()
.filter(Param::is_trainable)
.collect()
}
fn zero_grad(&self) {
for (_, p) in self.named_parameters() {
p.zero_grad();
}
}
fn train(&self) {
self.set_training(true);
}
fn eval(&self) {
self.set_training(false);
}
}
pub fn scoped<T>(scope: impl std::fmt::Display, items: Vec<(String, T)>) -> Vec<(String, T)> {
items
.into_iter()
.map(|(name, item)| (format!("{scope}.{name}"), item))
.collect()
}