fuel-dispatch 0.23.0

Dispatch infrastructure for fuel: KernelBindingTable, per-backend registration wrappers, CompiledNode + compile_node, ExecutionPlan + compile_plan + resolve_kernel, FusedKernelRegistry, PipelinedExecutor. The layer that takes a graph and runs it against registered backends. Extracted from fuel-memory 2026-05-31.
Documentation
---
fkc_version: 1
provider:
  name: fuel-reference-backend
  backend: Cpu                       # the reference oracle runs on the host
  kernel_source: "reference-oracle"  # the BindingEntry.kernel_source tag
  link_registry: fuel_reference_backend::fkc::ENTRY_POINTS  # §12.6 symbol→KernelRef map
  revision_base: "git:f41137b4"      # provider build id, folded into kernel_revision_hash
---

# fuel-reference-backend — convolution & pooling contracts


Reference (correctness-first) contracts for the conv/pool family of the pure-Rust oracle crate
(`fuel-reference-backend`, family `conv-attn` in `_inventory/reference.md`). Every kernel in this
crate is, by the crate-wide invariant, **contiguous-only, zero-offset, row-major** (`RefTensor<T>`
carries no strides and no offset — `lib.rs:68`), so every operand below declares
`contiguous: required` and `awkward_layout_strategy: requires_contiguous`: the planner contiguizes
any non-contiguous producer (pricing the inserted `Op::Contiguize` from its own FKC contract, §4.3)
before these kernels see the buffer. All math is in the generic `T: num_traits::Float` accumulator
(NO f32-accum widening for half), monomorphized to the dtype list the executor wires. Output is
always a fresh contiguous tensor (`RefTensor::from_vec`), aliasing none.

This file is rendered by mdBook and parsed by the FKC importer; the prose is documentation and the
` ```fkc ` block is authoritative (§3.1). Costs are marked `judge_measured` — the Judge bootstraps
them; FLOPs/bandwidth hints are given where genuinely derivable from the op geometry (§4.4) and are
the author's structural prior, not a fabricated calibrated number.

---

## conv2d  (2-D direct convolution; production, registry CONV2D)


Direct NCHW 2-D convolution with groups + optional bias; f32/f64; contiguous; T-precision accumulator.

Direct (im2col-free) 2-D convolution over a packed NCHW input. `x [N, Cin, H, W]`,
`weight [Cout, Cin/groups, Kh, Kw]`, optional `bias [Cout]`. Asymmetric `stride (sh, sw)` and
symmetric zero-`padding (ph, pw)`, grouped via `groups` (`Cin` and `Cout` both divisible by
`groups`; depthwise is the `groups == Cin` case). The kernel validates the geometry (`ConvShape`)
then delegates the inner loops to `fuel_conv::conv2d_direct` (`ops.rs:704`). Output
`[N, Cout, Hout, Wout]` with `Hout = (H + 2·ph − Kh)/sh + 1`, `Wout = (W + 2·pw − Kw)/sw + 1`.

Numerics: the accumulator is the operand dtype `T` (no f32 widening), so bf16/f16 accumulation
drifts versus an f32-accum implementation — this is a correctness oracle that matches the naive
nested-sum, not a numerically-hardened production GEMM. Zero padding contributes literal `T::zero()`
(skipped, not summed). Executor wiring (`exec.rs:1291`) admits **f32/f64 only**; bf16/f16 are
expressible by the generic kernel but the exec arm does not route them, so this contract declares
the exec-admitted dtype set. Perf: dense NCHW walk, output-stationary; cost scales with
`2·N·Cout·(Cin/groups)·Kh·Kw·Hout·Wout` MACs. Known limitation: contiguous-only — any strided or
offset producer is contiguized by the planner first; no internal contiguize, no in-place.

```fkc
kernel: conv2d
op_kind: Conv2D                # OpParams::Conv2D carrier; OpKind::Conv2D (dispatch.rs:122)
blurb: "Direct NCHW 2-D convolution with groups + optional bias; f32/f64; contiguous; T-precision accumulator."
backend: Cpu
kernel_source: "reference-oracle"
entry_point: "fuel_reference_backend::ops::conv2d_f32"   # one per dtype; §12.6
kernel_revision_hash: auto

