tracel-ai/burn · error
cat: unsupported dtype {:?}
Error message
cat: unsupported dtype {:?} What it means
cat in burn-flex dispatches concat on the dtype of the input tensors, instantiating cat_impl for every numeric type plus a special arm mapping U8 and Bool onto u8 storage. Any other dtype combination reaches the catch-all and panics. All tensors in the list must share the dtype — the dtype is taken from tensors[0].
Source
Thrown at crates/burn-flex/src/ops/cat.rs:30
if tensors.len() == 1 {
return tensors.into_iter().next().unwrap();
}
let dtype = tensors[0].dtype();
match dtype {
DType::F32 => cat_impl::<f32>(tensors, dim),
DType::F64 => cat_impl::<f64>(tensors, dim),
DType::F16 => cat_impl::<f16>(tensors, dim),
DType::BF16 => cat_impl::<bf16>(tensors, dim),
DType::I64 => cat_impl::<i64>(tensors, dim),
DType::I32 => cat_impl::<i32>(tensors, dim),
DType::I16 => cat_impl::<i16>(tensors, dim),
DType::I8 => cat_impl::<i8>(tensors, dim),
DType::U64 => cat_impl::<u64>(tensors, dim),
DType::U32 => cat_impl::<u32>(tensors, dim),
DType::U16 => cat_impl::<u16>(tensors, dim),
DType::U8 | DType::Bool(_) => cat_impl::<u8>(tensors, dim),
_ => panic!("cat: unsupported dtype {:?}", dtype),
}
}
fn cat_impl<E: Element + bytemuck::Pod>(tensors: Vec<FlexTensor>, dim: usize) -> FlexTensor {
let dtype = tensors[0].dtype();
let first_shape = tensors[0].layout().shape();
let ndims = first_shape.num_dims();
assert!(
dim < ndims,
"cat: dim {} out of bounds for {} dimensions",
dim,
ndims
);
// Compute output shape: sum along cat dim, others must match
let mut out_dims = first_shape.to_vec();
out_dims[dim] = 0;View on GitHub (pinned to d16f7ba2ed)
Solutions
- Cast all tensors to a common supported dtype before cat: tensors.iter().map(|t| t.cast(DType::F32)).collect().
- Ensure tensors[0] has a supported dtype since the dispatch keys off it.
- Normalize bool tensors explicitly (bool_empty/bool_into_int helpers) rather than relying on the U8|Bool arm.
Example fix
// before let out = cat(vec![a, b_f32], 0); // a is i64, b f32 // after let out = cat(vec![a.cast(DType::F32), b_f32], 0);
Defensive patterns
Strategy: validation
Validate before calling
let dtype = tensors[0].dtype();
if !matches!(dtype, DType::F64 | DType::F32 | DType::F16 | DType::BF16 | DType::I64 | DType::I32 | DType::I16 | DType::I8 | DType::U64 | DType::U32 | DType::U16 | DType::U8 | DType::Bool(_)) {
tensors = tensors.into_iter().map(|t| t.cast(DType::F32)).collect();
}
let out = cat(tensors, dim); Type guard
fn all_same_supported_dtype(ts: &[FlexTensor]) -> bool {
let d = ts[0].dtype();
ts.iter().all(|t| t.dtype() == d)
} Try / catch
let out = std::panic::catch_unwind(|| cat(tensors.clone(), dim))
.unwrap_or_else(|_| cat(tensors.iter().map(|t| t.cast(DType::F32)).collect(), dim)); Prevention
- Cast all tensors to a shared dtype before concatenating.
- Remember tensors[0]'s dtype drives the dispatch.
- Normalize Bool to U8 (or rely on the Bool(_) arm) consistently.
- Validate the list is non-empty and dtype-homogeneous in helpers.
When it happens
Trigger: Concatenating tensors whose dtype is not one of the listed numeric types, or where the first tensor's dtype is unsupported (dtype is read from tensors[0]). Mismatched dtypes across the list can also misroute into the wrong typed cat_impl.
Common situations: Concatenating bool masks with u8 buffers where an exotic dtype alias slipped in; mixed float/int lists relying on promotion; empty or mismatched tensor lists after filtering.
Related errors
- softmax: unsupported dtype {:?}
- burn_flex::layer_norm: unsupported dtype {:?}
- attention: unsupported dtype {:?}
- binary_op: unsupported dtype {:?}
- scalar_op: unsupported dtype {:?}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/0e8fa3b5204da992.
Report an issue: GitHub.