#[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 {}