{"record":{"id":"d001b73ef971ef13","repo":"tracel-ai/burn","slug":"softmax-unsupported-dtype","errorCode":null,"errorMessage":"softmax: unsupported dtype {:?}","messagePattern":"softmax: unsupported dtype (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-flex/src/ops/activation.rs","lineNumber":229,"sourceCode":"    );\n\n    if dim != rank - 1 {\n        let swapped = Flex::float_swap_dims(tensor, dim, rank - 1);\n        let normed = softmax_last(swapped);\n        return Flex::float_swap_dims(normed, dim, rank - 1);\n    }\n\n    softmax_last(tensor)\n}\n\nfn softmax_last(tensor: FloatTensor<Flex>) -> FloatTensor<Flex> {\n    let tensor = tensor.to_contiguous();\n    match tensor.dtype() {\n        DType::F32 => softmax_last_f32(tensor),\n        DType::F64 => softmax_last_f64(tensor),\n        DType::F16 => softmax_last_f16(tensor),\n        DType::BF16 => softmax_last_bf16(tensor),\n        dtype => panic!(\"softmax: unsupported dtype {:?}\", dtype),\n    }\n}\n\nfn softmax_last_f32(tensor: FlexTensor) -> FlexTensor {\n    let shape = tensor.layout().shape().clone();\n    let last = *shape.last().expect(\"softmax: empty shape\");\n    if last == 0 {\n        return tensor;\n    }\n    let input: &[f32] = tensor.storage();\n    let n = input.len();\n\n    // Zero-initialize the output. The previous implementation used\n    // `Vec::with_capacity` + `spare_capacity_mut` + a raw-pointer cast to\n    // `&mut [f32]` to skip the memset, but forming a `&mut [f32]` over\n    // uninitialized memory violates Rust's validity invariant (references\n    // must point to initialized values of the correct type) even if every\n    // element is written before it is read. The sound zero-memset","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-flex/src/ops/activation.rs#L211-L247","documentation":"burn-flex's softmax_last dispatches on the tensor's DType and has kernels only for F32, F64, F16 and BF16; any other dtype (integer, bool, etc.) hits the catch-all arm and panics. The library intentionally fails fast instead of silently casting, since softmax is only defined for floating-point data. This is a hard panic, not a Result, so it aborts the calling thread immediately.","triggerScenarios":"Calling softmax (or backend softmax_last) with a FlexTensor whose dtype is an integer type (I64/I32/I16/I8/U64/U32/U16/U8) or Bool. Typically happens after an argmax-free pipeline where logits were produced by an integer cast, or a quantized model whose output tensor was never cast back to float.","commonSituations":"Quantized/inference pipelines forgetting to dequantize logits; a cast chain like .int() left in before normalization; mixing backends where an upstream op produced integer output; test fixtures building integer tensors and reusing them for softmax.","solutions":["Cast the tensor to a float dtype before softmax, e.g. tensor.cast(DType::F32) (or .float() on the burn tensor API).","Check where the input was created and fix the producing op so it emits F32/F64/F16/BF16 logits directly.","If you control the dispatch, extend softmax_last with a cast-to-f32 wrapper for unsupported dtypes instead of panicking."],"exampleFix":"// before\nlet probs = tensor.softmax(); // tensor is I64\n// after\nlet probs = tensor.cast(burn_std::DType::F32).softmax();","handlingStrategy":"validation","validationCode":"if !matches!(tensor.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) {\n    tensor = tensor.cast(DType::F32);\n}\nlet probs = softmax(tensor);","typeGuard":"fn is_float_dtype(d: DType) -> bool {\n    matches!(d, DType::F32 | DType::F64 | DType::F16 | DType::BF16)\n}","tryCatchPattern":"// it panics (not a Result); catch only at a recovery boundary\nlet probs = std::panic::catch_unwind(|| softmax(tensor.clone()))\n    .unwrap_or_else(|_| softmax(tensor.cast(DType::F32)));","preventionTips":["Always cast logits to F32 before softmax.","Add a debug_assert on dtype before normalization ops.","Check quantized pipelines dequantize before float-only ops.","Keep a unit test that runs softmax on every dtype you support."],"tags":["panic","dtype","softmax","unsupported-dtype"],"backgroundTag":"unsupported-dtype","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}