huggingface/candle · error

norm not supported for integer dtypes

Error message

norm not supported for integer dtypes

What it means

Tensor::norm computes sqrt(sum(x^2)) which is only defined for float dtypes; integer tensors are rejected with this bail since the squared sum would overflow/lose meaning for int types. Cast to a float dtype to compute a norm.

Source

Thrown at candle-core/src/tensor.rs:1455

        (self * rhs).and_then(|ret| ret.sum_all())
    }

    /// Computes the **Frobenius norm** (L2 norm of all elements) of the tensor.
    /// - Output is `sqrt(sum(x^2))`.
    /// - Always returns a scalar (`[]` shape).
    ///
    /// # Example
    /// ```rust
    /// use candle_core::{Tensor, Device};
    /// let t = Tensor::new(&[[3., 4.], [0., 0.]], &Device::Cpu)?;
    /// let norm = t.norm()?;
    /// assert_eq!(norm.to_scalar::<f64>()?, 5.);
    /// # Ok::<(), candle_core::Error>(())
    /// ```
    pub fn norm(&self) -> Result<Self> {
        if self.dtype().is_int() {
            bail!("norm not supported for integer dtypes");
        }

        self.sqr().and_then(|x| x.sum_all()).and_then(|x| x.sqrt())
    }

    /// Performs strict matrix-vector multiplication (`[m, n] * [n] = [m]`).
    ///
    /// - If `self` is a matrix (`[m, n]`) and `rhs` is a vector (`[n]`), returns a vector (`[m]`).
    /// - **No broadcasting**: Panics if `self` is not 2D or if `rhs` is not 1D with matching size.
    ///
    /// # Example
    /// ```rust
    /// use candle_core::{Tensor, Device};
    /// let mat = Tensor::new(&[[1., 2., 3.], [4., 5., 6.]], &Device::Cpu)?;
    /// let vec = Tensor::new(&[1., 1., 1.], &Device::Cpu)?;
    /// let res = mat.mv(&vec)?;
    /// assert_eq!(res.to_vec1::<f64>()?, [6., 15.]);
    /// # Ok::<(), candle_core::Error>(())

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Cast to float first: t.to_dtype(candle_core::DType::F32)?.norm()?.
  2. If you truly need integer norms, compute manually with widening: t.to_dtype(F64) then sqr/sum/sqrt.
  3. Add a dtype check (t.dtype().is_int()) in utility functions and cast defensively.

Example fix

// before
let n = ids.norm()?; // ids: I64 -> error
// after
let n = ids.to_dtype(DType::F32)?.norm()?;
Defensive patterns

Strategy: validation

Validate before calling

let t = if t.dtype().is_int() {
    t.to_dtype(candle_core::DType::F32)?
} else { t };
let n = t.norm()?;

Try / catch

match t.norm() {
    Ok(n) => n,
    Err(e) if e.to_string().contains("integer dtypes") => t.to_dtype(DType::F32)?.norm()?,
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling tensor.norm() on a tensor with an integer dtype (U8, U32, I16, I32, I64) — e.g. after loading quantized/integer data or embedding indices.

Common situations: Computing norms of token-id tensors or uint8 image tensors without casting; generic utility code that assumes float input.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/2f4b4d6c60d5c1c5. Report an issue: GitHub.