accept:
  inputs:
    - name: x
      dtypes: [F32, F64]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [N, Cin, H, W]
    - name: weight
      dtypes: [F32, F64]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [Cout, Cin/groups, Kh, Kw]
      shape_constraint: "divisible(x.dim[1], weight.dim[1])"   # Cin divisible by Cin/groups
    - name: bias
      dtypes: [F32, F64]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 1                       # [Cout]
      shape_constraint: "same_as=weight.dim[0]"
      optional: true
  op_params:
    variant: Conv2D               # OpParams::Conv2D (primitive namespace; §3.7)
    fields:
      x_shape:   { kind: "[usize; 4]" }
      w_shape:   { kind: "[usize; 4]" }
      out_shape: { kind: "[usize; 4]" }
      stride:    { kind: "(usize, usize)" }
      padding:   { kind: "(usize, usize)" }
      dilation:  { kind: "(usize, usize)", note: "reference kernel walks dilation=(1,1) only; carried for ABI parity" }
      groups:    { kind: usize, constraint: "x.dim[1] % groups == 0 && weight.dim[0] % groups == 0" }

return:
  outputs:
    - name: out
      dtype_rule: passthrough(x)        # output dtype = input dtype (T)
      shape_rule: conv2d(params)        # [N, Cout, Hout, Wout] from OpParams::Conv2D geometry
      layout_guarantee: contiguous
      aliasing: none

caps:
  awkward_layout_strategy: requires_contiguous   # planner inserts Op::Contiguize (itself an FKC kernel) + sums its cost
  fast_paths:
    - { when: "groups == 1", note: "dense full-conv path; no per-group channel slicing" }
    - { when: "depthwise", note: "groups == Cin: one filter per channel" }
  in_place: false
  alignment_bytes: 64
  access_granularity_bits: 8

cost:
  provenance: judge_measured          # Judge bootstraps; the flops/bytes below are the structural prior
  class: conv
  # MACs = N * Cout * (Cin/groups) * Kh * Kw * Hout * Wout; 2 flops per MAC (mul + add)
  flops: "2 * out_shape[0] * out_shape[1] * (x_shape[1] / groups) * w_shape[2] * w_shape[3] * out_shape[2] * out_shape[3]"
  bytes_moved: "(x_shape[0]*x_shape[1]*x_shape[2]*x_shape[3] + w_shape[0]*w_shape[1]*w_shape[2]*w_shape[3] + out_shape[0]*out_shape[1]*out_shape[2]*out_shape[3]) * dtype_bytes"
  overhead_ns: ~                      # launch cost (host call + ConvShape validation) not authored — judge_measured
  memory: { device_bytes: 0, host_bytes: "out_shape[0]*out_shape[1]*out_shape[2]*out_shape[3] * dtype_bytes", disk_bytes: 0 }

precision:
  bit_stable_on_same_hardware: true   # deterministic nested loop, fixed accumulation order
  max_ulp: ~
  max_relative: ~
  max_absolute: ~
  audited: true
  notes: "T-precision accumulator (NO f32 widening for half); deterministic fixed summation order; zero padding adds T::zero(). Matches naive direct conv, not an f32-accum production GEMM."

determinism: same_hardware_bitwise
```

---

## conv_transpose2d  (2-D transposed convolution; registry CONV_TRANSPOSE2D)


Scatter-form NCHW 2-D transposed convolution with groups; f32/f64; contiguous; T-precision accumulator.

Textbook 2-D transposed convolution ("deconv") in scatter form: each input pixel is scattered into
a `Kh × Kw` output region through every kernel position (`ops.rs:751`). `x [N, Cin, H, W]`,
`weight [Cin, Cout/groups, Kh, Kw]` (note the **transposed channel order** versus `conv2d` — `Cin`
leads). Asymmetric `stride`, `padding`, `output_padding`, and `dilation` (all `(h, w)`), grouped via
`groups` (`Cin` divisible by `groups`). Output `[N, Cout, Hout, Wout]` with
`Hout = (H − 1)·sh − 2·ph + dh·(Kh − 1) + oph + 1` and the symmetric `Wout`.

Numerics: scatter-accumulate into a zero-initialized output buffer in operand dtype `T` (no f32
widening). Because the accumulation order over scattered contributions is fixed by the nested loop,
the result is deterministic and same-hardware bit-stable, but half-precision accumulation drifts
versus an f32-accum form. The kernel asserts the padding does not exceed the produced unpadded
dims. Executor wiring (`exec.rs:1322`) admits **f32/f64 only**; this contract declares that set.
Perf: scatter form is slower than a gather/im2col deconv (`O(N·Cin·H·W·Cout/groups·Kh·Kw)` writes
with output-overlap accumulation) — a correctness oracle, not a tuned kernel. Known limitation:
contiguous-only; no in-place; the output region overlap means writes are read-modify-write into the
fresh output buffer (still `aliasing: none` — no input is aliased).

```fkc
kernel: conv_transpose2d
op_kind: ConvTranspose2D       # OpParams::ConvTranspose2D carrier; OpKind::ConvTranspose2D (dispatch.rs:127)
blurb: "Scatter-form NCHW 2-D transposed convolution with groups; f32/f64; contiguous; T-precision accumulator."
backend: Cpu
kernel_source: "reference-oracle"
entry_point: "fuel_reference_backend::ops::conv_transpose2d_f32"   # one per dtype; §12.6
kernel_revision_hash: auto

