use std::fmt;
use tenferro_runtime::ExtensionCacheStore;
use tenferro_tensor::{BackendSession, Tensor, TensorRead};
use crate::{FftPlanCache, FftPlanSpec};
#[derive(Clone, Copy, Debug)]
enum FftCacheOwner {
CallerOwned,
RuntimeOwned,
}
pub struct FftExecutionCache<'a> {
owner: FftCacheOwner,
store: &'a mut ExtensionCacheStore,
}
impl fmt::Debug for FftExecutionCache<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FftExecutionCache")
.field("owner", &self.owner)
.field(
"stats",
&self
.store
.stats(tenferro_runtime::ExtensionCacheSelector::All),
)
.finish_non_exhaustive()
}
}
impl<'a> FftExecutionCache<'a> {
pub fn caller_owned(cache: &'a mut FftPlanCache) -> Self {
Self {
owner: FftCacheOwner::CallerOwned,
store: cache.store_mut(),
}
}
pub fn runtime_owned(cache: &'a mut ExtensionCacheStore) -> Self {
Self {
owner: FftCacheOwner::RuntimeOwned,
store: cache,
}
}
pub fn store_mut(&mut self) -> &mut ExtensionCacheStore {
self.store
}
}
pub trait FftBackend: BackendSession {
fn validate_fft_read_input(
&self,
_op: &'static str,
_input: &TensorRead<'_>,
) -> tenferro_tensor::Result<()> {
Ok(())
}
fn execute_fft(
&mut self,
input: &Tensor,
spec: &FftPlanSpec,
cache: FftExecutionCache<'_>,
) -> tenferro_tensor::Result<Tensor>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn execution_cache_debug_identifies_both_owners_and_exposes_the_store() {
let mut caller = FftPlanCache::default();
let mut caller_cache = FftExecutionCache::caller_owned(&mut caller);
assert!(format!("{caller_cache:?}").contains("CallerOwned"));
assert_eq!(
caller_cache
.store_mut()
.stats(tenferro_runtime::ExtensionCacheSelector::All)
.entries,
0
);
let mut runtime = ExtensionCacheStore::default();
let mut runtime_cache = FftExecutionCache::runtime_owned(&mut runtime);
assert!(format!("{runtime_cache:?}").contains("RuntimeOwned"));
assert_eq!(
runtime_cache
.store_mut()
.stats(tenferro_runtime::ExtensionCacheSelector::All)
.entries,
0
);
}
}