tracel-ai/burn · error

float_storage_as_f32: unsupported dtype {:?}

Error message

float_storage_as_f32: unsupported dtype {:?}

What it means

float_storage_as_f32 is a helper in the burn-flex backend that reads a tensor's storage as f32 for float operations (with special cases for f32, f16, bf16). It panics when the tensor's dtype is none of the supported float types. This happens when a non-float tensor (e.g. integer/bool) or an exotic dtype reaches a float-only path such as quantize_dynamic or a half-precision mean reduction.

Source

Thrown at crates/burn-flex/src/ops/mod.rs:87

pub(crate) fn float_storage_as_f32(tensor: &FlexTensor) -> Cow<'_, [f32]> {
    match tensor.dtype() {
        DType::F32 => Cow::Borrowed(tensor.storage::<f32>()),
        DType::F64 => Cow::Owned(tensor.storage::<f64>().iter().map(|&x| x as f32).collect()),
        DType::F16 => Cow::Owned(
            tensor
                .storage::<f16>()
                .iter()
                .map(|x| f32::from(*x))
                .collect(),
        ),
        DType::BF16 => Cow::Owned(
            tensor
                .storage::<bf16>()
                .iter()
                .map(|x| f32::from(*x))
                .collect(),
        ),
        other => panic!("float_storage_as_f32: unsupported dtype {:?}", other),
    }
}

pub mod activation;
pub mod attention;
pub mod binary;
mod bool;
pub mod cat;
pub mod comparison;
#[macro_use]
mod conv_common;
pub mod conv;
pub mod conv_transpose;
pub mod cumulative;
pub mod deform_conv;
pub mod expand;
pub mod fft;
pub mod flip;

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast the tensor to a supported float dtype (F32 or BF16) before calling the op, e.g. tensor.cast(burn::tensor::DType::F32).
  2. Inspect the offending tensor with tensor.dtype() (or a debug print) to confirm what dtype actually arrived; trace where it was created or loaded.
  3. If weights come from a checkpoint/quantized loader, configure the loader to dequantize to f32/bf16 at load time instead of keeping integer storage.
  4. If the dtype should be supported by the backend, add an arm to float_storage_as_f32 (e.g. I8 dequantization) in crates/burn-flex/src/ops/mod.rs.

Example fix

// before
let quantized = quantize_dynamic(int_weights_tensor);
// panic: float_storage_as_f32: unsupported dtype I8

// after
let float_weights = int_weights_tensor.cast(burn::tensor::DType::F32);
let quantized = quantize_dynamic(float_weights);
Defensive patterns

Strategy: validation

Validate before calling

fn assert_float(t: &burn::tensor::Tensor<burn::backend::Flex>) {
    assert!(
        matches!(t.dtype(), burn::tensor::DType::F32 | burn::tensor::DType::F64 | burn::tensor::DType::F16 | burn::tensor::DType::BF16),
        "float op requires float dtype, got {:?}",
        t.dtype()
    );
}
// call before: assert_float(&t); quantize_dynamic(t, ...)

Type guard

fn is_float_dtype(d: burn::tensor::DType) -> bool {
    matches!(d, burn::tensor::DType::F32 | burn::tensor::DType::F64 | burn::tensor::DType::F16 | burn::tensor::DType::BF16)
}

Try / catch

// burn-flex panics rather than returning Result; wrap risky calls to isolate the abort
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| quantize_dynamic(t.clone())));
match result {
    Ok(q) => q,
    Err(_) => quantize_dynamic(t.clone().cast(burn::tensor::DType::F32)),
}

Prevention

When it happens

Trigger: Calling quantize_dynamic or quantize on a tensor whose dtype is not F32/F16/BF16 (e.g. an I8/I64/U8 tensor); calling mean_dim_half or mean_scalar_half on a non-float tensor; any code path that passes an integer tensor where a float tensor was expected.

Common situations: Quantizing a model whose input/output embeddings are stored as int8 or int4; loading checkpoints whose weights were saved with integer dtypes and using them without casting; dtype inference on const tensors returning integers unintentionally.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/18a6db20b15b3f26. Report an issue: GitHub.