Skip to content

compile SparseKernelInserter event loop with numba - #34

Merged
cboulay merged 1 commit into
mainfrom
simulator-optimization
Jun 30, 2026
Merged

compile SparseKernelInserter event loop with numba#34
cboulay merged 1 commit into
mainfrom
simulator-optimization

Conversation

@kylmcgr

@kylmcgr kylmcgr commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

SparseKernelInserter._process looped over every event in Python and, per
event, re-evaluated the kernel (allocating a mask + zeros + fancy-index) and
did a sliced add. The cost scaled with channels × firing rate, making it a top
stage in the velocity→ecephys encoder.

This pre-samples every kernel once into a zero-padded table (one row per
distinct kernel, cached in state and rebuilt on stream reset) and scatters it
onto the dense buffer in a numba njit loop. Event value → table row is
resolved vectorized via np.unique over the (typically tiny) set of distinct
values.

The rewrite stays fully general — it works for any Kernel subclass
(ArrayKernel waveforms, FunctionalKernel, unit impulses) and preserves
scale_by_value, acausal pre_samples, and the chunk-boundary pending tail.

Results

Per-stage encoder benchmark (bench_cosine_encoder.py, 256ch @ 30 kHz):

chunk kernel_insert before after speedup
1 (live path) 0.203 ms/call 0.039 ms/call ~5.2×
50 9.78 ms/call 1.68 ms/call ~5.8×

End-to-end (simulator over LSL, 50 Hz, 256ch): WAVEFORMS at 0.097 ms/msg,
flat-to-better despite each message now carrying 2× the samples.

Correctness

  • Output is bit-identical to the previous implementation (max abs diff
    0.0) — kernel insertion is pure indexed addition, no reduction reassociation.
  • 151 unit tests pass (was 147): adds 4 tests covering the new resolution
    paths — scale_by_value with a real kernel and with a MultiKernel, unknown
    values falling back to the default key, and an explicit default_key.

Dependency

Declares numba explicitly. It was already imported by poissonevents.py but
never declared — this fixes that latent gap.

@kylmcgr
kylmcgr requested a review from cboulay June 29, 2026 17:26
@kylmcgr kylmcgr self-assigned this Jun 29, 2026
@cboulay
cboulay merged commit 0718b26 into main Jun 30, 2026
6 checks passed
@cboulay
cboulay deleted the simulator-optimization branch June 30, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants