I finally got time to play with Brian’s new feature.
The big problem is that I need to run simulations for a few days of model time! Of course, even if I record a dozen of neurons from a thousand, just for debugging purposes, I hit memory overflow in a few hours of model time
So, the idea is to stop the simulation from time to time, save data into a file and continue the run.
Non-stop simulation
Hear, a simple balanced network, just to illustrate an issue with this approach on Brian:
import os
from brian2 import *
set_device('cpp_standalone')
prefs.devices.cpp_standalone.openmp_threads = os.cpu_count()-1
El,gl,taum = -60, 0.005, 20*ms
Ee ,taue = 0 , 5*ms
Ei ,taui = -80 , 50*ms
equ='''
dv/dt = (gl*(El-v)+ge*(Ee-v)+gi*(Ei-v))/taum : 1 (unless refractory)
dge/dt = -ge/taue : 1
dgi/dt = -gi/taui : 1
'''
pop = NeuronGroup(1000,equ,method='rk4',threshold='v>-10', reset='v=El', refractory=5*ms)
pop.v = El
pie = PoissonInput(pop[:500], 'ge', 100, 100*Hz, weight=5e-4)
esyn = Synapses(pop,pop,'w : 1', on_pre='ge_post += w')
esyn.connect(p=0.2)
esyn.w = 0.1
esyn.delay = 200*ms
isyn = Synapses(pop,pop,'w : 1', on_pre='gi_post += w')
isyn.connect(p=0.2)
isyn.w = 0.002
esyn.delay = 200*ms
spm = SpikeMonitor(pop)
stm = StateMonitor(pop,['v','ge','gi'],record=[499,501])
run(200*second)
ax = subplot(411)
plot(spm.t/ms, spm.i, 'k.')
subplot(412,sharex=ax)
plot(stm.t/ms,stm.v[0],'k-')
plot(stm.t/ms,stm.v[1],'r-')
subplot(413,sharex=ax)
plot(stm.t/ms,stm.ge[0],'k-')
plot(stm.t/ms,stm.ge[1],'r-')
subplot(414,sharex=ax)
plot(stm.t/ms,stm.gi[0],'k-')
plot(stm.t/ms,stm.gi[1],'r-')
show()
Simulation with multiple stops
If I use the new method, something is missing
import os
from brian2 import *
set_device('cpp_standalone', build_on_run=False)
prefs.devices.cpp_standalone.openmp_threads = os.cpu_count()-1
El,gl,taum = -60, 0.005, 20*ms
Ee ,taue = 0 , 5*ms
Ei ,taui = -80 , 50*ms
equ='''
dv/dt = (gl*(El-v)+ge*(Ee-v)+gi*(Ei-v))/taum : 1 (unless refractory)
dge/dt = -ge/taue : 1
dgi/dt = -gi/taui : 1
'''
pop = NeuronGroup(1000,equ,method='rk4',threshold='v>-10', reset='v=El', refractory=5*ms)
pie = PoissonInput(pop[:500], 'ge', 100, 100*Hz, weight=5e-4)
esyn = Synapses(pop,pop,'w : 1', on_pre='ge_post += w')
esyn.connect(p=0.2)
esyn.w = 0.1
esyn.delay = 200*ms
isyn = Synapses(pop,pop,'w : 1', on_pre='gi_post += w')
isyn.connect(p=0.2)
isyn.w = 0.002
esyn.delay = 200*ms
spm = SpikeMonitor(pop)
stm = StateMonitor(pop,['v','ge','gi'],record=[499,501])
run(5*second)
device.build(run=False)
ax1 = subplot(411)
ax2 = subplot(412,sharex=ax1)
ax3 = subplot(413,sharex=ax1)
ax4 = subplot(414,sharex=ax1)
vm = ones(1000)*El
ge = zeros(1000)
gi = zeros(1000)
for _x in range(40):
device.run(run_args={pop.v: vm, pop.ge: ge, pop.gi: gi})
ax1.plot(spm.t/ms+5000*_x, spm.i, 'k.')
ax2.plot(stm.t/ms+5000*_x,stm.v[0],'k-')
ax2.plot(stm.t/ms+5000*_x,stm.v[1],'r-')
ax3.plot(stm.t/ms+5000*_x,stm.ge[0],'k-')
ax3.plot(stm.t/ms+5000*_x,stm.ge[1],'r-')
ax4.plot(stm.t/ms+5000*_x,stm.gi[0],'k-')
ax4.plot(stm.t/ms+5000*_x,stm.gi[1],'r-')
vm = pop.v[:]
ge = pop.ge[:]
gi = pop.gi[:]
show()
and results aren’t pretty
An Issue
Well, it is obviously the spike queue! Is it possible to save the spike queue somewhere and then restore it from the file? That will solve any problem of a long run with multiple stops.
Note This method works perfectly if there are no delays in the system. But as soon as spikes have to wait in spike queue, this method have an issue.