Having a runtime error in my stateMonitor for brian2cuda

Description of problem

I am trying to run brian2cuda on my neuron model but I am getting a parallelization error coupled with an error in my state monitors. The error doesn’t seem caused by compatibility since a simpler demo file works fine and it isn’t inherent to the code either because when I run without brian2cuda the code will compile and run fine. I was wondering if I could get some advice as to what could be going wrong in my code. Thank you in advance for your help.

Minimal code to reproduce problem

This is my brian2cuda implementation

print(brian2cuda.__version__)

print(brian2cuda.cuda_prefs)

set_device("cuda_standalone")

prefs.devices.cuda_standalone.cuda_backend.cuda_path = 'micromamba/envs/cuda_env'

This is the code in that has the error in question

def _create_State_Monitors(num_group):
  stateMonitors = []
  for i in num_group:
    state = StateMonitor(i, 'v', record = True)
    stateMonitors.append(state)
  return stateMonitors

What you have aready tried

I have tried running the code without brian2cuda and the program doesn’t have this error and runs to completion. I also ran a simplified program with just a simple neuron model and it ran and compiled as well. Here is the simplified code

import brian2cuda
import brian2
from brian2 import *

set_device('cuda_standalone')
prefs.devices.cuda_standalone.cuda_backend.cuda_path = '/home/stefano/micromamba/envs/cuda_env'

N = 1000
tau = 10*ms
eqs = '''
dv/dt = (v0 - v) / tau : volt (unless refractory)
v0 : volt
'''
group = NeuronGroup(N, eqs, threshold='v > 10*mV', reset='v = 0*mV',
                    refractory=5*ms, method='exact')

run(50*ms)

Full traceback of error (if relevant)

Traceback (most recent call last):
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/cuda_generator.py", line 403, in translate_one_statement_sequence
    raise ParallelisationError()
brian2cuda.cuda_generator.ParallelisationError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/core/network.py", line 1003, in before_run
    obj.before_run(run_namespace)
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/groups/group.py", line 1266, in before_run
    self.create_code_objects(run_namespace)
  File "micromamba/envs/cuda_env/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 "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/groups/group.py", line 1240, in create_default_code_object
    self.codeobj = create_runner_codeobj(
                   ^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/codegen/codeobject.py", line 484, in create_runner_codeobj
    return device.code_object(
           ^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/device.py", line 423, in code_object
    codeobj = super(CUDAStandaloneDevice, self).code_object(owner, name, abstract_code, variables,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/devices/cpp_standalone/device.py", line 704, in code_object
    codeobj = super().code_object(
              ^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/devices/device.py", line 324, in code_object
    scalar_code, vector_code, kwds = generator.translate(
                                     ^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/codegen/generators/base.py", line 303, in translate
    translated = self.translate_statement_sequence(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/codegen/generators/base.py", line 146, in translate_statement_sequence
    vector_code[name] = self.translate_one_statement_sequence(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/cuda_generator.py", line 412, in translate_one_statement_sequence
    lines += self.translate_to_read_arrays(read, write, indices)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/cuda_generator.py", line 349, in translate_to_read_arrays
    line = line + self.get_array_name(var) + '[' + index_var + '];'
                  ^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/cuda_generator.py", line 277, in get_array_name
    return device.get_array_name(var, access_data=True, prefix=prefix)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/device.py", line 182, in get_array_name
    array_name = self.arrays[var]
                 ~~~~~~~~~~~^^^^^
KeyError: <ArrayVariable(dimensions=metre ** 2 * kilogram * second ** -3 * amp ** -1,  dtype=float64, scalar=False, constant=False, read_only=False)>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "Kopsich_Neuron_Model-1/Scripts/FullyAbstractedKopsichModel.py", line 44, in <module>
    net.run(runtime, report = 'text')
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2/core/base.py", line 344, in device_override_decorated_function
    return getattr(curdev, name)(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "micromamba/envs/cuda_env/lib/python3.12/site-packages/brian2cuda/device.py", line 1546, in network_run
    net.before_run(namespace)
  File "micromamba/envs/cuda_env/lib/python3.12 ", line 346, in device_override_decorated_function
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  packages/brian2/core/network.py", line 1005, in before_run
    raise BrianObjectException(
brian2.core.base.BrianObjectException: Error encountered with object named 'statemonitor'.
Object was created here (most recent call only, full details in debug log):
 line 6, in _create_State_Monitors
    state = StateMonitor(i, 'v', record = True)

Hi @spoma33, thank you for your report. Unfortunately, I’m having a hard time to understand what happened here – I’d say it’s most likely a bug in brian2cuda! From the error message, it seems to have trouble to find the internal record of the v variable, but I don’t quite see why. I don’t think I can debug this further without code that actually reproduces the problem. I don’t think the create_State_Monitors function is to blame, at least if I use it in an extended version of your simple example, everything seems to work fine – you didn’t mention whether the groups you record from are actual groups or subgroups, so I tried both:

set_device('cuda_standalone')

N = 1000
tau = 10*ms
eqs = '''
dv/dt = (v0 - v) / tau : volt (unless refractory)
v0 : volt
'''
group1 = NeuronGroup(N, eqs, threshold='v > 10*mV', reset='v = 0*mV',
                    refractory=5*ms, method='exact')
group2 = NeuronGroup(N, eqs, threshold='v > 10*mV', reset='v = 0*mV',
                    refractory=5*ms, method='exact')

net = Network(group1, group2)
net.add(_create_State_Monitors([group1, group2]))
net.add(_create_State_Monitors([group1[:N//2], group1[N//2:]]))
net.run(50*ms)

This runs without any error, so I don’t know what I should do next to try to reproduce the issue.

Two recommendations for future reports of this kind:

  1. Very good reflex to print the brian2cuda version and the preferences, but it would be helpful to also include the output :wink: Regarding the preferences, they are unfortunately not that easy to print (you are printing the module that defines them, not the actual preferences) – but if you are only changing the cuda_path, this should not be related to this issue.
  2. When you include code, please wrap them in triple backticks like in the following example, otherwise they are hard to read and to copy&paste:
```
# A comment
print("Python code")
```

Thanks :pray: !

Oh okay I will keep that in mind when I ask again. If I have a large block of code should I wrap smaller subsets up to a certain number of lines in backticks or should I just wrap it once?

Also do you know if there are any websites where could I find out more about brian2cuda and brian2 interactions to see if there is something wrong with my code’s setup for brian2cuda?

It doesn’t matter much, but I’d split it up into smaller chunks if you want to “walk us through” the code, by commenting each chunk, and use one big chunk otherwise. If the code gets too big, it will be put into a scrollable box automatically, so don’t worry about pasting a long source file, it will not take up all the screen. If you want to get fancy, you can also use something like

<details>
<summary>The code</summary>

```
print("my code")
```

</details>

which gets rendered as

The code
print("my code")

(Note that the empty line after </summary> is necessary for the syntax highlighting to work – HTML in markdown is sometimes a bit fiddly).

I don’t know of any other place – this very discussion forum is all we got, I’m afraid. Please note that brian2cuda is not as stable and widely used as the rest of Brian, this is why we still consider it an “alpha” version.