AttributeError when trying "device.build()" in standalone mode

Description of problem

I followed the instruction stated in Brian2 documentation “User’s guide > Computational methods and efficiency > Stnadalone code generation”.
I had multiple builds so I added two lines after the ‘device.build()’ function :
device.reinit(self=device)
device.activate(self=device, build_on_run=False)

with the previously set build options provided to device.activate() function.
However, this generated an AttributeError: module ‘brian2tools.baseexport.device’ has no attribute ‘build’.

Therefore I tried in a different way, I added these two lines instead of ones above :
devices.Device.reinit(self=device)
devices.Device.activate(self=device, build_on_run=False)

Then, it raised another error, which is
Traceback (most recent call last):
File “/Users/yllee/Documents/SNN/snn_mnist_digit_recognisation-master-Brian2STDPMNIST-master/Brian2STDPMNIST-master/b2cpp/DC_snn_MNIST_B2c++_v3.py”, line 492, in
devices.Device.activate(self=device, build_on_run=False)
File “/Users/yllee/anaconda3/envs/snnpj/lib/python3.11/site-packages/brian2/devices/device.py”, line 333, in activate
if self.defaultclock is None:
^^^^^^^^^^^^^^^^^
AttributeError: module ‘brian2tools.baseexport.device’ has no attribute ‘defaultclock’

An another AttributeError that says there is no ‘defaultclock’.
In the documentation, it says that
" Device.activate will reset the 'defaultclock, you’ll therefore have to set its dt*after* theactivate` call if you want to use a non-default value."
I guess the ‘device.activate()’ function attempted to reset the defaultclock but it couldn’t find it.

How can I solve this problem?

Minimal code to reproduce problem

import brian2 as b2
from brian2 import *
from brian2 import devices
import brian2tools as b2t
from brian2tools import *

set_device('cpp_standalone', build_on_run=False)

neuron_eqs_e = '''
        dv/dt = ((v_rest_e - v) + (I_synE+I_synI) / nS) / (100*ms)  \
            : volt (unless refractory)
        I_synE = ge * nS *         -v                           : amp
        I_synI = gi * nS * (-100.*mV-v)                          : amp
        dge/dt = -ge/(1.0*ms)                                   : 1
        dgi/dt = -gi/(2.0*ms)                                  : 1
        dtheta/dt = -theta / (tc_theta)  : volt
        dtimer/dt = 0.1  : second
        '''
v_thresh_e_str = '(v>(theta - offset + v_thresh_e)) and (timer>refrac_e)'
refrac_e = 5.*b2.ms
tc_theta = 1e7*b2.ms
theta_plus_e = 0.05*b2.mV
scr_e = 'v = v_reset_e; theta += theta_plus_e; timer = 0*ms'

neuron_groups['e'] = b2.NeuronGroup(
    100, neuron_eqs_e, threshold= v_thresh_e_str, 
    refractory= refrac_e, reset= scr_e, method='euler'
)

devices.Device.build(self=device, directory='output', compile=True, run=True, debug=False)

devices.Device.reinit(self=device)
devices.Device.activate(self=device, build_on_run=False)

What you have aready tried

I followed the brian2 documentation.

Expected output (if relevant)

Actual output (if relevant)

Full traceback of error (if relevant)

First trial :
Traceback (most recent call last):
File “/Users/yllee/Documents/SNN/snn_mnist_digit_recognisation-master-Brian2STDPMNIST-master/Brian2STDPMNIST-master/b2cpp/DC_snn_MNIST_B2c++_v3.py”, line 489, in
device.build(self=device, directory=‘output’, compile=True, run=True, debug=False)
^^^^^^^^^^^^
AttributeError: module ‘brian2tools.baseexport.device’ has no attribute ‘build’

Second Trial :
Traceback (most recent call last):
File “/Users/yllee/Documents/SNN/snn_mnist_digit_recognisation-master-Brian2STDPMNIST-master/Brian2STDPMNIST-master/b2cpp/DC_snn_MNIST_B2c++_v3.py”, line 492, in
devices.Device.activate(self=device, build_on_run=False)
File “/Users/yllee/anaconda3/envs/snnpj/lib/python3.11/site-packages/brian2/devices/device.py”, line 333, in activate
if self.defaultclock is None:
^^^^^^^^^^^^^^^^^
AttributeError: module ‘brian2tools.baseexport.device’ has no attribute ‘defaultclock’

Hi @Elina The problem is due to the import statements here:

import brian2 as b2
from brian2 import *
from brian2 import devices
import brian2tools as b2t
from brian2tools import *

Importing everything from brian2 with the wildcard import will give you access to the device that is mentioned in the documentation. However, the wildcard import from brian2tools after it will overwrite this with an unrelated module from brian2tools, also called device – this is why your error messages refer to brian2tools.baseexport.device. If you need brian2tools, I wouldn’t do a wildcard import from it, in particular since you already import it as b2t. Similar for brian2, if you already import it and use it as b2, no need to have additional import statements. If you remove everything except for the import brian2 as b2, you can use b2.set_device, b2.device.build, b2.device.reinit, …

Also note that you never need to get self arguments to functions. In Python you usually write:

net = Network(...)
net.run(...)

instead of

net = Network(...)
Network.run(self=net, ...)

even though the two do the same thing. So don’t use devices.Device.activate(self=device), but rather device.activate() – of course using the correct device as explained above.

Hope that makes things clearer!

PS: Just to check: are you sure you need multiple builds?

1 Like

Thank you so much! Your help has resolved my problem.

1 Like