Skip to main content

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<f64> 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".

Implementors§