tracel-ai/burn · error

Can't store in u32

Error message

Can't store in u32

What it means

Quantized tensors stored as PackedU32 pack multiple quantized values per u32; this requires the last tensor dimension to be a multiple of the number of values packed per u32 (num_quants). If it isn't, the data cannot be laid out in whole u32 words and the library panics during tensor allocation.

Solutions

  1. Pad or choose the quantized dimension so the last dim is divisible by num_quants for the scheme
  2. Switch the scheme to QuantStore::Native with a byte-aligned value like Q8 if the dim can't change
  3. Check num_quants() for your QuantScheme to know the required divisibility
  4. Adjust model architecture (e.g. set the last linear out-features divisible by the pack factor)

Example fix

// before: last dim 1002 with Q4 packed in u32 (needs %8==0)
let qt = Tensor::new_quantized(data, scheme); // panics
// after: pad weights to 1008 or use Native store
let scheme = scheme.with_store(QuantStore::Native);
let qt = Tensor::new_quantized(data, scheme);
Defensive patterns

Strategy: validation

Validate before calling

let num_quants = scheme.num_quants();
assert_eq!(shape[shape.len() - 1] % num_quants, 0,
    "last dim must be divisible by {num_quants} for PackedU32");

Prevention

When it happens

Trigger: Creating a quantized tensor with QuantStore::PackedU32 (e.g. Q4/Q2 packing into u32) where shape[rank-1] % num_quants != 0, via new_qtensor or empty_qtensor.

Common situations: Quantizing a model whose last linear layer output (or embedding dim) isn't divisible by the pack factor (e.g. dim 1002 with 4-bit values packing 8 per u32), or reshaping packed quant tensors to non-divisible last dims.

Related errors


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

Appendix: source

Thrown at crates/burn-cubecl/src/ops/qtensor.rs:88

fn new_quantized(
    shape: impl Into<Shape>,
    scheme: QuantScheme,
    device: &CubeDevice,
    data: Option<Bytes>,
    alloc_kind: MemoryLayoutStrategy,
) -> CubeTensor {
    let client = device.client();
    let shape: Shape = shape.into();
    let mut shape_value: Shape = shape.clone();

    let rank = shape.rank();
    let shape_last = shape[rank - 1];
    let num_quants = scheme.num_quants();

    let data_size = match scheme.store {
        QuantStore::PackedU32(_) => {
            if !shape_last.is_multiple_of(num_quants) {
                panic!("Can't store in u32")
            }
            shape_value[rank - 1] = shape_last.div_ceil(num_quants);
            size_of::<u32>()
        }
        QuantStore::Native => match scheme.value {
            QuantValue::Q8F | QuantValue::Q8S | QuantValue::E4M3 | QuantValue::E5M2 => {
                size_of::<i8>()
            }
            QuantValue::Q4F
            | QuantValue::Q4S
            | QuantValue::Q2F
            | QuantValue::Q2S
            | QuantValue::E2M1 => {
                panic!("Can't store native sub-byte values")
            }
        },
        QuantStore::PackedNative(_) => match scheme.value {
            QuantValue::E2M1 => size_of::<e2m1x2>(),

View on GitHub (pinned to d16f7ba2ed)