Backend

Trait Backend 

pub trait Backend:
    Clone
    + Send
    + Sync
    + Debug
    + 'static {
    type Device: BackendDevice;
    type Storage: BackendStorage;

Show 21 methods // Required methods fn zeros( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn ones( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn full( shape: &Shape, val: f64, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn from_f64_slice( data: &[f64], dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn rand_uniform( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn rand_normal( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>; fn binary_op( op: BinaryOp, lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>; fn unary_op( op: UnaryOp, input: &Self::Storage, layout: &Layout, ) -> Result<Self::Storage, Error>; fn reduce_op( op: ReduceOp, input: &Self::Storage, layout: &Layout, dims: &[usize], keep_dim: bool, ) -> Result<Self::Storage, Error>; fn matmul( lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>; fn to_contiguous( input: &Self::Storage, layout: &Layout, ) -> Result<Self::Storage, Error>; fn to_f64_vec( input: &Self::Storage, layout: &Layout, ) -> Result<Vec<f64>, Error>; fn cmp_op( op: CmpOp, lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>; fn affine( input: &Self::Storage, layout: &Layout, mul: f64, add: f64, ) -> Result<Self::Storage, Error>; fn index_select( input: &Self::Storage, input_layout: &Layout, indices: &Self::Storage, indices_layout: &Layout, dim: usize, ) -> Result<Self::Storage, Error>; fn powf( input: &Self::Storage, layout: &Layout, exponent: f64, ) -> Result<Self::Storage, Error>; fn clamp( input: &Self::Storage, layout: &Layout, min: f64, max: f64, ) -> Result<Self::Storage, Error>; fn where_cond( mask: &Self::Storage, mask_layout: &Layout, on_true: &Self::Storage, on_true_layout: &Layout, on_false: &Self::Storage, on_false_layout: &Layout, ) -> Result<Self::Storage, Error>; fn gather( input: &Self::Storage, input_layout: &Layout, index: &Self::Storage, index_layout: &Layout, dim: usize, ) -> Result<Self::Storage, Error>; fn cat( inputs: &[(&Self::Storage, &Layout)], out_shape: &Shape, dim: usize, ) -> Result<Self::Storage, Error>; // Provided method fn cast( input: &Self::Storage, layout: &Layout, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error> { ... }
}
Expand description

Re-export core types. The main Backend trait. Implementing this for a struct (e.g., CpuBackend) makes that struct a complete compute backend for Shrew.

All operations take storage + layout (which encodes shape/strides) and return new storage (immutable semantics — no in-place mutation by default).

Required Associated Types§

type Device: BackendDevice

The device type for this backend.

type Storage: BackendStorage

The storage type for this backend.

Required Methods§

fn zeros( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Allocate storage filled with zeros.

fn ones( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Allocate storage filled with ones.

fn full( shape: &Shape, val: f64, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Allocate storage filled with a constant value.

fn from_f64_slice( data: &[f64], dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Create storage from a flat f64 slice, converting to the target dtype.

fn rand_uniform( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Create storage with random uniform values in [0, 1).

fn rand_normal( shape: &Shape, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Create storage with random normal values (mean=0, std=1).

fn binary_op( op: BinaryOp, lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>

Apply a binary op element-wise: result[i] = op(lhs[i], rhs[i]). The layouts handle broadcasting and non-contiguous access.

fn unary_op( op: UnaryOp, input: &Self::Storage, layout: &Layout, ) -> Result<Self::Storage, Error>

Apply a unary op element-wise: result[i] = op(input[i]).

fn reduce_op( op: ReduceOp, input: &Self::Storage, layout: &Layout, dims: &[usize], keep_dim: bool, ) -> Result<Self::Storage, Error>

Reduce along specific dimensions. If dims is empty, reduce over all elements.

fn matmul( lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>

General matrix multiply: C = A @ B. Supports batched matmul for tensors with rank > 2.

fn to_contiguous( input: &Self::Storage, layout: &Layout, ) -> Result<Self::Storage, Error>

Make a contiguous copy of the storage following the given layout. If the layout is already contiguous, this may just clone the storage.

fn to_f64_vec(input: &Self::Storage, layout: &Layout) -> Result<Vec<f64>, Error>

Copy data from this storage to a Vec on the host (for inspection).

fn cmp_op( op: CmpOp, lhs: &Self::Storage, lhs_layout: &Layout, rhs: &Self::Storage, rhs_layout: &Layout, ) -> Result<Self::Storage, Error>

Element-wise comparison, returns a u8 storage (0 or 1).

fn affine( input: &Self::Storage, layout: &Layout, mul: f64, add: f64, ) -> Result<Self::Storage, Error>

Affine transform: result = input * mul + add. Used for normalization and other fused operations.

fn index_select( input: &Self::Storage, input_layout: &Layout, indices: &Self::Storage, indices_layout: &Layout, dim: usize, ) -> Result<Self::Storage, Error>

Gather elements along a dimension using index tensor.

fn powf( input: &Self::Storage, layout: &Layout, exponent: f64, ) -> Result<Self::Storage, Error>

Element-wise power: result[i] = input[i] ^ exponent.

fn clamp( input: &Self::Storage, layout: &Layout, min: f64, max: f64, ) -> Result<Self::Storage, Error>

Element-wise clamp: result[i] = clamp(input[i], min, max).

fn where_cond( mask: &Self::Storage, mask_layout: &Layout, on_true: &Self::Storage, on_true_layout: &Layout, on_false: &Self::Storage, on_false_layout: &Layout, ) -> Result<Self::Storage, Error>

Element-wise conditional: result[i] = if mask[i] != 0 { on_true[i] } else { on_false[i] }.

fn gather( input: &Self::Storage, input_layout: &Layout, index: &Self::Storage, index_layout: &Layout, dim: usize, ) -> Result<Self::Storage, Error>

Gather elements along dim using index tensor.

output[i][j][k] = input[index[i][j][k]][j][k] (when dim=0) output[i][j][k] = input[i][index[i][j][k]][k] (when dim=1) etc.

index must have the same number of dimensions as input.

fn cat( inputs: &[(&Self::Storage, &Layout)], out_shape: &Shape, dim: usize, ) -> Result<Self::Storage, Error>

Concatenate multiple storages along dim into a single contiguous storage. Each entry is (storage, layout) so non-contiguous inputs are handled correctly. out_shape is the pre-validated output shape.

Provided Methods§

fn cast( input: &Self::Storage, layout: &Layout, dtype: DType, device: &Self::Device, ) -> Result<Self::Storage, Error>

Cast storage to a different dtype on-device (no host round-trip).

The default implementation falls back to to_f64_vec + from_f64_slice, which involves a host round-trip. Backends should override this with a native on-device kernel when possible.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§