Closed PikaPei closed 10 months ago
Thanks for the question. I will give you an example later.
Thanks for the report.
The device's memory is occupied by three parts: 1. data or arrays; 2. compiled functions (including a lot of constants); 3. brainpy objects.
Therefore, for each of your single run function, I recommend using the following command to clear them all.
import brainpy.math as bm
def run_one_model(pars):
model = ....
model.run()
l = model.loss()
l = np.asarray(l)
bm.clear_name_cache(ignore_warn=True)
bm.clear_buffer_memory(array=True, compilation=True)
return l
I hope this message is of some help.
Thanks for the suggestion!
However, it didn't work. Even a simple example eventually caused a crash. Would it be somewhat OS-dependent? I'm using Linux.
import brainpy as bp
import brainpy.math as bm
bm.set_environment(x64=True)
class Model(bp.NeuGroup):
def __init__(self, size):
super().__init__(size=size)
self.var1 = bm.Variable(bm.zeros(self.num))
self.integral = bp.odeint(self.dvar1, method="exp_auto")
def dvar1(self, var1, t):
dvar1dt = -var1
return dvar1dt
def update(self):
t = bp.share["t"]
dt = bp.share["dt"]
self.var1.value = self.integral(self.var1, t, dt=dt)
def run(self, duration):
self.runner = bp.DSRunner(self, monitors=["var1"])
self.runner.run(duration)
if __name__ == "__main__":
for _ in range(100):
for _ in range(100):
model = Model(size=50)
model.run(20000)
# clear cache after 100 iterations
bm.clear_name_cache(ignore_warn=True)
bm.clear_buffer_memory(array=True, compilation=True)
Thanks for the report. Please use brainpy.math.for_loop
. DSRunner
may have a memory leak. I have rewritten your code as:
import numpy as np
import brainpy as bp
import brainpy.math as bm
bm.set_environment(x64=True)
class Model(bp.NeuGroup):
def __init__(self, size):
super().__init__(size=size)
self.var1 = bm.Variable(bm.zeros(self.num))
self.integral = bp.odeint(self.dvar1, method="exp_auto")
def dvar1(self, var1, t):
dvar1dt = -var1
return dvar1dt
def update(self):
t = bp.share["t"]
dt = bp.share["dt"]
self.var1.value = self.integral(self.var1, t, dt=dt)
def one_iter(n=10):
for _ in range(n):
def step(i):
model.step_run(i)
bp.clear_input(model)
return model.var1.value
model = Model(size=50)
bm.for_loop(step, np.arange(int(20000 / bm.get_dt())), progress_bar=False)
print(f'clear cache after {n} iterations')
bm.clear_name_cache(ignore_warn=False)
bm.clear_buffer_memory('cpu', array=True, compilation=True)
if __name__ == "__main__":
for _ in range(100):
one_iter()
This solution works well for now. But memory usage still goes up slowly, even after using bm.for_loop
with bm.clear_name_cache
and bm.clear_buffer_memory
in every iteration.
In my case, it can handle 100 iterations without crashing, which is quite good. However, I think if it goes beyond 200 or 300 iterations, the program will probably shut down.
Still, I am very thankful for the current progress!
I'll close this issue. If the error still occurs, please open it at any time.
I figured out the memory issue, and it's from my model implementation. May I pose a question?
The code shown below is causing the memory to increase, mainly because I use self.solution["Time"] = t * bm.get_dt()
to store data.
I also think my original implementation with DSRunner had the same problem, which is that I put it inside the class, although I haven't tested it.
I'm wondering if this implementation is not a good way to do it, and what your recommendations would be? Thank you!
import brainpy as bp
import brainpy.math as bm
import numpy as np
bm.set_environment(x64=True)
class Model(bp.NeuGroup):
def __init__(self):
super().__init__(size=1)
self.duration = 10000
self.var1 = bm.Variable(bm.zeros(self.num))
self.integral = bp.odeint(self.dvar1, method="exp_auto")
def dvar1(self, var1, t):
dvar1dt = -var1
return dvar1dt
def update(self):
t = bp.share["t"]
dt = bp.share["dt"]
self.var1.value = self.integral(self.var1, t, dt=dt)
def step(self, i):
self.step_run(i)
bp.clear_input(self)
return self.var1.value
def run_for_loop(self, duration=None, **kwargs):
t = np.arange(int(self.duration / bm.get_dt()))
sol = bm.for_loop(self.step, t, **kwargs)
self.solution = {}
self.solution["Time"] = t * bm.get_dt() # key problem
self.solution["var1"] = sol
if __name__ == "__main__":
for _ in range(10000):
for _ in range(100):
model = Model()
model.run_for_loop(progress_bar=False)
bm.clear_name_cache(ignore_warn=True)
bm.clear_buffer_memory(array=True, compilation=True)
print("Cleared name cache and buffer memory.")
Hi BrainPy team!
I'd like to use BrainPy to build my model and use particle swarm optimization (PSO, by PySwarms) to find the best parameters. However, the memory usage increased quickly when re-initializing a new model within each iteration, resulting in the program eventually crashing. I thought it was because I kept generating new models without destroying them properly, so I tried the
bm.clear_buffer_memory()
, but this approach didn't help.Below is my pseudo code (you can see I create 100*100 models in my script). I can provide more details if needed. I would appreciate any advice. Thank you!