Expand description
bb::Backend — Contract trait for tensor compute backends.
The Contract has THREE surfaces, exposed side-by-side:
-
One typed method per mandatory primitive op (the 30 entries in
bb_ir::tensor_primitives::TENSOR_PRIMITIVES_OPS):add,mul,matmul,reduce_sum,reshape, …. Components reach these inline throughctx.backendsfor short-form tensor math — an Index’s distance kernel callsbackend.matmul(&query, &vectors)?instead of hand-rolling a loop. -
One method to execute a subgraph:
execute(&GraphProto, HashMap<String, Tensor>, BackendAttrs) → HashMap<String, Tensor>. Backends that prefer whole-graph dispatch override this entry point; the per-op defaults call through to it via a one-nodeGraphProto. -
One dispatch entry point for
BackendSubgraphcarriers:dispatch(&GraphProto, inputs, attrs, completion) → ContractResponse. The engine calls this for everyBackendSubgraphcarrier op. The default falls through toexecutesynchronously. Backends with per-subgraph caching, JIT compilation, or async device execution overridedispatchto returnContractResponse::Laterwhile device work runs.
§How the two sides compose
Default impls in crate::contracts::backend_default_walk
bridge the surfaces so a backend author overrides only the side
that’s natural for their target:
-
CpuBackend overrides the 30 per-op methods directly (
addruns ndarray’sAddimpl,matmulrunsdot, …). It does NOT overrideexecute— the default walker uses the overridden per-op methods. -
A Burn-style backend overrides
executenatively (Burn compiles the wholeGraphPrototo its own IR + runs once). It does NOT override per-op methods — they default-wrap a one-nodeGraphProtoand callexecute.
Backends overriding neither side stack-overflow on the first
call: every per-op default wraps into execute, whose default
walks back to per-op, ad infinitum. Backends MUST override at
least one side.
§Extension ops
Activation functions (Relu, Sigmoid, Softmax), pooling (MaxPool,
AveragePool), normalization (BatchNormalization, LayerNorm),
Conv, and so on are NOT on the Contract surface. They’re
extensions — a backend MAY declare them via
crate::roles::BackendRuntime::extension_opsets and handle
them through its own execute override; OR a future lowering
pass decomposes them into primitives so the Contract surface
covers any graph.
Structs§
- Backend
Attrs - Per-call NodeProto context surfaced to
Backend::executeso kernels overriding the whole-graph path see the original call site’s attributes + metadata alongside the body. Per-op methods (which receive their attributes positionally as typed args) don’t need this struct.
Traits§
- Backend
- User-facing Contract trait for a tensor compute backend.