brain
A whole connectome running as a leaky integrate-and-fire network on the GPU. `Brain.load` binds any `connectome` asset to the package's four `lif_*` kernels and returns a network; the `FruitFlyBrain` component is the usual owner, and anything holding the network can step, drive,…
brain
A whole connectome running as a leaky integrate-and-fire network on the GPU.
Brain.load binds any connectome asset to the package's four lif_*
kernels and returns a network; the FruitFlyBrain component is the usual
owner, and anything holding the network can step, drive, cut, read out and
draw it.
Exports
M.load(connectomeRef, params?) -> Brain— allocate the network at rest.paramsoverrides any ofdtMs,vRest,vThresh,vReset,tauM,tauSyn,refracMs,delayMs,weightMv,gain,minSynapses,traceMs,maxSpikes,seed.brain:update(dt)— once a frame: queue the stepsdtcovers, issue and drain the counter readback.brain:step(n)— queuensteps outright.brain:select(sel) -> { index }— the neurons a selection names.brain:stimulate(sel, hz)/brain:clearStimulation()— Poisson drive.brain:silence(sel, on)— ablate or restore.brain:watch(name, sel)/brain:unwatch(name)/brain:rates()— read groups out as Hz per neuron.brain:activity()— network mean rate, total spikes, dropped spikes, simulated time.brain:info(i)— what one neuron is.brain:showCloud(opts)/brain:hideCloud()/brain:worldPosition(i)— the instanced neuron cloud.brain:setParams(patch),brain:setRunning(on),brain:setTimeScale(x),brain:reset(),brain:ready(),brain:destroy(),brain:describe().
Usage
local Brain = require("~.brain") -- from inside the package
local brain = Brain.load(asset.resolve("fruitFly.maleCNS", "connectome"), { gain = 0.6 })
brain:watch("MN9", { types = { "MN9" } })
brain:stimulate({ types = { "claw_tpGRN" } }, 100)
-- every frame:
brain:update(dt)
print(brain:rates().MN9)
A selection is { types?, typePrefix?, pattern?, classes?, superclasses?, sides?, excitatory?, indices?, limit? }; every given key must hold.
Notes
- The network is silent until something is driven; a spike always traces back to a stimulus.
- Every GPU buffer is named
brain.<id>.<name>;compute.observe()lists them.destroyreleases them all. - The kernels'
paramsare per shader, so two networks on one engine share the model constants the lastapplyParamswrote.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2A spiking simulation of a whole connectome on the GPU. `Brain.load` binds any `connectome` asset to the four `lif_*` kernels of this package and returns a network you step, stimulate, silence, read out and draw: leaky integrate-and-fire neurons, synapse-count weights signed by the presynaptic transmitter, a fixed-point input ring for the synaptic delay, Poisson external drive per neuron, per-group spike counters read back every frame, and an instanced neuron cloud lit by each neuron's activity.
neuronMesh( ) → void
The octahedron every neuron is drawn as: six vertices, eight faces, unit radius. Flat normals come from the position, which is what a point needs.
load(connectome: any, opts: { [string]: any }?) →
Load a connectome onto the GPU as a spiking network at rest. value of a component's `Field.assetRef("connectome", ...)`, or `asset.resolve("maleCNS", "connectome")` written as a literal. `vThresh`, `vReset`, `tauM`, `tauSyn`, `refracMs`, `delayMs`, `weightMv`, `gain`, `traceMs`, `maxSpikes`, `seed`.
| arg | type | description |
|---|---|---|
| connectome | any | The connectome asset, an `AssetRef<connectome>` — the |
| opts | { [string]: any }? | Optional overrides of the model parameters: `dtMs`, `vRest`, |
examples
local brain = Brain.load("maleCNS", { gain = 0.5 })applyParams( ) →
Push the model parameters to the kernels. Called by `load`, and again by `setParams` after a change.
examples
brain:applyParams()
setParams(patch: { [string]: number }) →
Change model parameters live: any key `load` accepts. A change to `dtMs`, `tauM`, `tauSyn`, `delayMs`, `weightMv` or `gain` takes effect on the next step without a reset.
| arg | type | description |
|---|---|---|
| patch | { [string]: number } | The keys to change. |
examples
brain:setParams({ gain = 0.3 })reset( ) →
Put the network back at rest: every membrane at `vRest`, the input ring empty, the counters at zero, the clock at step zero. Stimulation, silencing and readout groups are kept.
examples
brain:reset()
flushCpu(self: ?) → void
| arg | type | description |
|---|---|---|
| self | ? |
step(count: number) →
Queue `count` simulation steps of `dtMs` each. Every step is three dispatches: integrate, propagate, clear.
| arg | type | description |
|---|---|---|
| count | number | How many steps. |
examples
brain:step(10)
ready( ) → boolean
Whether all four kernels are compiled and resident. A step asked for before then is skipped rather than queued behind the compile, so the network's clock only runs on kernels that exist.
examples
if brain:ready() then brain:step(1) end
drainReadbacks(self: ?) → void
| arg | type | description |
|---|---|---|
| self | ? |
update(dt: number) → number
Advance the network by real time: queues as many steps as `dt` seconds times `timeScale` covers (at most `maxStepsPerFrame`), issues the counter readback for this frame, and folds in every readback that has arrived. Call once per frame.
| arg | type | description |
|---|---|---|
| dt | number | Seconds since the previous call. |
examples
function update(dt) brain:update(dt) end
setRunning(on: boolean) →
Whether the network advances on `update`. `false` freezes it while keeping every state.
| arg | type | description |
|---|---|---|
| on | boolean | Run or hold. |
examples
brain:setRunning(false)
setTimeScale(scale: number) →
Simulated milliseconds per real second, as a multiple of real time; bounded by `maxStepsPerFrame` steps a frame.
| arg | type | description |
|---|---|---|
| scale | number | 1 is real time. |
examples
brain:setTimeScale(0.25)
simulatedMs( ) → number
How many milliseconds of network time have been simulated.
examples
print(brain:simulatedMs())
count( ) → number
How many neurons the network holds.
examples
brain:count()
info(i: number) →
What one neuron is: its soma position (micrometres, centred), its type, class, superclass, side, transmitter, out-degree, source body id, and whether it excites its targets.
| arg | type | description |
|---|---|---|
| i | number | The neuron index, from 0. |
examples
local info = brain:info(0)
select(sel: Selection) →
The neurons a selection names, as an array of indices (from 0). A selection combines any of: `types` (exact type names), `typePrefix`, `pattern` (a Lua pattern over the type name), `classes`, `superclasses`, `sides`, `excitatory`, `indices`; every given key must hold. `limit` caps the count.
| arg | type | description |
|---|---|---|
| sel | Selection | The selection. |
examples
local mn9 = brain:select({ types = { "MN9" } })test(i: number) → boolean
| arg | type | description |
|---|---|---|
| i | number |
resolveSelection(self: ?, sel: any) → void
| arg | type | description |
|---|---|---|
| self | ? | |
| sel | any |
stimulate(sel: any, rateHz: number) → number
Drive a set of neurons with external spikes at a Poisson rate. A rate of 0 stops driving them. Stimulation persists across `reset`.
| arg | type | description |
|---|---|---|
| sel | any | A selection, or an array of indices. |
| rateHz | number | Spikes per second per neuron. |
examples
brain:stimulate({ types = { "claw_tpGRN" } }, 100)clearStimulation( ) →
Stop every external drive.
examples
brain:clearStimulation()
silence(sel: any, silenced: boolean) → number
Silence a set of neurons (an ablation: they never spike) or restore them.
| arg | type | description |
|---|---|---|
| sel | any | A selection, or an array of indices. |
| silenced | boolean | True to silence, false to restore. |
examples
brain:silence({ types = { "DNp01" } }, true)slotOf(w: number, s: number) → number
| arg | type | description |
|---|---|---|
| w | number | |
| s | number |
withSlot(w: number, s: number, id: number) → number
| arg | type | description |
|---|---|---|
| w | number | |
| s | number | |
| id | number |
clearGroup(self: ?, id: number) → void
Take a group off every neuron that carries it in one of its slots.
| arg | type | description |
|---|---|---|
| self | ? | |
| id | number |
watch(name: string, sel: any) → number
Read a set of neurons out under a name: from then on `rates()` reports their mean firing rate. A neuron reads out under up to three groups at once; a fourth replaces the oldest. Watching a name again replaces its selection. Up to 255 groups.
| arg | type | description |
|---|---|---|
| name | string | The group's name. |
| sel | any | A selection, or an array of indices. |
examples
brain:watch("MN9", { types = { "MN9" } })unwatch(name: string) → boolean
Stop reading a group out. Its name and id are released.
| arg | type | description |
|---|---|---|
| name | string | The group's name. |
examples
brain:unwatch("MN9")rates( ) →
The mean firing rate of every watched group, in spikes per second per neuron, over the steps between the last two counter readbacks.
examples
for name, hz in pairs(brain:rates()) do print(name, hz) end
activity( ) →
The mean firing rate over the whole network, Hz per neuron, and the spikes the list could not hold (which lose their propagation).
examples
print(brain:activity().hz)
group(name: string) →
The indices a watched group holds.
| arg | type | description |
|---|---|---|
| name | string | The group's name. |
examples
brain:group("MN9")readActivity( ) →
Start an asynchronous read of every neuron's activity lane: the trace, the normalised membrane and the spike flag. Poll the handle's `:state()`; `:result()` is 16 floats per neuron, the first three being those values.
examples
local rb = brain:readActivity()
showCloud(opts: { [string]: any }?) →
Draw every neuron with a soma as an instanced octahedron lit by its own activity. `origin` places the brain's centre in the world, `scale` is world units per micrometre, `radius` the octahedron's radius in world units, `rotation` an optional quaternion. Call once; the cloud follows the network until `hideCloud`.
| arg | type | description |
|---|---|---|
| opts | { [string]: any }? | `{ origin?, scale?, radius?, material? }`. |
examples
brain:showCloud({ origin = { 0, 2, 0 }, scale = 0.01, radius = 0.012 })worldPosition(i: number) →
Where a neuron sits in the world while the cloud is shown.
| arg | type | description |
|---|---|---|
| i | number | The neuron index. |
examples
local x, y, z = brain:worldPosition(i)
hideCloud( ) →
Take the neuron cloud down.
examples
brain:hideCloud()
destroy( ) →
Release every GPU buffer the network holds. The handle is dead after this.
examples
brain:destroy()
describe( ) →
A one-table summary for logs and inspectors.
examples
print(Json.encode(brain:describe()))
Selection = {Params = {Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
Problems
Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.
agent_score is exposed.+ quality × 0.35
+ performance × 0.25
± compat factor
Usability ratings
Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".
Scoped to this part · feeds back into the world's score.