Skip to content

Backend IO

Raul Montoya Cardenas edited this page Jul 29, 2026 · 2 revisions

Backend I/O

Wiki hero

Generated with Grok Build: Grok 4.5 · xAI Imagine (/imagine)

Local pluggable I/O types live in src/backend.rs. They let the core library build and test without corpus-ipc or zmq.

Types

IngressPacket

Field Type Meaning
stimuli Vec<f32> Stimulus / readout vector for the network
modulators Option<Vec<f32>> Optional neuromod floats; None → defaults

SpikeEvent

Field Type
channel u16
time u32
strength f32

Independent of corpus-ipc event types; ZMQ path converts at the sink boundary.

Traits

StimulusSource: Send

fn next_ingress(&mut self) -> Result<Option<IngressPacket>>;
fn initialize(&mut self, model_path: Option<&str>) -> Result<()>;
fn shutdown(&mut self) -> Result<()> { Ok(()) }
  • Ok(None) — skip ingress this tick; tick loop still advances with zero-filled stimuli.
  • initialize should be idempotent on success.

SpikeSink: Send

fn emit(&mut self, spikes: &[SpikeEvent], batch_time: Duration) -> Result<()>;
fn flush(&mut self) -> Result<()> { Ok(()) }

batch_time is the same wall-clock duration used to stamp per-spike time fields; ZMQ batch metadata must stay aligned.

BackendPair

pub struct BackendPair {
    pub source: Box<dyn StimulusSource + Send>,
    pub sink: Box<dyn SpikeSink + Send>,
}

BackendPair::stub() // StubStimulusSource + NoopSpikeSink

Always-on stubs

Type Behavior
StubStimulusSource Returns empty stimuli, modulators: None
NoopSpikeSink Drops all emits
CollectingSpikeSink #[cfg(test)] only — records batches

Feature: corpus-ipc

When enabled, exports:

Type Role
ZmqStimulusSource Wraps corpus_ipc::ZmqBrainBackend; optional channel split for modulators
ZmqSpikeSink JSON SpineMessage::Spikes over ZMQ PUB; mutex-wrapped socket

Modulator extraction (with_channels)

readout = process_signals(&[])
if channels > 0 && readout.len() > channels:
  stimuli = readout[0..channels]
  modulators = readout[channels..channels+4] if long enough
else:
  entire readout as stimuli, modulators None

Default ZmqStimulusSource::new() uses channels=0 (no split). Binary uses with_channels(cfg.channels).

Wire format (egress)

Serializes corpus_ipc::SpineMessage::Spikes(SpikeBatch { batch_id, timestamp, spikes, ... }) as JSON bytes on the PUB socket.

Custom backends

Implement the traits, box into BackendPair, then:

BrainstemDaemon::try_with_backend(cfg, pair)?;

Last updated: July 28, 2026 Updated by: Grok Build: Grok 4.5 Package tip reference: 8176c58 (main)

Clone this wiki locally