tracel-ai/burn · error
matmul: unsupported dtype {:?}
Error message
matmul: unsupported dtype {:?} What it means
The public matmul entry point dispatches on the lhs tensor dtype and supports F32, F64, F16 and BF16 only. Any other dtype (integer dtypes, Bool, etc.) hits the panic arm. Integer matmul exists as a separate int_matmul function.
Source
Thrown at crates/burn-flex/src/ops/matmul.rs:104
let lhs_shape = lhs.layout().shape();
let rhs_shape = rhs.layout().shape();
let lhs_rank = lhs_shape.num_dims();
let rhs_rank = rhs_shape.num_dims();
assert!(lhs_rank >= 2, "matmul requires at least 2D tensors");
assert!(rhs_rank >= 2, "matmul requires at least 2D tensors");
// Check inner dimensions match: lhs[..., M, K] x rhs[..., K, N]
let k_lhs = lhs_shape[lhs_rank - 1];
let k_rhs = rhs_shape[rhs_rank - 2];
assert_eq!(k_lhs, k_rhs, "matmul: inner dimensions must match");
match lhs.dtype() {
DType::F32 => matmul_gemm::<f32>(lhs, rhs),
DType::F64 => matmul_gemm::<f64>(lhs, rhs),
DType::F16 => matmul_gemm::<f16>(lhs, rhs),
DType::BF16 => matmul_bf16(lhs, rhs),
_ => panic!("matmul: unsupported dtype {:?}", lhs.dtype()),
}
}
/// Extract 2D matrix strides from a tensor layout.
/// Returns (row_stride, col_stride) for the last two dimensions.
fn get_2d_strides(layout: &Layout) -> (isize, isize) {
let strides = layout.strides();
let ndim = strides.len();
let row_stride = strides[ndim - 2];
let col_stride = strides[ndim - 1];
(row_stride, col_stride)
}
/// Compute broadcast batch dimensions for batched matmul.
/// Returns (broadcast_shape, lhs_strides, rhs_strides) where strides map
/// output batch index to input batch offset (in matrices).
fn broadcast_batch_dims(
lhs_batch: &[usize],View on GitHub (pinned to d16f7ba2ed)
Solutions
- Cast the operands to a float dtype before matmul: a.cast::<f32>().matmul(b.cast::<f32>()).
- For true integer matmul, use the int tensor API (int_matmul supports I32/I64).
- Dequantize int8 weights to float before the linear layer.
- Assert both operands are float dtype at the model forward boundary.
Example fix
// before let y = indices.matmul(weights); // indices are I64 -> panic // after let y = indices.cast::<f32>().matmul(weights); // or use int_matmul for integer results
Defensive patterns
Strategy: validation
Validate before calling
assert!(lhs.dtype().is_float() && rhs.dtype().is_float(), "matmul requires float tensors, got {:?} and {:?}", lhs.dtype(), rhs.dtype()); Type guard
fn is_float_tensor(t: &FlexTensor) -> bool { matches!(t.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) } Prevention
- Cast integer operands to f32/f64 before matmul
- Use int_matmul for integer workloads
- Dequantize int8 weights to float before linear layers
- Assert operand dtypes at model forward boundaries
When it happens
Trigger: Calling Tensor::matmul on a Flex tensor with an integer dtype (I64/I32/U8/...) or Bool instead of a float dtype.
Common situations: Matmul on one-hot/boolean masks without casting; embedding-index tensors (int64) accidentally fed into a matmul; PyTorch port where torch.matmul handled int inputs; quantized (int8) weights used directly without a dequantize step.
Related errors
- int_matmul: unsupported dtype {:?}
- burn-flex does not support Bool(U32) storage (only Native an
- compare_int: unsupported dtype {:?}
- compare_int_elem: unsupported dtype {:?}
- any_float: unsupported dtype {:?}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/5945012c03e1924c.
Report an issue: GitHub.