use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use burn_pack::Tensor as PackTensor;
use super::applier::Applier;
use super::apply_result::ApplyResult;
use crate::collector::Collector;
use crate::{ModuleAdapter, PathFilter};
use burn_core::module::Module;
struct AbortOnUnwind;
impl Drop for AbortOnUnwind {
fn drop(&mut self) {
#[cfg(feature = "std")]
{
eprintln!(
"burn-store: a panic escaped Module::map during ModuleSnapshot::apply, leaving \
the module moved-from. Aborting rather than dropping it twice."
);
std::process::abort();
}
#[cfg(not(feature = "std"))]
panic!(
"burn-store: a panic escaped Module::map during ModuleSnapshot::apply, leaving the \
module moved-from"
);
}
}
pub trait ModuleSnapshot: Module {
fn collect(
&self,
filter: Option<PathFilter>,
adapter: Option<Box<dyn ModuleAdapter>>,
skip_enum_variants: bool,
) -> Vec<PackTensor> {
let mut collector = Collector::new(filter, adapter, skip_enum_variants);
self.visit(&mut collector);
collector.into_tensors()
}
fn apply(
&mut self,
tensors: Vec<PackTensor>,
filter: Option<PathFilter>,
adapter: Option<Box<dyn ModuleAdapter>>,
skip_enum_variants: bool,
) -> ApplyResult
where
Self: Sized,
{
let mut applier = Applier::new(tensors, filter, adapter, skip_enum_variants);
unsafe {
let module = core::ptr::read(self as *const Self);
let guard = AbortOnUnwind;
let new_module = module.map(&mut applier);
core::ptr::write(self as *mut Self, new_module);
core::mem::forget(guard);
}
applier.into_result()
}
fn save_into<P>(&self, store: &mut P) -> Result<(), P::Error>
where
P: ModuleStore,
{
store.collect_from(self)
}
fn load_from<P>(&mut self, store: &mut P) -> Result<ApplyResult, P::Error>
where
P: ModuleStore,
{
store.apply_to(self)
}
}
pub trait ModuleStore {
type Error: core::fmt::Debug + core::fmt::Display;
fn collect_from<M: ModuleSnapshot>(&mut self, module: &M) -> Result<(), Self::Error>;
fn apply_to<M: ModuleSnapshot>(&mut self, module: &mut M) -> Result<ApplyResult, Self::Error>;
fn get_tensor(&mut self, name: &str) -> Result<Option<&PackTensor>, Self::Error>;
fn get_all_tensors(&mut self) -> Result<&BTreeMap<String, PackTensor>, Self::Error>;
fn keys(&mut self) -> Result<Vec<String>, Self::Error>;
}
impl<M: Module> ModuleSnapshot for M {}