Skip to main content

KernelPattern

Enum KernelPattern 

Source
pub enum KernelPattern {
Show 17 variants MatMul { inputs: [TensorBinding; 2], output: TensorBinding, shape: MatMulShape, }, ElementWise { op: ElementWiseOp, inputs: [TensorBinding; 2], output: TensorBinding, dim_name: String, }, ElementWiseChain { base: TensorBinding, cast: Option<i32>, steps: Vec<ChainStep>, output: TensorBinding, dim_name: String, }, Conv2D { input: TensorBinding, weight: TensorBinding, output: TensorBinding, bias: Option<TensorBinding>, shape: Conv2DShape, activation: Option<ActivationOp>, }, Pool { kind: PoolKind, input: TensorBinding, output: TensorBinding, shape: PoolShape, }, Activation { op: ActivationOp, input: TensorBinding, output: TensorBinding, dim_name: String, }, Reduce { op: ReduceOp, input: TensorBinding, output: TensorBinding, axis: i64, }, Transpose { input: TensorBinding, output: TensorBinding, perm: Vec<i64>, }, Reshape { input: TensorBinding, output: TensorBinding, }, Normalization { input: TensorBinding, scale: TensorBinding, bias: TensorBinding, output: TensorBinding, epsilon: f32, norm_type: NormType, }, Concat { inputs: Vec<TensorBinding>, output: TensorBinding, axis: i64, }, Split { input: TensorBinding, outputs: Vec<TensorBinding>, axis: i64, }, Attention { query: TensorBinding, key: TensorBinding, value: TensorBinding, output: TensorBinding, d_k: String, seq_len: String, num_heads: u32, num_kv_heads: u32, causal: bool, }, Gather { data: TensorBinding, indices: TensorBinding, output: TensorBinding, axis: i64, }, Scatter { data: TensorBinding, indices: TensorBinding, updates: TensorBinding, output: TensorBinding, axis: i64, }, QuantizedMatMul { input: TensorBinding, weight: TensorBinding, scale: TensorBinding, bias: Option<TensorBinding>, output: TensorBinding, shape: MatMulShape, }, Unknown { reason: String, },
}
Expand description

A classified kernel pattern that maps to ONNX operators.

Variants§

§

MatMul

Loop + accumulation + 2 read arrays + 1 write array → ONNX MatMul.

Fields

§inputs: [TensorBinding; 2]
§

ElementWise

No loop + binary op on arrays → ONNX Add/Sub/Mul/Div.

Fields

§inputs: [TensorBinding; 2]
§dim_name: String
§

ElementWiseChain

A per-element expression one level deeper than a binary op: one tensor, an optional conversion, and a short chain of element-wise steps whose operands are whole tensors or dispatch-time scalars.

Two shapes in the vendored corpus need this and nothing narrower:

  • axpy, output[i] = y[i] + a * x[i] with a a uniform scalar — x, scaled, then added to y.
  • dequantize, output[i] = f32(input[i]) * s1 * s2 with two uniform scalars — a conversion, then two scales.

Neither is one operation over two tensors, and Self::ElementWise holds exactly two operands and one op, so both were refused. Neither is a fused activation either: nothing here is a unary function of one element, so widening Activation would not have held them.

The chain is deliberately linear. Every node has exactly one operand that is not a leaf, which is what makes it a sequence of graph nodes rather than a tree; snake and alibi, whose multiplies have two non-leaf operands, do not match and stay refused.

Fields

§base: TensorBinding

The tensor the chain starts from.

§cast: Option<i32>

The element type base is converted to before the first step, when the kernel converts it. dequantize reads array<i32> and writes array<f32>, and dropping the conversion would reinterpret bits.

§steps: Vec<ChainStep>

Applied in order, each as acc = acc <op> operand.

§dim_name: String
§

Conv2D

2D convolution: nested loops + kernel window + accumulation.

Fields

§bias: Option<TensorBinding>

Per-output-channel bias, when the kernel has one.

Optional because a convolution need not have a bias, not because dropping it is acceptable: a backend that cannot emit one must refuse rather than silently compute a convolution without it.

§activation: Option<ActivationOp>

The activation the kernel applies to what it stores.

output[i] = max(sum, 0.0) is a convolution and a ReLU, and this was silently dropped: the emitted model held a CONV_2D and nothing else, so it loaded, was accelerated, and returned unclipped values. The TFLite backend folds it into Conv2DOptions; a backend that cannot express it must say so rather than emit the convolution alone.

§

Pool

Pooling: nested loops + reduction over spatial window.

Fields

§

Activation

Activation function: no loop, single input, unary math op.

Fields

§dim_name: String
§

Reduce

Reduction over an axis: loop + accumulation, single input.

Fields

§axis: i64
§

Transpose

Transpose: permute tensor axes.

Fields

§perm: Vec<i64>
§

Reshape

Reshape: change tensor shape without data copy.

Fields

§

Normalization

Normalization: mean + variance + scale + bias.

Fields

§epsilon: f32
§norm_type: NormType
§

Concat

Concatenation of multiple inputs along an axis.

Fields

§axis: i64
§

Split

Split a single input into multiple outputs along an axis.

Fields

§axis: i64
§

Attention

Scaled dot-product attention.

Fields

§seq_len: String
§num_heads: u32

Number of attention heads (1 = single-head).

§num_kv_heads: u32

Number of K/V heads (for GQA; equals num_heads for MHA).

§causal: bool

Whether a causal mask is applied.

§

Gather

Gather: index into data tensor using indices.

Fields

§axis: i64
§

Scatter

Scatter: write updates into output tensor at given indices.

Fields

§axis: i64
§

QuantizedMatMul

A matrix multiplication whose right operand arrives as integer codes with one scale per output channel: output = input @ (weight * scale)ᵀ.

This is not Self::MatMul with an odd element type. A dense matmul has two operands; this has three, and the third is not a second matrix. scale carries one factor per row of the weight, so it multiplies the contraction’s result rather than participating in the contraction. Lowering it as a MatMul over weight and dropping scale would produce a graph whose every output is wrong by a per-channel factor, which is the failure a refusal is preferable to.

The weight’s rows are the output channels, so the contraction runs along the second axis of both operands and the lowerings transpose it. That is the layout every quantized kernel in the vendored corpus uses, and the one per-channel quantization is defined against: a scale per row is a scale per output feature only if a row is an output feature.

weight is reported with an element type of INT8 although the buffer the kernel binds is array<u32>. Four two’s-complement codes are packed per word, least-significant byte first, which is the byte layout of a contiguous i8 row. The packing is how the GPU kernel buys four columns per memory transaction; it is not part of what the kernel computes, and the graph names the codes rather than the words they arrived in.

Fields

§input: TensorBinding

The f32 activations, [m, k].

§weight: TensorBinding

The integer codes, [n, k] — one row per output channel.

§scale: TensorBinding

f32, [n] — one scale per weight row, applied after the contraction.

§bias: Option<TensorBinding>

A per-output-channel addend the kernel fuses onto the result.

matvec/q8_residual adds a residual after the row scale. Optional because a quantized matmul need not have one, not because dropping it is acceptable — the same rule Self::Conv2D’s bias carries.

§

Unknown

Unrecognized pattern — classification could not determine a known op.

Fields

§reason: String

Trait Implementations§

Source§

impl Clone for KernelPattern

Source§

fn clone(&self) -> KernelPattern

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for KernelPattern

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for KernelPattern

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.