accept:
  inputs:
    - name: x
      dtypes: [F32, F64]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [N, Cin, H, W]
    - name: weight
      dtypes: [F32, F64]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [Cin, Cout/groups, Kh, Kw] — transposed channel order
      shape_constraint: "same_as=x.dim[1]"   # weight.dim[0] (Cin) == x.dim[1] (Cin)
  op_params:
    variant: ConvTranspose2D      # OpParams::ConvTranspose2D (primitive namespace; §3.7)
    fields:
      x_shape:        { kind: "[usize; 4]" }
      w_shape:        { kind: "[usize; 4]" }
      out_shape:      { kind: "[usize; 4]" }
      stride:         { kind: "(usize, usize)" }
      padding:        { kind: "(usize, usize)" }
      output_padding: { kind: "(usize, usize)" }
      dilation:       { kind: "(usize, usize)" }
      groups:         { kind: usize, constraint: "x.dim[1] % groups == 0" }

return:
  outputs:
    - name: out
      dtype_rule: passthrough(x)            # output dtype = input dtype (T)
      shape_rule: conv_transpose2d(params)  # [N, Cout, Hout, Wout] from OpParams::ConvTranspose2D geometry
      layout_guarantee: contiguous
      aliasing: none

caps:
  awkward_layout_strategy: requires_contiguous   # planner inserts Op::Contiguize (itself an FKC kernel) + sums its cost
  fast_paths:
    - { when: "groups == 1", note: "full deconv; no per-group channel slicing" }
  in_place: false
  alignment_bytes: 64
  access_granularity_bits: 8

cost:
  provenance: judge_measured          # Judge bootstraps; the flops/bytes below are the structural prior
  class: conv
  # scatter MACs = N * Cin * H * W * (Cout/groups) * Kh * Kw; 2 flops per MAC (mul + accumulate)
  flops: "2 * x_shape[0] * x_shape[1] * x_shape[2] * x_shape[3] * (w_shape[1]) * w_shape[2] * w_shape[3]"
  bytes_moved: "(x_shape[0]*x_shape[1]*x_shape[2]*x_shape[3] + w_shape[0]*w_shape[1]*w_shape[2]*w_shape[3] + out_shape[0]*out_shape[1]*out_shape[2]*out_shape[3]) * dtype_bytes"
  overhead_ns: ~                      # launch cost not authored — judge_measured
  memory: { device_bytes: 0, host_bytes: "out_shape[0]*out_shape[1]*out_shape[2]*out_shape[3] * dtype_bytes", disk_bytes: 0 }

precision:
  bit_stable_on_same_hardware: true   # deterministic scatter order into zero-init buffer
  max_ulp: ~
  max_relative: ~
  max_absolute: ~
  audited: true
  notes: "T-precision accumulator (NO f32 widening for half); deterministic fixed scatter-accumulation order; output region overlap accumulated into a fresh zero-init buffer."

