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
use std::fs;
use std::path::Path;

fn visit_dir<F: FnMut(&Path)>(p: &Path, cb: &mut F) {
    if p.is_dir() {
        for entry in fs::read_dir(p).unwrap_or_else(|_| panic!("read_dir failed {}", p.display())) {
            if let Ok(e) = entry {
                let p2 = e.path();
                visit_dir(&p2, cb);
            }
        }
    } else if p.is_file() {
        cb(p)
    }
}

#[test]
fn cpu_backend_abstraction_real() {
    let previous = native_neural_network_std::std::engine_std::get_compute_backend();
    native_neural_network_std::std::engine_std::set_compute_backend(
        native_neural_network_std::std::engine_std::ComputeBackend::Cpu,
    );
    assert_eq!(
        native_neural_network_std::std::engine_std::get_compute_backend(),
        native_neural_network_std::std::engine_std::ComputeBackend::Cpu
    );
    native_neural_network_std::std::engine_std::set_compute_backend(previous);
}

#[test]
fn inspect_rnn_examples_f32() {
    let root = Path::new("rnn_examples");
    if !root.exists() {
        eprintln!("rnn_examples not present — nothing to inspect");
        return;
    }

    println!("path,ok_unpack,layers,weights,biases,any_nan_or_inf,sample_output_finite,error");

    let mut cb = |p: &Path| {
        if p.extension().and_then(|s| s.to_str()) != Some("rnn") {
            return;
        }

        let path_s = p.display().to_string();
        let mut ok_unpack = false;
        let mut layers_n = 0usize;
        let mut weights_n = 0usize;
        let mut biases_n = 0usize;
        let mut any_nan_or_inf = false;
        let mut sample_output_finite = false;
        let mut error = String::new();

        let bytes = match fs::read(p) {
            Ok(b) => b,
            Err(e) => {
                error = format!("read error: {}", e);
                println!(
                    "{},{},{},{},{},{},{},{}",
                    path_s,
                    ok_unpack,
                    layers_n,
                    weights_n,
                    biases_n,
                    any_nan_or_inf,
                    sample_output_finite,
                    error
                );
                return;
            }
        };

        let payload = if bytes.len() >= 4 && &bytes[0..4] == b"RNN\x00" {
            match native_neural_network_std::std::rnn_std::rnn_extract_blob_bytes_std(
                &bytes, "model",
            ) {
                Ok(blob) => blob,
                Err(e) => {
                    error = format!("container extract warning: {:?}; fallback raw", e);
                    bytes.clone()
                }
            }
        } else {
            bytes.clone()
        };

        let dtype = payload.get(6).copied().unwrap_or(0);
        if dtype == 1 {
            let unpack_res = std::panic::catch_unwind(|| {
                native_neural_network_std::std::rnn_std::rnn_unpack_v1_f64_std(&payload)
            })
            .map_err(|e| format!("panic during unpack: {:?}", e))
            .and_then(|r| r.map_err(|e| format!("unpack err: {:?}", e)));

            match unpack_res {
                Ok((layers, weights, biases)) => {
                    ok_unpack = true;
                    layers_n = layers.len();
                    weights_n = weights.len();
                    biases_n = biases.len();
                    any_nan_or_inf = weights.iter().chain(biases.iter()).any(|v| !v.is_finite());

                    if let (
                        Some(native_neural_network_std::std::layers_std::LayerSpec::Dense(first)),
                        Some(native_neural_network_std::std::layers_std::LayerSpec::Dense(last)),
                    ) = (layers.first(), layers.last())
                    {
                        let input_size = first.input_size as usize;
                        let output_size = last.output_size as usize;
                        if input_size > 0 && output_size > 0 {
                            let input = vec![0.5f64; input_size];
                            let mut out = vec![0f64; output_size];

                            if let Ok(c) = native_neural_network_std::std::rnn_std::rnn_required_from_bytes_v1_std(&payload) {
                                let mut specs_scratch = vec![native_neural_network_std::std::layers_std::LayerSpec::Dense(native_neural_network_std::std::layers_std::DenseLayerDesc { input_size:0, output_size:0, weight_offset:0, bias_offset:0, activation: native_neural_network_std::std::activations_std::ActivationKind::Identity }); layers.len()];
                                let mut weights_scratch = vec![0f64; c.weights];
                                let mut biases_scratch = vec![0f64; c.biases];
                                if let Ok(req) = native_neural_network_std::std::rnn_std::rnn_required_infer_scratch_from_specs_std(&layers) {
                                    let mut infer_scratch = vec![0f64; req];
                                    let run_res = native_neural_network_std::std::rnn_std::rnn_run_v1_f64(
                                        &payload,
                                        &input,
                                        &mut out,
                                        &mut specs_scratch,
                                        &mut weights_scratch,
                                        &mut biases_scratch,
                                        &mut infer_scratch,
                                    );
                                    if run_res.is_ok() {
                                        sample_output_finite = out.iter().all(|v| v.is_finite());
                                    } else {
                                        error = format!("run err: {:?}", run_res.err());
                                    }
                                }
                            }
                        }
                    }
                }
                Err(e) => error = format!("unpack error: {:?}", e),
            }
        } else {
            let unpack_res = std::panic::catch_unwind(|| {
                native_neural_network_std::std::rnn_std::rnn_unpack_v1_std(&payload)
            })
            .map_err(|e| format!("panic during unpack: {:?}", e))
            .and_then(|r| r.map_err(|e| format!("unpack err: {:?}", e)));

            match unpack_res {
                Ok((layers, weights, biases)) => {
                    ok_unpack = true;
                    layers_n = layers.len();
                    weights_n = weights.len();
                    biases_n = biases.len();
                    any_nan_or_inf = weights.iter().chain(biases.iter()).any(|v| !v.is_finite());

                    if let (
                        Some(native_neural_network_std::std::layers_std::LayerSpec::Dense(first)),
                        Some(native_neural_network_std::std::layers_std::LayerSpec::Dense(last)),
                    ) = (layers.first(), layers.last())
                    {
                        let input_size = first.input_size as usize;
                        let output_size = last.output_size as usize;
                        if input_size > 0 && output_size > 0 {
                            let input = vec![0.5f32; input_size];
                            let mut out = vec![0f32; output_size];

                            if let Ok(c) = native_neural_network_std::std::rnn_std::rnn_required_from_bytes_v1_std(&payload) {
                                let mut specs_scratch = vec![native_neural_network_std::std::layers_std::LayerSpec::Dense(native_neural_network_std::std::layers_std::DenseLayerDesc { input_size:0, output_size:0, weight_offset:0, bias_offset:0, activation: native_neural_network_std::std::activations_std::ActivationKind::Identity }); layers.len()];
                                let mut weights_scratch = vec![0f32; c.weights];
                                let mut biases_scratch = vec![0f32; c.biases];
                                if let Ok(req) = native_neural_network_std::std::rnn_std::rnn_required_infer_scratch_from_specs_std(&layers) {
                                    let mut infer_scratch = vec![0f32; req];
                                    let run_res = native_neural_network_std::std::rnn_std::rnn_run_v1(
                                        &payload,
                                        &input,
                                        &mut out,
                                        &mut specs_scratch,
                                        &mut weights_scratch,
                                        &mut biases_scratch,
                                        &mut infer_scratch,
                                    );
                                    if run_res.is_ok() {
                                        sample_output_finite = out.iter().all(|v| v.is_finite());
                                    } else {
                                        error = format!("run err: {:?}", run_res.err());
                                    }
                                }
                            }
                        }
                    }
                }
                Err(e) => error = format!("unpack error: {:?}", e),
            }
        }

        println!(
            "{},{},{},{},{},{},{},{}",
            path_s,
            ok_unpack,
            layers_n,
            weights_n,
            biases_n,
            any_nan_or_inf,
            sample_output_finite,
            error
        );
    };

    visit_dir(root, &mut cb);
}