use crate::plan::{Direction, PlanDesc};
use crate::scalar::{Complex, Real, Scalar};
pub trait Backend: Sized + Send + Sync + 'static {
type Device: Device<Self>;
type Buffer<T: Scalar>: BufferOps<Self, T>;
type C2cPlan<T: Complex>: C2cPlanOps<Self, T>;
type R2cPlan<F: Real>: R2cPlanOps<Self, F>;
type C2rPlan<F: Real>: C2rPlanOps<Self, F>;
type Error: std::error::Error + Send + Sync + 'static;
const NAME: &'static str;
}
pub trait Device<B: Backend>: Sized + Send + Sync {
fn alloc<T: Scalar>(&self, len: usize) -> Result<B::Buffer<T>, B::Error>;
fn plan_c2c<T: Complex>(&self, desc: &PlanDesc) -> Result<B::C2cPlan<T>, B::Error>;
fn plan_r2c<F: Real>(&self, desc: &PlanDesc) -> Result<B::R2cPlan<F>, B::Error>;
fn plan_c2r<F: Real>(&self, desc: &PlanDesc) -> Result<B::C2rPlan<F>, B::Error>;
fn synchronize(&self) -> Result<(), B::Error>;
}
pub trait BufferOps<B: Backend, T: Scalar>: Sized {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn write(&mut self, src: &[T]) -> Result<(), B::Error>;
fn read(&self, dst: &mut [T]) -> Result<(), B::Error>;
}
pub trait C2cPlanOps<B: Backend, T: Complex>: Sized {
fn execute(&mut self, buffer: &mut B::Buffer<T>, direction: Direction) -> Result<(), B::Error>;
}
pub trait R2cPlanOps<B: Backend, F: Real>: Sized {
fn execute(
&mut self,
input: &B::Buffer<F>,
output: &mut B::Buffer<F::Complex>,
) -> Result<(), B::Error>;
}
pub trait C2rPlanOps<B: Backend, F: Real>: Sized {
fn execute(
&mut self,
input: &B::Buffer<F::Complex>,
output: &mut B::Buffer<F>,
) -> Result<(), B::Error>;
}