Custom OCL neuron; 'SimNeurons' object has no attribute 'state'

Hi all,

I’ve followed the steps to add a custom neuron model (callled CA1LIF, just a LIF neuron but with a variable resting potential) as described in this thread Parameter space exploration, nengo_ocl and SpiNNaker - #10 by xchoo

However when running the model I get a warning stating AttributeError: 'SimNeurons' object has no attribute 'state' . The warning is thrown (is this the correct term?) from the custom ocl simulator from inside the _plan_CA1LIF function that looks like this:

    def _plan_CA1LIF(self, ops):
        if not all(op.neurons.min_voltage == 0 for op in ops):
            raise NotImplementedError("LIF min voltage")
        dt = self.model.dt
        J = self.all_data[[self.sidx[op.J] for op in ops]]
        V = self.all_data[[self.sidx[op.state["voltage"]] for op in ops]] # <- HERE IS THE ISSUE
        W = self.all_data[[self.sidx[op.state["refractory_time"]] for op in ops]]
        S = self.all_data[[self.sidx[op.output] for op in ops]]
        ref = self.RaggedArray(
            [op.neurons.tau_ref * np.ones(op.J.size) for op in ops], dtype=J.dtype
        )
        tau = self.RaggedArray(
            [op.neurons.tau_rc * np.ones(op.J.size) for op in ops], dtype=J.dtype
        )
        amp = self.RaggedArray(
            [op.neurons.amplitude * np.ones(op.J.size) for op in ops], dtype=J.dtype
        )
        rest = self.RaggedArray(
            [op.neurons.rest_voltage * np.ones(op.J.size) for op in ops], dtype=J.dtype
        )
        return [plan_ca1lif(self.queue, dt, J, V, W, S, ref, tau, amp, rest)]

With only a minor change, this code is just an exact copy of how the LIF neuron is added to ocl. Does anyone see why this error could occur? I have added the neuron type to the builder as well like this and i can just this neuron type just fine using regular nengo (2.8.0), instead of OCL:

@Builder.register(CA1LIF)
def build_ca1lif(model, ca1lif, neurons):
    """Builds a `.CA1LIF` object into a model.

    In addition to adding a `.SimNeurons` operator, this build function sets up
    signals to track the voltage and refractory times for each neuron.

    Parameters
    ----------
    model : Model
        The model to build into.
    ca1lif : CA1LIF
        Neuron type to build.
    neuron : Neurons
        The neuron population object corresponding to the neuron type.

    Notes
    -----
    Does not modify ``model.params[]`` and can therefore be called
    more than once with the same `.LIF` instance.
    """

    model.sig[neurons]['voltage'] = Signal(
        np.zeros(neurons.size_in), name="%s.voltage" % neurons)
    model.sig[neurons]['refractory_time'] = Signal(
        np.zeros(neurons.size_in), name="%s.refractory_time" % neurons)
    model.add_op(SimNeurons(
        neurons=ca1lif,
        J=model.sig[neurons]['in'],
        output=model.sig[neurons]['out'],
        states=[model.sig[neurons]['voltage'],
                model.sig[neurons]['refractory_time']]))

The .state attribute is a new way of tracking neuron state that we introduced in Nengo 3.1. You’ll have to make sure that the Nengo and NengoOCL versions you’re using are compatible with one another, and that both your new _plan_CA1LIF function and build_ca1lif functions are compatible with the underlying Nengo version.

The best practice would be to use the latest version of NengoOCL (2.1.0), and the version of Nengo that it is compatible with (3.1.0). However, if you have a constraint that requires you to use an older Nengo or NengoOCL version, just make sure the two are compatible by checking the NengoOCL releases page.

1 Like