rlx-umap 0.2.18

Parametric UMAP on RLX — full fit/transform API and k-NN building blocks.
// RLX — versatile ML compiler + runtime.
// Copyright (C) 2026 Eugene Hauptmann, Nataliya Kosmyna.
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Attribute blob for `umap.knn` / `umap.knn_backward` (`k` neighbours per row).

/// Per-instance knobs for k-NN custom ops.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KnnAttrs {
    /// Number of nearest neighbours per row (must be `< n`).
    pub k: u32,
}

impl KnnAttrs {
    pub const ENCODE_LEN: usize = 4;

    pub fn encode(self) -> Vec<u8> {
        self.k.to_le_bytes().to_vec()
    }

    pub fn decode(attrs: &[u8]) -> Result<Self, String> {
        let bytes: [u8; 4] = attrs
            .get(..Self::ENCODE_LEN)
            .and_then(|s| s.try_into().ok())
            .ok_or_else(|| {
                format!(
                    "knn attrs: expected {} bytes, got {}",
                    Self::ENCODE_LEN,
                    attrs.len()
                )
            })?;
        Ok(Self {
            k: u32::from_le_bytes(bytes),
        })
    }
}