use std::fmt;
use tenferro_tensor::BackendSession;
use crate::extension_cache::ExtensionCacheStore;
pub struct ExtensionExecutionContext<'a, B: BackendSession + ?Sized> {
backend: &'a mut B,
caches: &'a mut ExtensionCacheStore,
}
impl<B: BackendSession + ?Sized> fmt::Debug for ExtensionExecutionContext<'_, B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExtensionExecutionContext")
.field("backend_type", &std::any::type_name::<B>())
.field("caches", &self.caches)
.finish_non_exhaustive()
}
}
impl<'a, B: BackendSession + ?Sized> ExtensionExecutionContext<'a, B> {
pub fn new(backend: &'a mut B, caches: &'a mut ExtensionCacheStore) -> Self {
Self { backend, caches }
}
pub fn backend(&self) -> &B {
self.backend
}
pub fn backend_mut(&mut self) -> &mut B {
self.backend
}
pub fn caches(&self) -> &ExtensionCacheStore {
self.caches
}
pub fn caches_mut(&mut self) -> &mut ExtensionCacheStore {
self.caches
}
pub fn parts_mut(&mut self) -> (&mut B, &mut ExtensionCacheStore) {
(self.backend, self.caches)
}
}
#[cfg(test)]
mod tests {
use super::*;
use tenferro_cpu::CpuBackend;
use tenferro_tensor::{BackendSession, BackendSessionHost, Tensor};
use crate::ExtensionCacheSelector;
#[test]
fn context_accepts_non_owning_backend_session() {
let mut backend = CpuBackend::new();
let mut caches = ExtensionCacheStore::new();
backend.with_backend_session(|session| {
let mut context = ExtensionExecutionContext::new(session, &mut caches);
let _: &dyn BackendSession = context.backend();
let lhs = Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap();
let rhs = Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap();
let output = context.backend_mut().add(&lhs, &rhs).unwrap();
assert_eq!(output.as_slice::<f64>().unwrap(), &[4.0, 6.0]);
assert_eq!(
context.caches().stats(ExtensionCacheSelector::All).entries,
0
);
let (_, caches) = context.parts_mut();
assert_eq!(caches.stats(ExtensionCacheSelector::All).entries, 0);
});
}
}