#spiking #snn #stdp #neuromorphic

neuromod

A high-performance Rust SNN library for neuroscience research and pure spiking neural network library featuring LIF, Izhikevich, Hebbian, Nagumo, Lapicque and Hodgkin-Huxley dynamics

6 releases (3 breaking)

Uses new Rust 2024

0.4.0 Apr 22, 2026
0.3.0 Apr 4, 2026
0.2.2 Mar 24, 2026
0.1.0 Mar 18, 2026

#996 in Algorithms

GPL-3.0 license

155KB
1.5K SLoC

neuromod

A generalized Rust library for spiking neural networks (SNNs), centered on biologically grounded neuron models, neuromodulation, and plasticity.

neuromod is designed to be a reusable core: topology-neutral at initialization, dynamically sizable at runtime, and strict about input shape validation.

Highlights

  • Dynamic network sizing with SpikingNetwork::with_dimensions(...)
  • Backward-compatible default constructor: SpikingNetwork::new()
  • Strict step contract: Result<Vec<usize>, StepError>
  • Neutral initialization (blank synaptic weights; no hardcoded domain topology)
  • Canonical neuron models included:
    • Lapicque
    • LIF
    • GIF (Generalized Integrate-and-Fire)
    • Izhikevich
    • FitzHugh-Nagumo
    • Hodgkin-Huxley
  • Classical Hebbian STDP utilities and reward-modulated learning components

Installation

[dependencies]
neuromod = "0.4.0"

Quick Start

use neuromod::{NeuroModulators, SpikingNetwork};

fn main() {
    let mut network = SpikingNetwork::new(); // default: 16 LIF, 5 Izh, 16 channels
    let stimuli = [0.5_f32; 16];
    let modulators = NeuroModulators::default();

    let spikes = network.step(&stimuli, &modulators).unwrap();
    println!("Spiking neuron indices: {spikes:?}");
}

Dynamic Dimensions

use neuromod::{NeuroModulators, SpikingNetwork};

fn main() {
    let mut network = SpikingNetwork::with_dimensions(518, 5, 518);
    let modulators = NeuroModulators::default();
    let stimuli = vec![0.25_f32; 518];

    let spikes = network.step(&stimuli, &modulators).unwrap();
    println!("Spike count: {}", spikes.len());
}

Step Errors (Shape Validation)

step validates that stimuli.len() == num_channels and returns an error on mismatch.

use neuromod::{NeuroModulators, SpikingNetwork, StepError};

fn main() {
    let mut network = SpikingNetwork::with_dimensions(32, 4, 32);
    let modulators = NeuroModulators::default();
    let bad_stimuli = vec![0.1_f32; 31];

    match network.step(&bad_stimuli, &modulators) {
        Ok(_) => unreachable!("expected length mismatch"),
        Err(StepError::InputLenMismatch { expected, got }) => {
            println!("InputLenMismatch: expected {expected}, got {got}");
        }
    }
}

Neuromodulators

NeuroModulators supports both direct control and signal-derived initialization.

use neuromod::NeuroModulators;

fn main() {
    // (thermal_signal, power_signal, throughput_signal, timing_signal)
    let mut mods = NeuroModulators::from_signals(75.0, 300.0, 0.05, 2640.0);

    mods.add_reward(0.2);
    mods.add_stress(0.1);
    mods.boost_focus(0.3);
    mods.add_aux_reward(0.4);
    mods.decay();

    println!("dopamine={:.3}, aux={:.3}", mods.dopamine, mods.aux_dopamine);
}

Included Components

  • SpikingNetwork, StepError
  • NeuroModulators
  • Neuron models:
    • LifNeuron
    • GifNeuron
    • IzhikevichNeuron
    • LapicqueNeuron
    • FitzHughNagumoNeuron
    • HodgkinHuxleyNeuron
  • Learning/plasticity:
    • apply_classical_stdp, StdpParams, HebbianIzhikevichNetwork
    • EligibilityTrace, RmStdpConfig

Examples

Run included examples:

cargo run --example basic
cargo run --example rstdp_demo

Development

cargo check
cargo test
cargo bench --no-run

License

GPL-3.0

Dependencies

~0.7–1.6MB
~33K SLoC