tracel-ai/burn · error
int_matmul: unsupported dtype {:?}
Error message
int_matmul: unsupported dtype {:?} What it means
int_matmul performs integer matrix multiplication but only supports I32 and I64 dtypes; the match panics for all others (I8/I16, unsigned U8..U64, floats, Bool). Operands must also share the same inner (K) dimension, enforced by an assert just above the panic.
Source
Thrown at crates/burn-flex/src/ops/matmul.rs:516
pub fn int_matmul(lhs: FlexTensor, rhs: FlexTensor) -> FlexTensor {
assert_eq!(lhs.dtype(), rhs.dtype(), "int_matmul: dtype mismatch");
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, "int_matmul requires at least 2D tensors");
assert!(rhs_rank >= 2, "int_matmul requires at least 2D tensors");
let k_lhs = lhs_shape[lhs_rank - 1];
let k_rhs = rhs_shape[rhs_rank - 2];
assert_eq!(k_lhs, k_rhs, "int_matmul: inner dimensions must match");
match lhs.dtype() {
DType::I32 => matmul_i32(lhs, rhs),
DType::I64 => matmul_i64(lhs, rhs),
_ => panic!("int_matmul: unsupported dtype {:?}", lhs.dtype()),
}
}
/// i32 matmul using naive triple loop with SIMD dot product.
fn matmul_i32(lhs: FlexTensor, rhs: FlexTensor) -> FlexTensor {
let lhs = lhs.to_contiguous();
let rhs = rhs.to_contiguous();
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();
if lhs_rank == 2 && rhs_rank == 2 {
matmul_2d_i32(&lhs, &rhs)
} else {
matmul_batched_i32(lhs, rhs)
}View on GitHub (pinned to d16f7ba2ed)
Solutions
- Cast both operands to I32 or I64 before the matmul: a.cast::<i32>().matmul(b.cast::<i32>()).
- For int8 quantized workloads, upcast to i32 (standard practice to avoid accumulation overflow anyway).
- For float tensors, use the float matmul path instead of int_matmul.
- Add a dtype assert on both operands before entering the matmul helper.
Example fix
// before let out = w_u8.matmul(x_u8); // U8 -> panic // after let out = w_u8.cast::<i32>().matmul(x_u8.cast::<i32>());
Defensive patterns
Strategy: validation
Validate before calling
assert!(matches!(lhs.dtype(), DType::I32 | DType::I64) && matches!(rhs.dtype(), DType::I32 | DType::I64), "int_matmul supports only I32/I64, got {:?} and {:?}", lhs.dtype(), rhs.dtype()); Type guard
fn is_int_matmul_compatible(t: &FlexTensor) -> bool { matches!(t.dtype(), DType::I32 | DType::I64) } Prevention
- Cast I8/I16/unsigned operands to I32 before integer matmul
- Upcast int8 quantized weights to i32 to avoid accumulation overflow
- Use the float matmul path for float tensors
- Assert both operand dtypes before helper matmul functions
When it happens
Trigger: Calling int matmul with operands of dtype I8/I16 or any unsigned dtype (U8/U16/U32/U64), or passing float tensors to the int matmul path.
Common situations: Quantized inference with int8 weights/activations; image tensors (u8) fed into an integer linear layer; dtype mismatch between lhs (i32) and rhs (u8) so lhs itself is fine but patterns like casting only one operand mislead; porting numpy int matmuls with 16-bit types.
Related errors
- 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/1c005addda5b264c.
Report an issue: GitHub.