use std::collections::HashMap;
use fandhe_ai_autodiff::nn::ForwardHooked as AutodiffForwardHooked;
use fandhe_ai_autodiff::nn::Module as AutodiffModule;
use super::ForwardHookCtx;
use crate::nn::module::{FacadeModuleAdapter, Module};
use crate::{AutodiffError, TapeRef, Tensor, Var};
pub struct ForwardHooked<M: Module> {
inner: AutodiffForwardHooked<FacadeModuleAdapter<Box<M>>>,
}
impl<M: Module> ForwardHooked<M> {
pub fn new<F>(inner: M, hook: F) -> Self
where
F: Fn(&ForwardHookCtx<'_>) -> Result<(), AutodiffError> + Send + Sync + 'static,
{
Self {
inner: AutodiffForwardHooked::new(FacadeModuleAdapter(Box::new(inner)), hook),
}
}
pub fn inner(&self) -> &M {
&self.inner.inner().0
}
pub fn inner_mut(&mut self) -> &mut M {
&mut self.inner.inner_mut().0
}
pub fn into_inner(self) -> M {
*self.inner.into_inner().0
}
}
impl<M: Module> Module for ForwardHooked<M> {
fn forward<'t>(&self, tape: TapeRef<'t>, input: &Var<'t>) -> Result<Var<'t>, AutodiffError> {
AutodiffModule::forward(&self.inner, tape.0, input)
}
fn named_parameters(&self) -> Vec<(String, &Tensor<f32>)> {
self.inner().named_parameters()
}
fn set_parameter(&mut self, name: &str, value: Tensor<f32>) -> Result<(), AutodiffError> {
self.inner_mut().set_parameter(name, value)
}
fn state_dict(&self) -> HashMap<String, Tensor<f32>> {
self.inner().state_dict()
}
fn load_state_dict(
&mut self,
state: HashMap<String, Tensor<f32>>,
) -> Result<(), AutodiffError> {
self.inner_mut().load_state_dict(state)
}
fn set_training(&mut self, training: bool) {
self.inner_mut().set_training(training);
}
fn training(&self) -> bool {
self.inner().training()
}
fn set_requires_grad(&mut self, requires_grad: bool) -> Result<(), AutodiffError> {
self.inner_mut().set_requires_grad(requires_grad)
}
fn freeze(&mut self) -> Result<(), AutodiffError> {
self.inner_mut().freeze()
}
fn requires_grad(&self) -> bool {
self.inner().requires_grad()
}
fn children(&self) -> Vec<(String, &dyn Module)> {
self.inner().children()
}
fn children_mut(&mut self) -> Vec<(String, &mut dyn Module)> {
self.inner_mut().children_mut()
}
fn named_modules(&self) -> Vec<(String, &dyn Module)> {
self.inner().named_modules()
}
fn parameter_count(&self) -> usize {
self.inner().parameter_count()
}
fn type_name(&self) -> &'static str {
self.inner().type_name()
}
}