use std::fmt;
use tenferro_tensor::Engine;
use crate::extension_cache::ExtensionCacheStore;
pub struct ExtensionExecutionContext<'a, B: Engine + ?Sized> {
backend: &'a mut B,
caches: &'a mut ExtensionCacheStore,
}
impl<B: Engine + ?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: Engine + ?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::CpuEngine;
use tenferro_tensor::{Engine, Tensor, TensorElementwise, TensorRead};
use crate::ExtensionCacheSelector;
#[test]
fn context_accepts_a_caller_held_engine() {
let mut engine = CpuEngine::serial();
let mut caches = ExtensionCacheStore::new();
let mut context = ExtensionExecutionContext::new(&mut engine, &mut caches);
let _: &dyn Engine = 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_read(TensorRead::from_tensor(&lhs), TensorRead::from_tensor(&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);
}
}