Description of problem
I want to save the entire network (setup and states) to reuse across interpreter sessions. I wish I could pickle/dill the whole thing, but this runs into problems with weakref
and generated code. I see the closest thing to a solution provided by Brian is the store()/restore()
functions but for restore
to work I need to reconstruct the network exactly as before. I’ll do it if I have to, but first, how hard would it be to automate the reconstruction part (everything minus generated code, I assume)? If it wouldn’t be overly difficult, I’d rather contribute a general solution to future Brian users than just solve the problem one time for my use case.
For context, I need to save and load the network repeatedly in different parts of an experiment pipeline (which I mentioned here). For example, run a training simulation once, save the whole network, then run experiments with different parameters in parallel. I need to be able to load the trained network from the saved file in multiple interpreter sessions.
Ideas
- create additional
save()/load()
functions, could pickle everything including states but removing problematic parts (weakrefs, device?) - optionally save the device (
device['arrays']
seems to be where the weakref problem is occurring) with normal, not weak, references
Full traceback of error (if relevant)
weakref causes problems after unpickling, but only once I try to run:
Traceback (most recent call last):
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/core/network.py", line 1003, in before_run
obj.before_run(run_namespace)
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/groups/group.py", line 1266, in before_run
self.create_code_objects(run_namespace)
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/groups/group.py", line 1259, in create_code_objects
code_object = self.create_default_code_object(run_namespace)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/groups/group.py", line 1240, in create_default_code_object
self.codeobj = create_runner_codeobj(
^^^^^^^^^^^^^^^^^^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/codegen/codeobject.py", line 484, in create_runner_codeobj
return device.code_object(
^^^^^^^^^^^^^^^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/devices/device.py", line 358, in code_object
codeobj = codeobj_class(
^^^^^^^^^^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/codegen/runtime/cython_rt/cython_rt.py", line 108, in __init__
super().__init__(
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/codegen/runtime/numpy_rt/numpy_rt.py", line 201, in __init__
self.variables_to_namespace()
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/codegen/runtime/cython_rt/cython_rt.py", line 249, in variables_to_namespace
self.namespace[dyn_array_name] = self.device.get_value(
^^^^^^^^^^^^^^^^^^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/site-packages/brian2/devices/device.py", line 529, in get_value
return self.arrays[var]
~~~~~~~~~~~^^^^^
File "/home/kyle/miniforge3/envs/snakemake/lib/python3.12/weakref.py", line 415, in __getitem__
return self.data[ref(key)]
~~~~~~~~~^^^^^^^^^^
KeyError: <weakref at 0x7fd42b8e2e30; to 'DynamicArrayVariable' at 0x7fd42b821310>