native_neural_network_std 0.2.1

Ergonomic std wrapper for the `native_neural_network` crate (no_std) — std-friendly re-exports and utilities.
Documentation
#[derive(Debug)]
pub enum LayerStdError {
    EmptyPlan,
    InvalidShape,
    InvalidRange,
    IncompatibleChain,
    BufferTooSmall,
    CountMismatch,
}

impl From<native_neural_network::layers::LayerError> for LayerStdError {
    fn from(e: native_neural_network::layers::LayerError) -> Self {
        match e {
            native_neural_network::layers::LayerError::EmptyPlan => LayerStdError::EmptyPlan,
            native_neural_network::layers::LayerError::InvalidShape => LayerStdError::InvalidShape,
            native_neural_network::layers::LayerError::InvalidRange => LayerStdError::InvalidRange,
            native_neural_network::layers::LayerError::IncompatibleChain => {
                LayerStdError::IncompatibleChain
            }
            native_neural_network::layers::LayerError::BufferTooSmall => {
                LayerStdError::BufferTooSmall
            }
            native_neural_network::layers::LayerError::CountMismatch => {
                LayerStdError::CountMismatch
            }
        }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct DenseLayerDesc {
    pub input_size: usize,
    pub output_size: usize,
    pub weight_offset: usize,
    pub bias_offset: usize,
    pub activation: native_neural_network::activations::ActivationKind,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LayerSpec {
    Dense(DenseLayerDesc),
}

impl From<native_neural_network::layers::DenseLayerDesc> for DenseLayerDesc {
    fn from(d: native_neural_network::layers::DenseLayerDesc) -> Self {
        DenseLayerDesc {
            input_size: d.input_size,
            output_size: d.output_size,
            weight_offset: d.weight_offset,
            bias_offset: d.bias_offset,
            activation: d.activation,
        }
    }
}

impl From<DenseLayerDesc> for native_neural_network::layers::DenseLayerDesc {
    fn from(d: DenseLayerDesc) -> Self {
        native_neural_network::layers::DenseLayerDesc {
            input_size: d.input_size,
            output_size: d.output_size,
            weight_offset: d.weight_offset,
            bias_offset: d.bias_offset,
            activation: d.activation,
        }
    }
}

impl From<native_neural_network::layers::LayerSpec> for LayerSpec {
    fn from(s: native_neural_network::layers::LayerSpec) -> Self {
        match s {
            native_neural_network::layers::LayerSpec::Dense(d) => {
                LayerSpec::Dense(DenseLayerDesc::from(d))
            }
        }
    }
}

impl From<LayerSpec> for native_neural_network::layers::LayerSpec {
    fn from(s: LayerSpec) -> Self {
        match s {
            LayerSpec::Dense(d) => native_neural_network::layers::LayerSpec::Dense(
                native_neural_network::layers::DenseLayerDesc::from(d),
            ),
        }
    }
}

pub fn build_specs_from_layers(
    layers: &[usize],
    hidden_activation: native_neural_network::activations::ActivationKind,
    output_activation: native_neural_network::activations::ActivationKind,
    weights_len: usize,
    biases_len: usize,
) -> Result<Vec<LayerSpec>, LayerStdError> {
    let layer_count = layers.len().saturating_sub(1);
    let mut out_native = vec![
        native_neural_network::layers::LayerSpec::Dense(
            native_neural_network::layers::DenseLayerDesc {
                input_size: 0,
                output_size: 0,
                weight_offset: 0,
                bias_offset: 0,
                activation: native_neural_network::activations::ActivationKind::Identity
            }
        );
        layer_count
    ];
    let used = native_neural_network::layers::build_from_layers(
        layers,
        hidden_activation,
        output_activation,
        weights_len,
        biases_len,
        &mut out_native,
    )
    .map_err(LayerStdError::from)?;
    out_native.truncate(used);
    Ok(out_native.into_iter().map(LayerSpec::from).collect())
}

pub fn to_native_vec(specs: &[LayerSpec]) -> Vec<native_neural_network::layers::LayerSpec> {
    specs
        .iter()
        .cloned()
        .map(native_neural_network::layers::LayerSpec::from)
        .collect()
}

pub fn fill_native_slice_from_std(
    src: &[LayerSpec],
    dst: &mut [native_neural_network::layers::LayerSpec],
) -> usize {
    let count = core::cmp::min(src.len(), dst.len());
    for i in 0..count {
        dst[i] = native_neural_network::layers::LayerSpec::from(src[i]);
    }
    count
}

pub fn fill_std_slice_from_native(
    src: &[native_neural_network::layers::LayerSpec],
    dst: &mut [LayerSpec],
) -> usize {
    let count = core::cmp::min(src.len(), dst.len());
    for i in 0..count {
        dst[i] = LayerSpec::from(src[i]);
    }
    count
}

pub fn with_native_plan_from_parts<F, R>(
    layers: &[LayerSpec],
    weights: &[f32],
    biases: &[f32],
    f: F,
) -> R
where
    F: FnOnce(&native_neural_network::layers::LayerPlan<'_>) -> R,
{
    let native_buf: Vec<_> = layers
        .iter()
        .cloned()
        .map(native_neural_network::layers::LayerSpec::from)
        .collect();
    let plan = native_neural_network::layers::LayerPlan {
        layers: &native_buf,
        weights,
        biases,
    };
    f(&plan)
}

#[derive(Debug, Clone)]
pub struct LayerPlanStd {
    pub layers: Vec<LayerSpec>,
    pub weights: Vec<f32>,
    pub biases: Vec<f32>,
}

impl LayerPlanStd {
    pub fn new(layers: Vec<LayerSpec>, weights: Vec<f32>, biases: Vec<f32>) -> Self {
        LayerPlanStd {
            layers,
            weights,
            biases,
        }
    }

    pub fn as_native_plan<F, R>(&self, f: F) -> R
    where
        F: FnOnce(&native_neural_network::layers::LayerPlan<'_>) -> R,
    {
        let native_buf: Vec<_> = self
            .layers
            .iter()
            .cloned()
            .map(native_neural_network::layers::LayerSpec::from)
            .collect();
        let plan = native_neural_network::layers::LayerPlan {
            layers: &native_buf,
            weights: &self.weights,
            biases: &self.biases,
        };
        f(&plan)
    }
}

impl LayerSpec {
    pub fn input_size(&self) -> usize {
        match self {
            LayerSpec::Dense(d) => d.input_size,
        }
    }

    pub fn output_size(&self) -> usize {
        match self {
            LayerSpec::Dense(d) => d.output_size,
        }
    }
}

impl core::fmt::Display for LayerStdError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "LayerStdError::{:?}", self)
    }
}

impl std::error::Error for LayerStdError {}