Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Micro HNSW v2.2 - Neuromorphic Vector Search Engine

A 7.2KB neuromorphic computing core that fuses graph-based vector search (HNSW) with biologically-inspired spiking neural networks. Designed for 256-core ASIC deployment, edge AI, and real-time similarity-driven neural processing.

Vector search meets brain-inspired computing — query vectors trigger neural spikes, enabling attention mechanisms, winner-take-all selection, and online learning through spike-timing dependent plasticity (STDP).

Why Micro HNSW + SNN?

Traditional vector databases return ranked results. Micro HNSW v2.2 goes further: similarity scores become neural currents that drive a spiking network. This enables:

  • Spiking Attention: Similar vectors compete via lateral inhibition — only the strongest survive
  • Temporal Coding: Spike timing encodes confidence (first spike = best match)
  • Online Learning: STDP automatically strengthens connections between co-activated vectors
  • Event-Driven Efficiency: Neurons only compute when they spike — 1000x more efficient than dense networks
  • Neuromorphic Hardware Ready: Direct mapping to Intel Loihi, IBM TrueNorth, or custom ASIC

Features

Vector Search (HNSW Core)

  • Multi-core sharding: 256 cores × 32 vectors = 8,192 total vectors
  • Distance metrics: L2 (Euclidean), Cosine similarity, Dot product
  • Beam search: Width-3 beam for improved recall
  • Cross-core merging: Unified results from distributed search

Graph Neural Network Extensions

  • Typed nodes: 16 Cypher-style types for heterogeneous graphs
  • Weighted edges: Per-node weights for message passing
  • Neighbor aggregation: GNN-style feature propagation
  • In-place updates: Online learning and embedding refinement

Spiking Neural Network Layer

  • LIF neurons: Leaky Integrate-and-Fire with membrane dynamics
  • Refractory periods: Biologically-realistic spike timing
  • STDP plasticity: Hebbian learning from spike correlations
  • Spike propagation: Graph-routed neural activation
  • HNSW→SNN bridge: Vector similarity drives neural currents

Deployment

  • 7.2KB WASM: Runs anywhere WebAssembly runs
  • No allocator: Pure static memory, no_std Rust
  • ASIC-ready: Synthesizable for custom silicon
  • Edge-native: Microcontrollers to data centers

"Real-World Applications" Section

Application Description
1. Embedded Vector Database Semantic search on microcontrollers/IoT with 256-core sharding
2. Knowledge Graphs Cypher-style typed entities (GENE, PROTEIN, DISEASE) with spreading activation
3. Self-Learning Systems Anomaly detection that learns via STDP without retraining
4. DNA/Protein Analysis k-mer embeddings for genomic similarity with winner-take-all alignment
5. Algorithmic Trading Microsecond pattern matching with neural winner-take-all signals
6. Industrial Control (PLC/SCADA) Predictive maintenance via vibration analysis at the edge
7. Robotics & Sensor Fusion Multi-modal LIDAR/camera/IMU fusion with spike-based binding

Specifications

Parameter Value Notes
Vectors/Core 32 Static allocation
Total Vectors 8,192 256 cores × 32 vectors
Max Dimensions 16 Per vector
Neighbors (M) 6 Graph connectivity
Beam Width 3 Search beam size
Node Types 16 4-bit packed
SNN Neurons 32 One per vector
WASM Size ~7.2KB After wasm-opt -Oz
Gate Count ~45K Estimated for ASIC

Building

# Add wasm32 target
rustup target add wasm32-unknown-unknown

# Build with size optimizations
cargo build --release --target wasm32-unknown-unknown

# Optimize with wasm-opt (required for SNN features)
wasm-opt -Oz --enable-nontrapping-float-to-int -o micro_hnsw.wasm \
    target/wasm32-unknown-unknown/release/micro_hnsw_wasm.wasm

# Check size
ls -la micro_hnsw.wasm

JavaScript Usage

Basic Usage