determinism: same_hardware_bitwise
```

---

## conv2d_simple  (2-D convolution; legacy, no bias/groups — test-only oracle)


Legacy gather-form NCHW 2-D convolution, no bias/groups, scalar stride/padding; f32/f64; contiguous.

Legacy textbook 2-D convolution: gather form, output-stationary, **no bias and no groups**, with a
**scalar** `stride` and **scalar** `padding` (`ops.rs:2209`). `x [N, Cin, H, W]`,
`kernel [Cout, Cin, Kh, Kw]` (full `Cin`, since there are no groups). Symmetric zero padding;
output `[N, Cout, Hout, Wout]` with `Hout = (H + 2·pad − Kh)/stride + 1`, `Wout` symmetric.
Out-of-range (padded) coordinates contribute nothing (skipped). This is the predecessor of the
production `conv2d` above and is retained as a simpler cross-check oracle.

**Status — no dispatch carrier (test-only).** Per the inventory (`reference.md:211`) this kernel is
**not wired in the executor** and has **no `OpKind` and no `OpParams` variant** in `fuel-dispatch`
(only the production `conv2d`/`OpKind::Conv2D` is wired; grep confirms no `Conv2dSimple` op-kind).
The contract below is therefore authored faithfully but, like an MX contract (§6), it
**parse-validates yet is NOT registrable as-is**: §10.7 (op-param variant must be a real
`OpParams` variant) and the required `op_kind` ∈ real `OpKind` both fail because no such variant
exists. The `op_kind` field names the intended `Conv2dSimple` carrier as a forward marker; an
importer returns a `BadOpParamsVariant`/unknown-`OpKind` error (the `MxNotYetRegistrable`-class
discipline) until a dispatch carrier lands or the kernel is folded into `OpKind::Conv2D` with
`groups == 1`. Numerics match `conv2d`: T-precision accumulator, deterministic, contiguous-only.

```fkc
kernel: conv2d_simple
op_kind: Conv2dSimple          # forward marker only; NO such OpKind/OpParams variant exists in fuel-dispatch
                               # (test-only oracle, no dispatch carrier) — describe-only (§3.10)
registrable: false             # §3.10 — documentation-only; not registered, op_kind/op_params not required to resolve
blurb: "Legacy gather-form NCHW 2-D convolution, no bias/groups, scalar stride/padding; f32/f64; contiguous."
backend: Cpu
kernel_source: "reference-oracle"
entry_point: "fuel_reference_backend::ops::conv2d_simple_f32"   # one per dtype; §12.6
kernel_revision_hash: auto

accept:
  inputs:
    - name: x
      dtypes: [F32, F64, BF16, F16]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [N, Cin, H, W]
    - name: kernel
      dtypes: [F32, F64, BF16, F16]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [Cout, Cin, Kh, Kw]
      shape_constraint: "same_as=x.dim[1]"   # kernel.dim[1] (Cin) == x.dim[1] (Cin)
  op_params:
    variant: Conv2dSimple         # [consumer-ahead] NO such OpParams variant; see Status
    fields:
      stride:  { kind: usize, constraint: "stride > 0" }
      padding: { kind: usize }

return:
  outputs:
    - name: out
      dtype_rule: passthrough(x)        # output dtype = input dtype (T)
      shape_rule: "from_params(N=x.dim[0], Cout=kernel.dim[0], Hout=(x.dim[2]+2*padding-kernel.dim[2])/stride+1, Wout=(x.dim[3]+2*padding-kernel.dim[3])/stride+1)"
      layout_guarantee: contiguous
      aliasing: none

caps:
  awkward_layout_strategy: requires_contiguous
  fast_paths: []
  in_place: false
  alignment_bytes: 64
  access_granularity_bits: 8

cost:
  provenance: judge_measured          # Judge bootstraps; the flops/bytes below are the structural prior
  class: conv
  # MACs = N * Cout * Cin * Kh * Kw * Hout * Wout; 2 flops per MAC
  flops: "2 * x.dim[0] * kernel.dim[0] * x.dim[1] * kernel.dim[2] * kernel.dim[3] * out.dim[2] * out.dim[3]"
  bytes_moved: "(x.dim[0]*x.dim[1]*x.dim[2]*x.dim[3] + kernel.dim[0]*kernel.dim[1]*kernel.dim[2]*kernel.dim[3] + out.dim[0]*out.dim[1]*out.dim[2]*out.dim[3]) * dtype_bytes"
  overhead_ns: ~                      # launch cost not authored — judge_measured
  memory: { device_bytes: 0, host_bytes: "out.dim[0]*out.dim[1]*out.dim[2]*out.dim[3] * dtype_bytes", disk_bytes: 0 }

precision:
  bit_stable_on_same_hardware: true
  max_ulp: ~
  max_relative: ~
  max_absolute: ~
  audited: true
  notes: "T-precision accumulator (NO f32 widening for half); deterministic gather summation order; zero padding skipped (contributes 0)."

