pub(crate) mod op_prep;
mod emulation;
pub mod npu;
mod typecheck;
use std::fmt::Debug;
use furiosa_mapping::Mapping as MappingValue;
use furiosa_mapping::*;
use crate::cast::ContractionCast;
use crate::scalar::{MaterializableScalar, Scalar};
use crate::tensor::memory::{HbmTensor, HostTensor};
pub use emulation::Emulation;
pub use npu::Npu;
pub use typecheck::Typecheck;
pub trait Backend: Sized + 'static {
type Storage<D: Scalar>: Clone + Debug + PartialEq;
fn from_vec<D: Scalar>(mapping: &MappingValue, data: impl IntoIterator<Item = D>) -> Self::Storage<D>;
fn from_buf<D: Scalar>(mapping: &MappingValue, buf: Vec<u8>) -> Self::Storage<D> {
Self::from_vec(mapping, (0..mapping.size()).map(|i| D::load(&buf, i)))
}
fn uninit<D: Scalar>(mapping: &MappingValue) -> Self::Storage<D>;
fn into_vec<D: MaterializableScalar>(storage: Self::Storage<D>, mapping: &MappingValue) -> Vec<D>;
fn into_buf<D: MaterializableScalar>(storage: Self::Storage<D>, mapping: &MappingValue) -> Vec<u8> {
D::to_buf(&Self::into_vec(storage, mapping))
}
fn map<D: MaterializableScalar, D2: Scalar>(
src: &Self::Storage<D>,
f: impl Fn(D) -> D2 + Sync,
) -> Self::Storage<D2>;
fn map_bounded<D: Scalar, D2: Scalar>(
src: &Self::Storage<D>,
len: usize,
f: impl Fn(D) -> D2 + Sync,
) -> Self::Storage<D2>;
fn zip_with<D: MaterializableScalar, D2: MaterializableScalar, D3: Scalar>(
a: &Self::Storage<D>,
b: &Self::Storage<D2>,
f: impl Fn(D, D2) -> D3 + Sync,
) -> Self::Storage<D3>;
fn zip3_with<D: MaterializableScalar, D2: MaterializableScalar, D3: MaterializableScalar, D4: Scalar>(
a: &Self::Storage<D>,
b: &Self::Storage<D2>,
c: &Self::Storage<D3>,
f: impl Fn(D, D2, D3) -> D4 + Sync,
) -> Self::Storage<D4>;
#[allow(clippy::too_many_arguments)]
fn transpose<D: Scalar, Src: M, Dst: M>(
dst: &mut Self::Storage<D>,
src: &Self::Storage<D>,
src_offset: &Index,
dst_offset: &Index,
src_map: &MappingValue,
dst_map: &MappingValue,
allow_broadcast: bool,
);
fn reduce<D: MaterializableScalar, Src: M, Dst: M>(
src: &Self::Storage<D>,
reduce_fn: impl Fn(D, D) -> D + Sync,
identity: D,
allow_broadcast: bool,
) -> Self::Storage<D>;
fn contraction<D: ContractionCast + MaterializableScalar>(
lhs: &Self::Storage<D>,
rhs: &Self::Storage<D>,
lhs_map: &MappingValue,
rhs_map: &MappingValue,
pre_reduce: &MappingValue,
out: &MappingValue,
) -> Self::Storage<D>;
fn scatter<D: Scalar, Src: M, Key: M, Dst: M, Idx: M>(
src: &Self::Storage<D>,
dst: &mut Self::Storage<D>,
index: &Self::Storage<i32>,
scaled: bool,
);
fn gather<D: MaterializableScalar, Src: M, Dst: M, Idx: M>(
src: &Self::Storage<D>,
dst: &mut Self::Storage<D>,
index: &Self::Storage<i32>,
scaled: bool,
);
fn reshape<D: Scalar, Src: M, Dst: M>(src: &Self::Storage<D>) -> Self::Storage<D>;
fn transmute<D: MaterializableScalar, Src: M, Dst: M>(
storage: Self::Storage<D>,
src_map: &MappingValue,
dst_map: &MappingValue,
) -> Self::Storage<D>;
fn to_hbm<D: MaterializableScalar, Element: M, Chip: M, Element2: M>(
host: &HostTensor<D, Element, Self>,
) -> impl std::future::Future<Output = HbmTensor<D, Chip, Element2, Self>>;
fn from_hbm<D: MaterializableScalar, Chip: M, Element: M, Element2: M>(
hbm: &HbmTensor<D, Chip, Element, Self>,
) -> impl std::future::Future<Output = HostTensor<D, Element2, Self>>;
fn bind_device(_device: crate::context::Device) {}
}