const response = await fetch('micro_hnsw.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes);
const wasm = instance.exports;

// Initialize: init(dims, metric, core_id)
// metric: 0=L2, 1=Cosine, 2=Dot
wasm.init(8, 1, 0);  // 8 dims, cosine similarity, core 0

// Insert vectors
const insertBuf = new Float32Array(wasm.memory.buffer, wasm.get_insert_ptr(), 16);
insertBuf.set([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
const idx = wasm.insert();  // Returns 0, or 255 if full

// Set node type (for Cypher-style queries)
wasm.set_node_type(idx, 3);  // Type 3 = e.g., "Person"

// Search
const queryBuf = new Float32Array(wasm.memory.buffer, wasm.get_query_ptr(), 16);
queryBuf.set([0.95, 0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
const resultCount = wasm.search(5);  // k=5

// Read results
const resultPtr = wasm.get_result_ptr();
const resultView = new DataView(wasm.memory.buffer, resultPtr);
for (let i = 0; i < resultCount; i++) {
    const idx = resultView.getUint8(i * 8);
    const coreId = resultView.getUint8(i * 8 + 1);
    const dist = resultView.getFloat32(i * 8 + 4, true);

    // Filter by type if needed
    if (wasm.type_matches(idx, 0b1000)) {  // Only type 3
        console.log(`Result: idx=${idx}, distance=${dist}`);
    }
}

Spiking Neural Network (NEW)

// Reset SNN state
wasm.snn_reset();

// Inject current into neurons (simulates input)
wasm.snn_inject(0, 1.5);  // Strong input to neuron 0
wasm.snn_inject(1, 0.8);  // Weaker input to neuron 1

// Run simulation step (dt in ms)
const spikeCount = wasm.snn_step(1.0);  // 1ms timestep
console.log(`${spikeCount} neurons spiked`);

// Propagate spikes to neighbors
wasm.snn_propagate(0.5);  // gain=0.5

// Apply STDP learning
wasm.snn_stdp();

// Or use combined tick (step + propagate + optional STDP)
const spikes = wasm.snn_tick(1.0, 0.5, 1);  // dt=1ms, gain=0.5, learn=true

// Get spike bitset (which neurons fired)
const spikeBits = wasm.snn_get_spikes();
for (let i = 0; i < 32; i++) {
    if (spikeBits & (1 << i)) {
        console.log(`Neuron ${i} spiked!`);
    }
}

// Check individual neuron
if (wasm.snn_spiked(0)) {
    console.log('Neuron 0 fired');
}

// Get/set membrane potential
const v = wasm.snn_get_membrane(0);
wasm.snn_set_membrane(0, 0.5);

// Get simulation time
console.log(`Time: ${wasm.snn_get_time()} ms`);

HNSW-SNN Integration

// Vector search activates matching neurons
// Search converts similarity to neural current
const queryBuf = new Float32Array(wasm.memory.buffer, wasm.get_query_ptr(), 16);
queryBuf.set([0.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);

// hnsw_to_snn: search + inject currents based on distance
const found = wasm.hnsw_to_snn(5, 2.0);  // k=5, gain=2.0

// Now run SNN to see which neurons fire from similarity
wasm.snn_tick(1.0, 0.5, 1);
const spikes = wasm.snn_get_spikes();
console.log(`Similar vectors that spiked: 0b${spikes.toString(2)}`);

GNN Message Passing

// Set edge weights for nodes (0-255, higher = more important)
wasm.set_edge_weight(0, 255);  // Node 0: full weight
wasm.set_edge_weight(1, 128);  // Node 1: half weight

// Aggregate neighbors (GNN-style)
wasm.aggregate_neighbors(0);  // Aggregates neighbors of node 0

// Read aggregated embedding from DELTA buffer
const deltaBuf = new Float32Array(wasm.memory.buffer, wasm.get_delta_ptr(), 16);
console.log('Aggregated:', Array.from(deltaBuf));

// Update vector: v = v + alpha * delta
wasm.update_vector(0, 0.1);  // 10% update toward neighbors

Multi-Core (256 Cores)

const cores = [];
for (let i = 0; i < 256; i++) {
    const { instance } = await WebAssembly.instantiate(wasmBytes);
    instance.exports.init(8, 1, i);
    cores.push(instance.exports);
}

// Parallel search with merging
async function searchAll(query, k) {
    for (const core of cores) {
        new Float32Array(core.memory.buffer, core.get_query_ptr(), 16).set(query);
    }

    const results = await Promise.all(cores.map(c => c.search(k)));

    cores[0].clear_global();
    for (let i = 0; i < cores.length; i++) {
        cores[0].merge(cores[i].get_result_ptr(), results[i]);
    }

    return cores[0].get_global_ptr();
}

C API

// Core API
void init(uint8_t dims, uint8_t metric, uint8_t core_id);
float* get_insert_ptr(void);
float* get_query_ptr(void);
SearchResult* get_result_ptr(void);
SearchResult* get_global_ptr(void);
uint8_t insert(void);
uint8_t search(uint8_t k);
uint8_t merge(SearchResult* results, uint8_t count);
void clear_global(void);

// Info
uint8_t count(void);
uint8_t get_core_id(void);
uint8_t get_metric(void);
uint8_t get_dims(void);
uint8_t get_capacity(void);

// Cypher Node Types
void set_node_type(uint8_t idx, uint8_t type);  // type: 0-15
uint8_t get_node_type(uint8_t idx);
uint8_t type_matches(uint8_t idx, uint16_t type_mask);

// GNN Edge Weights
void set_edge_weight(uint8_t node, uint8_t weight);  // weight: 0-255
uint8_t get_edge_weight(uint8_t node);
void aggregate_neighbors(uint8_t idx);  // Results in DELTA buffer

// Vector Updates
float* get_delta_ptr(void);
float* set_delta_ptr(void);  // Mutable access
void update_vector(uint8_t idx, float alpha);  // v += alpha * delta

// Spiking Neural Network (NEW in v2.2)
void snn_reset(void);                           // Reset all SNN state
void snn_set_membrane(uint8_t idx, float v);    // Set membrane potential
float snn_get_membrane(uint8_t idx);            // Get membrane potential
void snn_set_threshold(uint8_t idx, float t);   // Set firing threshold
void snn_inject(uint8_t idx, float current);    // Inject current
uint8_t snn_spiked(uint8_t idx);                // Did neuron spike?
uint32_t snn_get_spikes(void);                  // Spike bitset (32 neurons)
uint8_t snn_step(float dt);                     // LIF step, returns spike count
void snn_propagate(float gain);                 // Propagate spikes to neighbors
void snn_stdp(void);                            // STDP weight update
uint8_t snn_tick(float dt, float gain, uint8_t learn);  // Combined step
float snn_get_time(void);                       // Get simulation time
uint8_t hnsw_to_snn(uint8_t k, float gain);     // Search → neural activation

// SearchResult structure (8 bytes)
typedef struct {
    uint8_t idx;
    uint8_t core_id;
    uint8_t _pad[2];
    float distance;
} SearchResult;

Real-World Applications

1. Embedded Vector Database

Run semantic search on microcontrollers, IoT devices, or edge servers without external dependencies.

// Semantic search on edge device
// Each core handles a shard of your embedding space
const cores = await initializeCores(256);

// Insert document embeddings (from TinyBERT, MiniLM, etc.)
for (const doc of documents) {
    const embedding = await encoder.encode(doc.text);
    const coreId = hashToCoreId(doc.id);
    cores[coreId].insertVector(embedding, doc.type);
}

// Query: "machine learning tutorials"
const queryVec = await encoder.encode(query);
const results = await searchAllCores(queryVec, k=10);

// Results ranked by cosine similarity across 8K vectors
// Total memory: 7.2KB × 256 = 1.8MB for 8K vectors

Why SNN helps: After search, run snn_tick() with inhibition — only the most relevant results survive the neural competition. Better than simple top-k.


2. Knowledge Graphs (Cypher-Style)

Build typed property graphs with vector-enhanced traversal.

// Define entity types for a biomedical knowledge graph
const GENE = 0, PROTEIN = 1, DISEASE = 2, DRUG = 3, PATHWAY = 4;

// Insert entities with embeddings
insertVector(geneEmbedding, GENE);      // "BRCA1" → type 0
insertVector(proteinEmbedding, PROTEIN); // "p53" → type 1
insertVector(diseaseEmbedding, DISEASE); // "breast cancer" → type 2

// Cypher-like query: Find proteins similar to query, connected to diseases
const proteinMask = 1 << PROTEIN;
const results = wasm.search(20);

for (const r of results) {
    if (wasm.type_matches(r.idx, proteinMask)) {
        // Found similar protein - now traverse edges
        wasm.aggregate_neighbors(r.idx);
        // Check if neighbors include diseases
    }
}

Why SNN helps: Model spreading activation through the knowledge graph. A query about "cancer treatment" activates DISEASE nodes, which propagate to connected DRUG and GENE nodes via snn_propagate().


3. Self-Learning Systems (Online STDP)

Systems that learn patterns from experience without retraining.

// Anomaly detection that learns normal patterns
class SelfLearningAnomalyDetector {
    async processEvent(sensorVector) {
        // Find similar past events
        wasm.hnsw_to_snn(5, 2.0);  // Top-5 similar → neural current

        // Run SNN with STDP learning enabled
        const spikes = wasm.snn_tick(1.0, 0.5, 1);  // learn=1

        if (spikes === 0) {
            // Nothing spiked = no similar patterns = ANOMALY
            return { anomaly: true, confidence: 0.95 };
        }

        // Normal: similar patterns recognized and reinforced
        // STDP strengthened the connection for next time
        return { anomaly: false };
    }
}

// Over time, the system learns what "normal" looks like
// New attack patterns won't match → no spikes → alert

How it works: STDP increases edge weights between vectors that co-activate. Repeated normal patterns build strong connections; novel anomalies find no matching pathways.


4. DNA/Protein Sequence Analysis

k-mer embeddings enable similarity search across genomic data.

// DNA sequence similarity with neuromorphic processing
const KMER_SIZE = 6;  // 6-mer embeddings

// Embed reference genome k-mers
for (let i = 0; i < genome.length - KMER_SIZE; i++) {
    const kmer = genome.slice(i, i + KMER_SIZE);
    const embedding = kmerToVector(kmer);  // One-hot or learned embedding
    wasm.insert();
    wasm.set_node_type(i % 32, positionToType(i));  // Encode genomic region
}

// Query: Find similar sequences to a mutation site
const mutationKmer = "ATCGTA";
const queryVec = kmerToVector(mutationKmer);
wasm.hnsw_to_snn(10, 3.0);

// SNN competition finds the MOST similar reference positions
wasm.snn_tick(1.0, -0.2, 0);  // Lateral inhibition
const matches = wasm.snn_get_spikes();

// Surviving spikes = strongest matches
// Spike timing = match confidence (earlier = better)

Why SNN helps:

  • Winner-take-all: Only the best alignments survive
  • Temporal coding: First spike indicates highest similarity
  • Distributed processing: 256 cores = parallel genome scanning

5. Algorithmic Trading

Microsecond pattern matching for market microstructure.

// Real-time order flow pattern recognition
class TradingPatternMatcher {
    constructor() {
        // Pre-load known patterns: momentum, mean-reversion, spoofing, etc.
        this.patterns = [
            { name: 'momentum_breakout', vector: [...], type: 0 },
            { name: 'mean_reversion', vector: [...], type: 1 },
            { name: 'spoofing_signature', vector: [...], type: 2 },
            { name: 'iceberg_order', vector: [...], type: 3 },
        ];

        for (const p of this.patterns) {
            insertVector(p.vector, p.type);
        }
    }

    // Called every tick (microseconds)
    onMarketData(orderBookSnapshot) {
        const features = extractFeatures(orderBookSnapshot);
        // [bid_depth, ask_depth, spread, imbalance, volatility, ...]

        // Find matching patterns
        setQuery(features);
        wasm.hnsw_to_snn(5, 2.0);

        // SNN decides which pattern "wins"
        wasm.snn_tick(0.1, -0.5, 0);  // Fast tick, strong inhibition

        const winner = wasm.snn_get_spikes();
        if (winner & (1 << 0)) return 'GO_LONG';   // Momentum
        if (winner & (1 << 1)) return 'GO_SHORT';  // Mean reversion
        if (winner & (1 << 2)) return 'CANCEL';    // Spoofing detected

        return 'HOLD';
    }
}

Why SNN helps:

  • Sub-millisecond latency: 7.2KB WASM runs in L1 cache
  • Winner-take-all: Only one signal fires, no conflicting trades
  • Adaptive thresholds: Market regime changes adjust neuron sensitivity

6. Industrial Control Systems (PLC/SCADA)

Predictive maintenance and anomaly detection at the edge.

// Vibration analysis for rotating machinery
class PredictiveMaintenance {
    constructor() {
        // Reference signatures: healthy, bearing_wear, misalignment, imbalance
        this.signatures = loadVibrationSignatures();
        for (const sig of this.signatures) {
            insertVector(sig.fftFeatures, sig.condition);
        }
    }

    // Called every 100ms from accelerometer
    analyzeVibration(fftSpectrum) {
        setQuery(fftSpectrum);

        // Match against known conditions
        wasm.hnsw_to_snn(this.signatures.length, 1.5);
        wasm.snn_tick(1.0, 0.3, 1);  // Learn new patterns over time

        const spikes = wasm.snn_get_spikes();

        // Check which condition matched
        if (spikes & (1 << HEALTHY)) {
            return { status: 'OK', confidence: wasm.snn_get_membrane(HEALTHY) };
        }
        if (spikes & (1 << BEARING_WEAR)) {
            return {
                status: 'WARNING',
                condition: 'bearing_wear',
                action: 'Schedule maintenance in 72 hours'
            };
        }
        if (spikes & (1 << CRITICAL)) {
            return { status: 'ALARM', action: 'Immediate shutdown' };
        }

        // No match = unknown condition = anomaly
        return { status: 'UNKNOWN', action: 'Flag for analysis' };
    }
}

Why SNN helps:

  • Edge deployment: Runs on PLC without cloud connectivity
  • Continuous learning: STDP adapts to machine aging
  • Deterministic timing: No garbage collection pauses

7. Robotics & Sensor Fusion

Combine LIDAR, camera, and IMU embeddings for navigation.

// Multi-modal sensor fusion for autonomous navigation
class SensorFusion {
    // Each sensor type gets dedicated neurons
    LIDAR_NEURONS = [0, 1, 2, 3, 4, 5, 6, 7];      // 8 neurons
    CAMERA_NEURONS = [8, 9, 10, 11, 12, 13, 14, 15]; // 8 neurons
    IMU_NEURONS = [16, 17, 18, 19, 20, 21, 22, 23];  // 8 neurons

    fuseAndDecide(lidarEmbed, cameraEmbed, imuEmbed) {
        wasm.snn_reset();

        // Inject sensor readings as currents
        for (let i = 0; i < 8; i++) {
            wasm.snn_inject(this.LIDAR_NEURONS[i], lidarEmbed[i] * 2.0);
            wasm.snn_inject(this.CAMERA_NEURONS[i], cameraEmbed[i] * 1.5);
            wasm.snn_inject(this.IMU_NEURONS[i], imuEmbed[i] * 1.0);
        }

        // Run competition — strongest signals propagate
        for (let t = 0; t < 5; t++) {
            wasm.snn_tick(1.0, 0.4, 0);
        }

        // Surviving spikes = fused representation
        const fusedSpikes = wasm.snn_get_spikes();

        // Decision: which direction is clear?
        // Spike pattern encodes navigable directions
        return decodeSpikePattern(fusedSpikes);
    }
}

Why SNN helps:

  • Natural sensor fusion: Different modalities compete and cooperate
  • Graceful degradation: If camera fails, LIDAR/IMU still produce spikes
  • Temporal binding: Synchronous spikes indicate consistent information

Architecture: How It All Connects

┌─────────────────────────────────────────────────────────────────────┐
│                         APPLICATION LAYER                            │
├─────────────────────────────────────────────────────────────────────┤
│  Trading   │  Genomics  │  Robotics  │  Industrial  │  Knowledge   │
│  Signals   │  k-mers    │  Sensors   │  Vibration   │  Graphs      │
└─────┬──────┴─────┬──────┴─────┬──────┴──────┬───────┴──────┬───────┘
      │            │            │             │              │
      ▼            ▼            ▼             ▼              ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        EMBEDDING LAYER                               │
│  Convert domain data → 16-dimensional vectors                        │
│  (TinyBERT, k-mer encoding, FFT features, one-hot, learned, etc.)   │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    MICRO HNSW v2.2 CORE (7.2KB)                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐            │
│   │   HNSW      │───▶│    GNN      │───▶│    SNN      │            │
│   │  (Search)   │    │  (Propagate)│    │   (Decide)  │            │
│   └─────────────┘    └─────────────┘    └─────────────┘            │
│         │                   │                  │                    │
│         ▼                   ▼                  ▼                    │
│   ┌──────────┐       ┌──────────┐       ┌──────────┐               │
│   │ Cosine   │       │ Neighbor │       │ LIF      │               │
│   │ L2, Dot  │       │ Aggregate│       │ Dynamics │               │
│   └──────────┘       └──────────┘       └──────────┘               │
│                                                │                    │
│                                                ▼                    │
│                                         ┌──────────┐               │
│                                         │  STDP    │               │
│                                         │ Learning │               │
│                                         └──────────┘               │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        OUTPUT: SPIKE PATTERN                         │
│  • Which neurons fired → Classification/Decision                     │
│  • Spike timing → Confidence ranking                                 │
│  • Membrane levels → Continuous scores                               │
│  • Updated weights → Learned associations                            │
└─────────────────────────────────────────────────────────────────────┘

Quick Reference: API by Use Case

Use Case Key Functions Pattern
Vector DB insert(), search(), merge() Insert → Search → Rank
Knowledge Graph set_node_type(), type_matches(), aggregate_neighbors() Type → Filter → Traverse
Self-Learning snn_tick(..., learn=1), snn_stdp() Process → Learn → Adapt
Anomaly Detection hnsw_to_snn(), snn_get_spikes() Match → Spike/NoSpike → Alert
Trading snn_tick() with inhibition, snn_get_spikes() Compete → Winner → Signal
Industrial snn_inject(), snn_tick(), snn_get_membrane() Sense → Fuse → Classify
Sensor Fusion Multiple snn_inject(), snn_propagate() Inject → Propagate → Bind

Code Examples

Cypher-Style Typed Queries

// Define node types
const PERSON = 0, COMPANY = 1, PRODUCT = 2;

// Insert typed nodes
insertVector([...], PERSON);
insertVector([...], COMPANY);

// Search only for PERSON nodes
const personMask = 1 << PERSON;  // 0b001
for (let i = 0; i < resultCount; i++) {
    if (wasm.type_matches(results[i].idx, personMask)) {
        // This is a Person node
    }
}

GNN Layer Implementation

// One GNN propagation step across all nodes
function gnnStep(alpha = 0.1) {
    for (let i = 0; i < wasm.count(); i++) {
        wasm.aggregate_neighbors(i);  // Mean of neighbors
        wasm.update_vector(i, alpha); // Blend with self
    }
}

// Run 3 GNN layers
for (let layer = 0; layer < 3; layer++) {
    gnnStep(0.5);
}

Spiking Attention Layer

// Use SNN for attention: similar vectors compete via lateral inhibition
function spikingAttention(queryVec, steps = 10) {
    wasm.snn_reset();

    const queryBuf = new Float32Array(wasm.memory.buffer, wasm.get_query_ptr(), 16);
    queryBuf.set(queryVec);
    wasm.hnsw_to_snn(wasm.count(), 3.0);  // Strong activation from similarity

    // Run SNN dynamics - winner-take-all emerges
    for (let t = 0; t < steps; t++) {
        wasm.snn_tick(1.0, -0.3, 0);  // Negative gain = inhibition
    }

    // Surviving spikes = attention winners
    return wasm.snn_get_spikes();
}

Online Learning with STDP

// Present pattern sequence, learn associations
function learnSequence(patterns, dt = 10.0) {
    wasm.snn_reset();

    for (const pattern of patterns) {
        // Inject current for active neurons
        for (const neuron of pattern) {
            wasm.snn_inject(neuron, 2.0);
        }

        // Run with STDP learning enabled
        wasm.snn_tick(dt, 0.5, 1);
    }

    // Edge weights now encode sequence associations
}

ASIC / Verilog

The verilog/ directory contains synthesizable RTL for direct ASIC implementation.

Multi-Core Architecture with SNN

┌─────────────────────────────────────────────────────────────┐
│                    256-Core ASIC Layout                      │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────┐    │
│  │                   SNN Controller                     │    │
│  │  (Membrane, Threshold, Spike Router, STDP Engine)   │    │
│  └─────────────────────────────────────────────────────┘    │
│                         ↕                                    │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐     ┌─────┐ ┌─────┐       │
│  │Core │ │Core │ │Core │ │Core │ ... │Core │ │Core │       │
│  │  0  │ │  1  │ │  2  │ │  3  │     │ 254 │ │ 255 │       │
│  │ 32  │ │ 32  │ │ 32  │ │ 32  │     │ 32  │ │ 32  │       │
│  │ vec │ │ vec │ │ vec │ │ vec │     │ vec │ │ vec │       │
│  │ LIF │ │ LIF │ │ LIF │ │ LIF │     │ LIF │ │ LIF │       │
│  └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘     └──┬──┘ └──┬──┘       │
│     │       │       │       │           │       │           │
│     └───────┴───────┴───────┴───────────┴───────┘           │
│                         ▼                                    │
│              ┌─────────────────────┐                        │
│              │   Result Merger     │                        │
│              │  (Priority Queue)   │                        │
│              └─────────────────────┘                        │
│                         ▼                                    │
│              ┌─────────────────────┐                        │
│              │    AXI-Lite I/F     │                        │
│              └─────────────────────┘                        │
└─────────────────────────────────────────────────────────────┘

Version History

Version Size Features
v1 4.6KB L2 only, single core, greedy search
v2 7.3KB +3 metrics, +multi-core, +beam search
v2.1 5.5KB +node types, +edge weights, +GNN updates, wasm-opt
v2.2 7.2KB +LIF neurons, +STDP learning, +spike propagation, +HNSW-SNN bridge

Performance

Operation Complexity Notes
Insert O(n × dims) Per core
Search O(beam × M × dims) Beam search
Merge O(k × cores) Result combining
Aggregate O(M × dims) GNN message passing
Update O(dims) Vector modification
SNN Step O(n) Per neuron LIF
Propagate O(n × M) Spike routing
STDP O(spikes × M) Only for spiking neurons

SNN Parameters (Compile-time)

Parameter Value Description
TAU_MEMBRANE 20.0 Membrane time constant (ms)
TAU_REFRAC 2.0 Refractory period (ms)
V_RESET 0.0 Reset potential after spike
V_REST 0.0 Resting potential
STDP_A_PLUS 0.01 LTP magnitude
STDP_A_MINUS 0.012 LTD magnitude
TAU_STDP 20.0 STDP time constant (ms)

License

MIT OR Apache-2.0