pub trait ComputeBackend:
Send
+ Sync
+ Debug {
Show 24 methods
// Required methods
fn name(&self) -> &str;
fn init(&mut self) -> BackendResult<()>;
fn is_initialized(&self) -> bool;
fn gemm(
&self,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f64,
a_ptr: u64,
lda: usize,
b_ptr: u64,
ldb: usize,
beta: f64,
c_ptr: u64,
ldc: usize,
) -> BackendResult<()>;
fn conv2d_forward(
&self,
input_ptr: u64,
input_shape: &[usize],
filter_ptr: u64,
filter_shape: &[usize],
output_ptr: u64,
output_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()>;
fn attention(
&self,
q_ptr: u64,
k_ptr: u64,
v_ptr: u64,
o_ptr: u64,
batch: usize,
heads: usize,
seq_q: usize,
seq_kv: usize,
head_dim: usize,
scale: f64,
causal: bool,
) -> BackendResult<()>;
fn reduce(
&self,
op: ReduceOp,
input_ptr: u64,
output_ptr: u64,
shape: &[usize],
axis: usize,
) -> BackendResult<()>;
fn unary(
&self,
op: UnaryOp,
input_ptr: u64,
output_ptr: u64,
n: usize,
) -> BackendResult<()>;
fn binary(
&self,
op: BinaryOp,
a_ptr: u64,
b_ptr: u64,
output_ptr: u64,
n: usize,
) -> BackendResult<()>;
fn synchronize(&self) -> BackendResult<()>;
fn alloc(&self, bytes: usize) -> BackendResult<u64>;
fn free(&self, ptr: u64) -> BackendResult<()>;
fn copy_htod(&self, dst: u64, src: &[u8]) -> BackendResult<()>;
fn copy_dtoh(&self, dst: &mut [u8], src: u64) -> BackendResult<()>;
// Provided methods
fn capabilities(&self) -> Capabilities { ... }
fn available_devices(&self) -> BackendResult<Vec<DeviceInfo>> { ... }
fn recommended_tile_for(&self, m: usize, n: usize, k: usize) -> TileShape { ... }
fn gemm_mixed_precision(
&self,
prec: MixedPrecision,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f32,
a_ptr: u64,
lda: usize,
b_ptr: u64,
ldb: usize,
beta: f32,
c_ptr: u64,
ldc: usize,
) -> BackendResult<()> { ... }
fn conv2d_backward_data(
&self,
grad_output_ptr: u64,
grad_output_shape: &[usize],
filter_ptr: u64,
filter_shape: &[usize],
grad_input_ptr: u64,
grad_input_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()> { ... }
fn conv2d_backward_filter(
&self,
input_ptr: u64,
input_shape: &[usize],
grad_output_ptr: u64,
grad_output_shape: &[usize],
grad_filter_ptr: u64,
grad_filter_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()> { ... }
fn softmax(
&self,
input_ptr: u64,
output_ptr: u64,
shape: &[usize],
axis: usize,
) -> BackendResult<()> { ... }
fn gather(
&self,
input_ptr: u64,
indices: &[usize],
output_ptr: u64,
rows: usize,
cols: usize,
) -> BackendResult<()> { ... }
fn scatter(
&self,
input_ptr: u64,
indices: &[usize],
output_ptr: u64,
rows: usize,
cols: usize,
) -> BackendResult<()> { ... }
fn batched_gemm(
&self,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f64,
a_ptr: u64,
lda: usize,
stride_a: usize,
b_ptr: u64,
ldb: usize,
stride_b: usize,
beta: f64,
c_ptr: u64,
ldc: usize,
stride_c: usize,
batch_count: usize,
) -> BackendResult<()> { ... }
}Expand description
Abstract compute backend trait.
Implementations provide GPU-accelerated compute operations.
All operations work with opaque device memory pointers (u64)
and explicit shape/stride information, making the trait
independent of any particular memory management scheme.
§Object Safety
This trait is object-safe and can be used as Box<dyn ComputeBackend>
or &dyn ComputeBackend for dynamic dispatch.
§Lifecycle
Required Methods§
Sourcefn init(&mut self) -> BackendResult<()>
fn init(&mut self) -> BackendResult<()>
Initialize the backend (select device, create context).
Must be called before any other operation. Calling init on an
already-initialized backend is a no-op.
Sourcefn is_initialized(&self) -> bool
fn is_initialized(&self) -> bool
Returns true if the backend is ready for operations.
Sourcefn gemm(
&self,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f64,
a_ptr: u64,
lda: usize,
b_ptr: u64,
ldb: usize,
beta: f64,
c_ptr: u64,
ldc: usize,
) -> BackendResult<()>
fn gemm( &self, trans_a: BackendTranspose, trans_b: BackendTranspose, m: usize, n: usize, k: usize, alpha: f64, a_ptr: u64, lda: usize, b_ptr: u64, ldb: usize, beta: f64, c_ptr: u64, ldc: usize, ) -> BackendResult<()>
General matrix multiply: C = alpha * op(A) * op(B) + beta * C.
§Arguments
trans_a,trans_b— transpose modes for A and B.m,n,k— matrix dimensions (C is m×n, A is m×k, B is k×n after transpose).alpha,beta— scaling factors.a_ptr,b_ptr,c_ptr— device pointers to column-major f64 matrices.lda,ldb,ldc— leading dimensions.
Sourcefn conv2d_forward(
&self,
input_ptr: u64,
input_shape: &[usize],
filter_ptr: u64,
filter_shape: &[usize],
output_ptr: u64,
output_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()>
fn conv2d_forward( &self, input_ptr: u64, input_shape: &[usize], filter_ptr: u64, filter_shape: &[usize], output_ptr: u64, output_shape: &[usize], stride: &[usize], padding: &[usize], ) -> BackendResult<()>
2D convolution forward pass.
§Arguments
input_ptr— device pointer to input tensor (NCHW layout).input_shape—[N, C, H, W].filter_ptr— device pointer to filter tensor.filter_shape—[K, C, Fh, Fw].output_ptr— device pointer to output tensor.output_shape—[N, K, Oh, Ow].stride—[sh, sw].padding—[ph, pw].
Sourcefn attention(
&self,
q_ptr: u64,
k_ptr: u64,
v_ptr: u64,
o_ptr: u64,
batch: usize,
heads: usize,
seq_q: usize,
seq_kv: usize,
head_dim: usize,
scale: f64,
causal: bool,
) -> BackendResult<()>
fn attention( &self, q_ptr: u64, k_ptr: u64, v_ptr: u64, o_ptr: u64, batch: usize, heads: usize, seq_q: usize, seq_kv: usize, head_dim: usize, scale: f64, causal: bool, ) -> BackendResult<()>
Scaled dot-product attention.
Computes softmax(Q * K^T / scale) * V with optional causal masking.
§Arguments
q_ptr,k_ptr,v_ptr— device pointers to query, key, value tensors.o_ptr— device pointer to output tensor.batch,heads— batch size and number of attention heads.seq_q,seq_kv— query and key/value sequence lengths.head_dim— dimension of each attention head.scale— attention scale factor (typically1 / sqrt(head_dim)).causal— iftrue, apply causal (lower-triangular) mask.
Sourcefn reduce(
&self,
op: ReduceOp,
input_ptr: u64,
output_ptr: u64,
shape: &[usize],
axis: usize,
) -> BackendResult<()>
fn reduce( &self, op: ReduceOp, input_ptr: u64, output_ptr: u64, shape: &[usize], axis: usize, ) -> BackendResult<()>
Reduction along an axis.
Reduces input along axis using the specified op and writes to output.
Sourcefn unary(
&self,
op: UnaryOp,
input_ptr: u64,
output_ptr: u64,
n: usize,
) -> BackendResult<()>
fn unary( &self, op: UnaryOp, input_ptr: u64, output_ptr: u64, n: usize, ) -> BackendResult<()>
Element-wise unary operation.
Applies op to each of the n elements at input_ptr and writes to output_ptr.
Sourcefn binary(
&self,
op: BinaryOp,
a_ptr: u64,
b_ptr: u64,
output_ptr: u64,
n: usize,
) -> BackendResult<()>
fn binary( &self, op: BinaryOp, a_ptr: u64, b_ptr: u64, output_ptr: u64, n: usize, ) -> BackendResult<()>
Element-wise binary operation.
Applies op element-wise: output[i] = op(a[i], b[i]) for n elements.
Sourcefn synchronize(&self) -> BackendResult<()>
fn synchronize(&self) -> BackendResult<()>
Synchronize all pending operations on this backend.
Blocks the host until all previously submitted GPU work completes.
Sourcefn alloc(&self, bytes: usize) -> BackendResult<u64>
fn alloc(&self, bytes: usize) -> BackendResult<u64>
Allocate device memory.
Returns an opaque device pointer. The caller is responsible for
eventually calling free.
Sourcefn free(&self, ptr: u64) -> BackendResult<()>
fn free(&self, ptr: u64) -> BackendResult<()>
Free device memory previously allocated with alloc.
Provided Methods§
Sourcefn capabilities(&self) -> Capabilities
fn capabilities(&self) -> Capabilities
Report this backend’s capabilities (precision support, Tensor Cores, unified memory, thread/shared-memory limits, …).
The default is the conservative CPU profile; GPU backends override it with values read from their driver.
Sourcefn available_devices(&self) -> BackendResult<Vec<DeviceInfo>>
fn available_devices(&self) -> BackendResult<Vec<DeviceInfo>>
Enumerate the devices this backend exposes, in a backend-agnostic
DeviceInfo shape.
The default returns an empty list (a backend that cannot enumerate
devices, e.g. a pure trait stub). Real backends override it; the
CpuBackend reports a single host device.
Sourcefn recommended_tile_for(&self, m: usize, n: usize, k: usize) -> TileShape
fn recommended_tile_for(&self, m: usize, n: usize, k: usize) -> TileShape
Suggest a GEMM tile shape (tile_m, tile_n, tile_k) for the given
problem dimensions, to seed an autotuner.
The default heuristic scales the tile with the problem size and snaps
to a WMMA-aligned tile when capabilities
reports Tensor Cores. Backends may override with hardware-specific
shapes.
Sourcefn gemm_mixed_precision(
&self,
prec: MixedPrecision,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f32,
a_ptr: u64,
lda: usize,
b_ptr: u64,
ldb: usize,
beta: f32,
c_ptr: u64,
ldc: usize,
) -> BackendResult<()>
fn gemm_mixed_precision( &self, prec: MixedPrecision, trans_a: BackendTranspose, trans_b: BackendTranspose, m: usize, n: usize, k: usize, alpha: f32, a_ptr: u64, lda: usize, b_ptr: u64, ldb: usize, beta: f32, c_ptr: u64, ldc: usize, ) -> BackendResult<()>
Mixed-precision GEMM: C = alpha * op(A) * op(B) + beta * C where the
A/B operands are stored in a reduced 16-bit format
(MixedPrecision::F16 or MixedPrecision::Bf16) but the dot
products accumulate in f32 — the Tensor-Core / WMMA contract.
Unlike gemm (column-major f64), this operates on
column-major f32 buffers, matching the f32 storage every GPU
uploads to a half/bfloat16 GEMM. The CPU reference emulates the 16-bit
storage by rounding each input element to the target format
(round-to-nearest, ties-to-even) before the f32 accumulation, so its
output equals what a real reduced-precision kernel would produce.
§Arguments
prec— input storage format (f16orbf16); the accumulator and outputCare alwaysf32.trans_a,trans_b— transpose modes for A and B.m,n,k— matrix dimensions (C is m×n, A is m×k, B is k×n after transpose).alpha,beta— scaling factors (applied inf32).a_ptr,b_ptr,c_ptr— device pointers to column-majorf32matrices.lda,ldb,ldc— leading dimensions.
The default implementation returns BackendError::Unsupported; the
CpuBackend implements the reference math, and GPU backends override
it with a Tensor-Core kernel.
Sourcefn conv2d_backward_data(
&self,
grad_output_ptr: u64,
grad_output_shape: &[usize],
filter_ptr: u64,
filter_shape: &[usize],
grad_input_ptr: u64,
grad_input_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()>
fn conv2d_backward_data( &self, grad_output_ptr: u64, grad_output_shape: &[usize], filter_ptr: u64, filter_shape: &[usize], grad_input_ptr: u64, grad_input_shape: &[usize], stride: &[usize], padding: &[usize], ) -> BackendResult<()>
Backward pass of conv2d_forward w.r.t. the
input (data gradient): given the upstream gradient grad_output,
produce grad_input of the same shape as the forward input.
Mathematically this is the full convolution of grad_output with the
spatially-flipped filter (equivalently, the transpose of the forward
im2col matrix applied to the upstream gradient). All tensors are
row-major f32 in NCHW / KCHW layout, matching
conv2d_forward.
§Arguments
grad_output_ptr/grad_output_shape— upstream gradient,[N, K, Oh, Ow].filter_ptr/filter_shape— forward filter,[K, C, Fh, Fw].grad_input_ptr/grad_input_shape— output data gradient,[N, C, H, W].stride—[sh, sw];padding—[ph, pw](same as the forward pass).
The default returns BackendError::Unsupported; the CpuBackend
implements the reference math.
Sourcefn conv2d_backward_filter(
&self,
input_ptr: u64,
input_shape: &[usize],
grad_output_ptr: u64,
grad_output_shape: &[usize],
grad_filter_ptr: u64,
grad_filter_shape: &[usize],
stride: &[usize],
padding: &[usize],
) -> BackendResult<()>
fn conv2d_backward_filter( &self, input_ptr: u64, input_shape: &[usize], grad_output_ptr: u64, grad_output_shape: &[usize], grad_filter_ptr: u64, grad_filter_shape: &[usize], stride: &[usize], padding: &[usize], ) -> BackendResult<()>
Backward pass of conv2d_forward w.r.t. the
filter (weight gradient): given the forward input and the upstream
gradient grad_output, produce grad_filter of the same shape as the
forward filter.
Mathematically this is the correlation of input with grad_output
(the forward im2col matrix multiplied by the upstream gradient). All
tensors are row-major f32 in NCHW / KCHW layout, matching
conv2d_forward.
§Arguments
input_ptr/input_shape— forward input,[N, C, H, W].grad_output_ptr/grad_output_shape— upstream gradient,[N, K, Oh, Ow].grad_filter_ptr/grad_filter_shape— output weight gradient,[K, C, Fh, Fw].stride—[sh, sw];padding—[ph, pw](same as the forward pass).
The default returns BackendError::Unsupported; the CpuBackend
implements the reference math.
Sourcefn softmax(
&self,
input_ptr: u64,
output_ptr: u64,
shape: &[usize],
axis: usize,
) -> BackendResult<()>
fn softmax( &self, input_ptr: u64, output_ptr: u64, shape: &[usize], axis: usize, ) -> BackendResult<()>
Numerically-stable softmax along axis of the tensor described by
shape (row-major, f32).
The default implementation returns
BackendError::Unsupported;
the CpuBackend implements it directly, and GPU backends override
it with a fused kernel. Consumers that need softmax on a backend that
does not provide it can still compose it from
reduce(Max) + unary(Exp) + reduce(Sum) + binary(Div).
Sourcefn gather(
&self,
input_ptr: u64,
indices: &[usize],
output_ptr: u64,
rows: usize,
cols: usize,
) -> BackendResult<()>
fn gather( &self, input_ptr: u64, indices: &[usize], output_ptr: u64, rows: usize, cols: usize, ) -> BackendResult<()>
Row-gather: copy the rows named by indices out of a rows × cols
(f32, row-major) table into a contiguous output of
indices.len() × cols.
Needed by embedding tables and MoE routing. The default returns
BackendError::Unsupported.
Sourcefn scatter(
&self,
input_ptr: u64,
indices: &[usize],
output_ptr: u64,
rows: usize,
cols: usize,
) -> BackendResult<()>
fn scatter( &self, input_ptr: u64, indices: &[usize], output_ptr: u64, rows: usize, cols: usize, ) -> BackendResult<()>
Row-scatter: write each input row (indices.len() × cols, f32) into
output at the destination row given by indices, preserving
unreferenced rows of the rows × cols output table.
The inverse routing primitive to gather. The default
returns BackendError::Unsupported.
Sourcefn batched_gemm(
&self,
trans_a: BackendTranspose,
trans_b: BackendTranspose,
m: usize,
n: usize,
k: usize,
alpha: f64,
a_ptr: u64,
lda: usize,
stride_a: usize,
b_ptr: u64,
ldb: usize,
stride_b: usize,
beta: f64,
c_ptr: u64,
ldc: usize,
stride_c: usize,
batch_count: usize,
) -> BackendResult<()>
fn batched_gemm( &self, trans_a: BackendTranspose, trans_b: BackendTranspose, m: usize, n: usize, k: usize, alpha: f64, a_ptr: u64, lda: usize, stride_a: usize, b_ptr: u64, ldb: usize, stride_b: usize, beta: f64, c_ptr: u64, ldc: usize, stride_c: usize, batch_count: usize, ) -> BackendResult<()>
Strided batched GEMM: for each batch b in 0..batch_count,
compute C_b = alpha * op(A_b) * op(B_b) + beta * C_b
where A_b starts at a_ptr + b * stride_a * 4 bytes (f32 elements), etc.
§Arguments
trans_a,trans_b— transpose modes for A and B.m,n,k— matrix dimensions (C is m×n).alpha,beta— scaling factors.a_ptr,b_ptr,c_ptr— device pointers to the first matrix in each batch.lda,ldb,ldc— leading dimensions.stride_a,stride_b,stride_c— element strides between consecutive matrices.batch_count— number of GEMM operations in the batch.
The default implementation dispatches batch_count individual
gemm calls with pointer offsets.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementations on Foreign Types§
Source§impl<T: ComputeBackend + ?Sized> ComputeBackend for &mut T
Forward every ComputeBackend method through a mutable reference, so
callers holding &mut dyn ComputeBackend (or &mut T) can pass it where
a ComputeBackend is expected without re-boxing.
impl<T: ComputeBackend + ?Sized> ComputeBackend for &mut T
Forward every ComputeBackend method through a mutable reference, so
callers holding &mut dyn ComputeBackend (or &mut T) can pass it where
a ComputeBackend is expected without re-boxing.