Skip to main content

nir_rs/
lib.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Pure-Rust implementation of the Neuromorphic Intermediate Representation (NIR).
4//!
5//! NIR is a framework-agnostic graph format for spiking neural networks
6//! (analogous to ONNX for conventional nets). This crate provides a typed
7//! in-memory graph model plus HDF5 `.nir` read/write that interoperates with
8//! the Python reference implementation.
9//!
10//! # Status
11//!
12//! **v0.4 — developer experience**: a public load-inspect-save example makes
13//! the HDF5 workflow executable end to end, on top of the v0.3 I/O and v0.2
14//! graph model — the closed [`NirNode`] enum (wire-accurate type strings),
15//! [`NirGraph`] with ordered nodes/edges, [`Tensor`] / metadata types, and
16//! structured [`NirError`].
17//!
18//! I/O lives behind the opt-in **`hdf5`** feature because it links the native
19//! libhdf5 library; the graph model itself has no system dependencies. See the
20//! [`io`] module for the feature gate, the file layout, and the version-string
21//! policy.
22//!
23//! The independent opt-in **`serde`** feature implements Serde traits for the
24//! graph model. Formats such as JSON are useful for debugging and tests only:
25//! they are not a stable NIR schema or an interchange format. Use HDF5 `.nir`
26//! through [`io::read`] / [`io::write`] for interoperability. JSON also cannot
27//! represent non-finite floats faithfully, so NaN and infinities are not
28//! guaranteed to round-trip.
29//!
30//! ```toml
31//! nir-rs = { version = "0.4", features = ["hdf5"] }
32//! ```
33//!
34//! Run the complete fixture workflow from a checkout with:
35//!
36//! ```text
37//! cargo run --example load_inspect_lif --features hdf5
38//! ```
39//!
40//! # Example
41//!
42//! ```
43//! use nir_rs::nodes::{Affine, Input, Lif, Output};
44//! use nir_rs::types::Tensor;
45//! use nir_rs::{NirGraph, NirNode};
46//!
47//! let mut g = NirGraph::new();
48//! g.insert_node(
49//!     "input",
50//!     NirNode::Input(Input {
51//!         shape: vec![4],
52//!         metadata: Default::default(),
53//!     }),
54//! )?;
55//! g.insert_node(
56//!     "fc",
57//!     NirNode::Affine(Affine {
58//!         weight: Tensor::from_f32(vec![2, 4], vec![0.1; 8])?,
59//!         bias: Tensor::from_f32(vec![2], vec![0.0, 0.0])?,
60//!         metadata: Default::default(),
61//!     }),
62//! )?;
63//! g.insert_node(
64//!     "lif",
65//!     NirNode::Lif(Lif {
66//!         tau: Tensor::from_f64(vec![2], vec![10.0, 10.0])?,
67//!         r: Tensor::from_f64(vec![2], vec![1.0, 1.0])?,
68//!         v_leak: Tensor::from_f64(vec![2], vec![0.0, 0.0])?,
69//!         v_threshold: Tensor::from_f64(vec![2], vec![1.0, 1.0])?,
70//!         v_reset: None,
71//!         metadata: Default::default(),
72//!     }),
73//! )?;
74//! g.insert_node(
75//!     "output",
76//!     NirNode::Output(Output {
77//!         shape: vec![2],
78//!         metadata: Default::default(),
79//!     }),
80//! )?;
81//! g.add_edge("input", "fc");
82//! g.add_edge("fc", "lif");
83//! g.add_edge("lif", "output");
84//! g.validate_structure()?;
85//!
86//! // With `features = ["hdf5"]`, the graph exchanges as a `.nir` file:
87//! // nir_rs::io::write("model.nir", &g)?;
88//! // let reloaded = nir_rs::io::read("model.nir")?;
89//! # Ok::<(), nir_rs::NirError>(())
90//! ```
91//!
92//! # Non-goals
93//!
94//! - SNN training or simulation
95//! - Mapping graphs onto specific neuromorphic hardware
96//! - Framework-specific converters (belong in producer/consumer tools)
97//!
98//! # Upstream
99//!
100//! - [neuromorphs/NIR](https://github.com/neuromorphs/NIR)
101//! - [neuroir.org](https://neuroir.org/)
102//! - Paper: [Pedersen et al., Nat. Commun. 15, 8122 (2024)](https://doi.org/10.1038/s41467-024-52259-9)
103//!   — please cite if you use NIR (see the repository `README` / `CITATION.cff`)
104//!
105//! Wire type names must match the Python IR (`CubaLIF`, `Conv2d`, …), not
106//! informal marketing aliases.
107
108#![warn(missing_docs)]
109
110pub mod error;
111pub mod graph;
112pub mod io;
113pub mod nodes;
114pub mod types;
115
116pub use error::{NirError, Result};
117pub use graph::NirGraph;
118pub use nodes::NirNode;
119pub use types::{DType, MetadataMap, MetadataValue, Tensor, TensorData};