determinism: same_hardware_bitwise
```

---

## max_pool2d  (2-D max pooling, no padding — test-only oracle)


Per-channel 2-D max pool, square window, no padding, scalar stride; f32/f64/bf16/f16; contiguous; exact (no accumulation).

2-D max pooling on a rank-4 NCHW input with **no padding** (`ops.rs:2301`). For each
`kernel_size × kernel_size` window stepped by **scalar** `stride`, emit the maximum value in the
window. `x [N, C, H, W]`; output `[N, C, Hout, Wout]` with `Hout = (H − kernel_size)/stride + 1`,
`Wout` symmetric. Channels pass through unchanged (pool is per-channel). NaN handling follows the
`T::max` reduction used in the window scan; window max is a pure max-reduction, so the result is
deterministic and same-hardware bit-stable (a max is exact — no rounding, no accumulation).

**Status — no dispatch carrier (test-only).** Per the inventory (`reference.md:212`) this kernel is
**not wired in the executor**. A graph-side `Op::MaxPool2D` exists in `fuel-core`
(`op.rs:93`, fields `kernel_size: (usize, usize)`, `stride: (usize, usize)`), but there is **no
`OpKind::MaxPool2D` and no `OpParams::MaxPool2D` in `fuel-dispatch`** (grep over
`fuel-ir/src` and `fuel-dispatch/src` returns nothing). Note also a shape mismatch the
contract surfaces honestly: the reference oracle takes **scalar** `kernel_size`/`stride` (a square
window, no padding), whereas the graph `Op::MaxPool2D` carries **tuple** `(usize, usize)` for each
and the lazy API (`lazy.rs:3785`) additionally supports padding + pad-value — so this oracle covers
only the square-window, no-padding subset. Like `conv2d_simple`, this contract parse-validates but
is **NOT registrable as-is** (§10.7 fails: no real `OpKind`/`OpParams` variant); an importer returns
the unknown-`OpKind` / `BadOpParamsVariant` error (the `MxNotYetRegistrable`-class discipline) until
a dispatch carrier lands. Contiguous-only; no in-place; fresh output buffer.

```fkc
kernel: max_pool2d
op_kind: MaxPool2D             # forward marker only; NO such OpKind/OpParams in fuel-dispatch (graph Op::MaxPool2D
                               # exists, op.rs:93, but no dispatch carrier; test-only oracle) — describe-only (§3.10)
registrable: false             # §3.10 — documentation-only; not registered, op_kind/op_params not required to resolve
blurb: "Per-channel 2-D max pool, square window, no padding, scalar stride; f32/f64/bf16/f16; contiguous; exact (no accumulation)."
backend: Cpu
kernel_source: "reference-oracle"
entry_point: "fuel_reference_backend::ops::max_pool2d_f32"   # one per dtype; §12.6
kernel_revision_hash: auto

accept:
  inputs:
    - name: x
      dtypes: [F32, F64, BF16, F16]
      layout: { contiguous: required, strided: rejected, broadcast_stride0: rejected, start_offset: rejected, reverse_strides: rejected }
      rank: 4                       # [N, C, H, W]
  op_params:
    variant: MaxPool2D            # [consumer-ahead] NO such OpParams variant; see Status
    fields:
      kernel_size: { kind: usize, constraint: "kernel_size > 0 && kernel_size <= x.dim[2] && kernel_size <= x.dim[3]" }
      stride:      { kind: usize, constraint: "stride > 0" }

return:
  outputs:
    - name: out
      dtype_rule: passthrough(x)        # output dtype = input dtype (T)
      shape_rule: "from_params(N=x.dim[0], C=x.dim[1], Hout=(x.dim[2]-kernel_size)/stride+1, Wout=(x.dim[3]-kernel_size)/stride+1)"
      layout_guarantee: contiguous
      aliasing: none

caps:
  awkward_layout_strategy: requires_contiguous
  fast_paths: []
  in_place: false
  alignment_bytes: 64
  access_granularity_bits: 8

cost:
  provenance: judge_measured          # Judge bootstraps; the bytes/flops below are the structural prior
  class: reduction
  # comparisons = N * C * Hout * Wout * kernel_size^2 (one max-compare per window element)
  flops: "x.dim[0] * x.dim[1] * out.dim[2] * out.dim[3] * kernel_size * kernel_size"
  bytes_moved: "(x.dim[0]*x.dim[1]*x.dim[2]*x.dim[3] + out.dim[0]*out.dim[1]*out.dim[2]*out.dim[3]) * dtype_bytes"
  overhead_ns: ~                      # launch cost not authored — judge_measured
  memory: { device_bytes: 0, host_bytes: "out.dim[0]*out.dim[1]*out.dim[2]*out.dim[3] * dtype_bytes", disk_bytes: 0 }

precision:
  bit_stable_on_same_hardware: true   # max is exact (selection, not accumulation): bit-identical everywhere
  max_ulp: 0
  max_relative: ~
  max_absolute: ~
  audited: true
  notes: "Pure max-reduction over the window: no rounding, no accumulation. Window max is exact; result is bitwise-stable. NaN follows T::max semantics."

determinism: same_hardware_bitwise
```