sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
neuron_impl_standard.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 The University of Manchester
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
19#ifndef _NEURON_IMPL_STANDARD_H_
20#define _NEURON_IMPL_STANDARD_H_
21
22#include "neuron_impl.h"
23
24// Includes for model parts used in this implementation
30
32
33// Further includes
34#include <debug.h>
35#include <bit_field.h>
36#include <recording.h>
37
49
57
58// This import depends on variables defined above
60
63
66
69
72
75
78
79SOMETIMES_UNUSED // Marked unused as only used sometimes
83static bool neuron_impl_initialise(uint32_t n_neurons) {
84
85 // Allocate DTCM for neuron array
86 if (sizeof(neuron_t)) {
87 neuron_array = spin1_malloc(n_neurons * sizeof(neuron_t));
88 if (neuron_array == NULL) {
89 log_error("Unable to allocate neuron array - Out of DTCM");
90 return false;
91 }
92 }
93
94 // Allocate DTCM for input type array and copy block of data
95 if (sizeof(input_type_t)) {
96 input_type_array = spin1_malloc(n_neurons * sizeof(input_type_t));
97 if (input_type_array == NULL) {
98 log_error("Unable to allocate input type array - Out of DTCM");
99 return false;
100 }
101 }
102
103 // Allocate DTCM for additional input array and copy block of data
104 if (sizeof(additional_input_t)) {
106 spin1_malloc(n_neurons * sizeof(additional_input_t));
108 log_error("Unable to allocate additional input array"
109 " - Out of DTCM");
110 return false;
111 }
112 }
113
114 // Allocate DTCM for threshold type array and copy block of data
115 if (sizeof(threshold_type_t)) {
117 spin1_malloc(n_neurons * sizeof(threshold_type_t));
118 if (threshold_type_array == NULL) {
119 log_error("Unable to allocate threshold type array - Out of DTCM");
120 return false;
121 }
122 }
123
124 // Allocate DTCM for synapse shaping parameters
125 if (sizeof(synapse_types_t)) {
127 spin1_malloc(n_neurons * sizeof(synapse_types_t));
128 if (synapse_types_array == NULL) {
129 log_error("Unable to allocate synapse types array - Out of DTCM");
130 return false;
131 }
132 }
133
134 return true;
135}
136
137SOMETIMES_UNUSED // Marked unused as only used sometimes
143 index_t synapse_type_index, index_t neuron_index,
144 input_t weights_this_timestep) {
145 // simple wrapper to synapse type input function
146 synapse_types_t *parameters = &synapse_types_array[neuron_index];
147 synapse_types_add_neuron_input(synapse_type_index,
148 parameters, weights_this_timestep);
149}
150
154static uint32_t n_words_needed(size_t size) {
155 return (size + (sizeof(uint32_t) - 1)) / sizeof(uint32_t);
156}
157
158SOMETIMES_UNUSED // Marked unused as only used sometimes
165 address_t address, uint32_t next, uint32_t n_neurons,
166 address_t save_initial_state) {
167
168 // Read the number of steps per timestep
169 n_steps_per_timestep = address[next++];
170 if (n_steps_per_timestep == 0) {
171 log_error("bad number of steps per timestep: 0");
173 }
174
175 if (sizeof(neuron_t)) {
176 neuron_params_t *params = (neuron_params_t *) &address[next];
177 for (uint32_t i = 0; i < n_neurons; i++) {
178 neuron_model_initialise(&neuron_array[i], &params[i],
180 }
181 next += n_words_needed(n_neurons * sizeof(neuron_params_t));
182 }
183
184 if (sizeof(input_type_t)) {
185 input_type_params_t *params = (input_type_params_t *) &address[next];
186 for (uint32_t i = 0; i < n_neurons; i++) {
189 }
191 }
192
193 if (sizeof(threshold_type_t)) {
195 for (uint32_t i = 0; i < n_neurons; i++) {
198 }
200 }
201
202 if (sizeof(synapse_types_t)) {
204 for (uint32_t i = 0; i < n_neurons; i++) {
207 }
209 }
210
211 if (sizeof(additional_input_t)) {
213 for (uint32_t i = 0; i < n_neurons; i++) {
216 }
218 }
219
220 // If we are to save the initial state, copy the whole of the parameters
221 // to the initial state
222 if (save_initial_state) {
223 spin1_memcpy(save_initial_state, address, next * sizeof(uint32_t));
224 }
225
226#if LOG_LEVEL >= LOG_DEBUG
227 for (index_t n = 0; n < n_neurons; n++) {
230 }
231#endif // LOG_LEVEL >= LOG_DEBUG
232}
233
234SOMETIMES_UNUSED // Marked unused as only used sometimes
240 uint32_t timer_count, uint32_t time, uint32_t n_neurons) {
241
242 for (uint32_t neuron_index = 0; neuron_index < n_neurons; neuron_index++) {
243
244 // Get the neuron itself
245 neuron_t *this_neuron = &neuron_array[neuron_index];
246
247 // Get the input_type parameters and voltage for this neuron
248 input_type_t *input_types = &input_type_array[neuron_index];
249
250 // Get threshold and additional input parameters for this neuron
251 threshold_type_t *the_threshold_type = &threshold_type_array[neuron_index];
252 additional_input_t *additional_inputs = &additional_input_array[neuron_index];
253 synapse_types_t *the_synapse_type = &synapse_types_array[neuron_index];
254
255 // Loop however many times requested; do this in reverse for efficiency,
256 // and because the index doesn't actually matter
257 for (uint32_t i_step = n_steps_per_timestep; i_step > 0; i_step--) {
258 // Get the voltage
259 state_t soma_voltage = neuron_model_get_membrane_voltage(this_neuron);
260
261 // Get the exc and inh values from the synapses
263 input_t *exc_syn_values =
264 synapse_types_get_excitatory_input(exc_values, the_synapse_type);
266 input_t *inh_syn_values =
267 synapse_types_get_inhibitory_input(inh_values, the_synapse_type);
268
269 // Call functions to obtain exc_input and inh_input
270 input_t *exc_input_values = input_type_get_input_value(
271 exc_syn_values, input_types, NUM_EXCITATORY_RECEPTORS);
272 input_t *inh_input_values = input_type_get_input_value(
273 inh_syn_values, input_types, NUM_INHIBITORY_RECEPTORS);
274
275 // Sum g_syn contributions from all receptors for recording
276 REAL total_exc = ZERO;
277 REAL total_inh = ZERO;
278
279 for (int i = 0; i < NUM_EXCITATORY_RECEPTORS; i++) {
280 total_exc += exc_input_values[i];
281 }
282 for (int i = 0; i < NUM_INHIBITORY_RECEPTORS; i++) {
283 total_inh += inh_input_values[i];
284 }
285
286 // Do recording if on the first step
287 if (i_step == n_steps_per_timestep) {
289 V_RECORDING_INDEX, neuron_index, soma_voltage);
291 GSYN_EXC_RECORDING_INDEX, neuron_index, total_exc);
293 GSYN_INH_RECORDING_INDEX, neuron_index, total_inh);
294 }
295
296 // Call functions to convert exc_input and inh_input to current
298 exc_input_values, input_types, soma_voltage);
300 inh_input_values, input_types, soma_voltage);
301
302 // Get any input from an injected current source
303 REAL current_offset = current_source_get_offset(time, neuron_index);
304
305 // Get any external bias input
307 additional_inputs, soma_voltage);
308
309 // update neuron parameters
311 NUM_EXCITATORY_RECEPTORS, exc_input_values,
312 NUM_INHIBITORY_RECEPTORS, inh_input_values,
313 external_bias, current_offset, this_neuron);
314
315 // determine if a spike should occur
316 bool spike_now =
317 threshold_type_is_above_threshold(result, the_threshold_type);
318
319 // If spike occurs, communicate to relevant parts of model
320 if (spike_now) {
321
322 // Call relevant model-based functions
323 // Tell the neuron model
324 neuron_model_has_spiked(this_neuron);
325
326 // Tell the additional input
327 additional_input_has_spiked(additional_inputs);
328
329 // Record the spike
331
332 // Send the spike
333 send_spike(timer_count, time, neuron_index);
334 }
335
336 // Shape the existing input according to the included rule
337 synapse_types_shape_input(the_synapse_type);
338 }
339
340 #if LOG_LEVEL >= LOG_DEBUG
342 #endif // LOG_LEVEL >= LOG_DEBUG
343 }
344}
345
346SOMETIMES_UNUSED // Marked unused as only used sometimes
352 address_t address, uint32_t next, uint32_t n_neurons) {
353
354 // Skip over the steps per timestep
355 next += 1;
356
357 if (sizeof(neuron_t)) {
358 neuron_params_t *params = (neuron_params_t *) &address[next];
359 for (uint32_t i = 0; i < n_neurons; i++) {
360 neuron_model_save_state(&neuron_array[i], &params[i]);
361 }
362 next += n_words_needed(n_neurons * sizeof(neuron_params_t));
363 }
364
365 if (sizeof(input_type_t)) {
366 input_type_params_t *params = (input_type_params_t *) &address[next];
367 for (uint32_t i = 0; i < n_neurons; i++) {
369 }
371 }
372
373 if (sizeof(threshold_type_t)) {
375 for (uint32_t i = 0; i < n_neurons; i++) {
377 }
379 }
380
381 if (sizeof(synapse_types_t)) {
383 for (uint32_t i = 0; i < n_neurons; i++) {
385 }
387 }
388
389 if (sizeof(additional_input_t)) {
391 for (uint32_t i = 0; i < n_neurons; i++) {
393 }
395 }
396}
397
398#if LOG_LEVEL >= LOG_DEBUG
399SOMETIMES_UNUSED // Marked unused as only used sometimes
403 bool empty = true;
404 for (index_t i = 0; i < n_neurons; i++) {
408 empty = empty && (0 == bitsk(
410 - synapse_types_get_inhibitory_input(inh_values, params)[0]));
411 }
412
413 if (!empty) {
414 for (index_t i = 0; i < n_neurons; i++) {
418 input_t *exc_input = synapse_types_get_excitatory_input(exc_values, params);
419 input_t *inh_input = synapse_types_get_inhibitory_input(inh_values, params);
420 input_t input = exc_input[0] - inh_input[0];
421 if (bitsk(input) != 0) {
422 log_debug("Neuron %3u: input %12.6k (= ", i, input);
424 log_debug(")");
425 }
426 }
427 }
428}
429
430SOMETIMES_UNUSED // Marked unused as only used sometimes
438
439SOMETIMES_UNUSED // Marked unused as only used sometimes
443const char *neuron_impl_get_synapse_type_char(uint32_t synapse_type) {
444 return synapse_types_get_type_char(synapse_type);
445}
446#endif // LOG_LEVEL >= LOG_DEBUG
447
448#endif // _NEURON_IMPL_STANDARD_H_
API for additional inputs.
static input_t additional_input_get_input_value_as_current(struct additional_input_t *additional_input, state_t membrane_voltage)
Gets the value of current provided by the additional input this timestep.
static void additional_input_initialise(additional_input_t *state, additional_input_params_t *params, uint32_t n_steps_per_timestep)
initialise the structure from the parameters
static void additional_input_save_state(additional_input_t *state, additional_input_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
static void additional_input_has_spiked(struct additional_input_t *additional_input)
Notifies the additional input type that the neuron has spiked.
The additional input is due to calcium ions.
The additional input is due to calcium ions.
uint32_t index_t
uint32_t time
The current timer tick value.
Definition c_main.c:94
uint32_t * address_t
General API of a current source implementation.
static REAL current_source_get_offset(uint32_t time, uint32_t neuron_index)
Calculate the current offset from all injected current sources.
void log_error(const char *message,...)
void log_debug(const char *message,...)
API for synaptic inputs (see also src/neuron/synapse_types)
static void input_type_convert_inhibitory_input_to_current(input_t *restrict inh_input, const input_type_t *input_type, state_t membrane_voltage)
Converts an inhibitory input into an inhibitory current.
static void input_type_initialise(input_type_t *state, input_type_params_t *params, uint32_t n_steps_per_timestep)
initialise the structure from the parameters
#define NUM_INHIBITORY_RECEPTORS
The number of inhibitory receptors.
Definition input_type.h:37
static input_t * input_type_get_input_value(input_t *restrict value, input_type_t *input_type, uint16_t num_receptors)
Gets the actual input value. This allows any scaling to take place.
#define NUM_EXCITATORY_RECEPTORS
The number of excitatory receptors.
Definition input_type.h:28
static void input_type_save_state(input_type_t *state, input_type_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
static void input_type_convert_excitatory_input_to_current(input_t *restrict exc_input, const input_type_t *input_type, state_t membrane_voltage)
Converts an excitatory input into an excitatory current.
Conductance input parameters.
Conductance state.
accum REAL
Type used for "real" numbers.
Definition maths-util.h:91
#define ZERO
A REAL 0.0.
Definition maths-util.h:123
REAL state_t
The type of a state variable.
REAL input_t
The type of an input.
static uint32_t n_neurons
The number of neurons on the core.
Definition neuron.c:45
General API of a neuron implementation.
bitfield_recording_indices
Indices for recording of bitfields.
word_recording_indices
Indices for recording of words.
@ SPIKE_RECORDING_BITFIELD
Spike event recording index.
@ N_BITFIELD_VARS
Number of recorded bitfields.
void neuron_impl_print_synapse_parameters(uint32_t n_neurons)
Print the synapse parameters of the neurons.
static neuron_t * neuron_array
Array of neuron states.
static input_type_t * input_type_array
Input states array.
const char * neuron_impl_get_synapse_type_char(uint32_t synapse_type)
Get the synapse type character for a synapse type.
static threshold_type_t * threshold_type_array
Threshold states array.
static void neuron_impl_do_timestep_update(uint32_t timer_count, uint32_t time, uint32_t n_neurons)
Do the timestep update for the particular implementation.
static void neuron_impl_load_neuron_parameters(address_t address, uint32_t next, uint32_t n_neurons, address_t save_initial_state)
Load in the neuron parameters.
@ GSYN_INH_RECORDING_INDEX
Gsyn_inh (excitatory synaptic conductance/current) recording index.
@ GSYN_EXC_RECORDING_INDEX
Gsyn_exc (excitatory synaptic conductance/current) recording index.
@ N_RECORDED_VARS
Number of recorded word-sized state variables.
@ V_RECORDING_INDEX
V (somatic potential) recording index.
static uint32_t n_words_needed(size_t size)
The number of words required to hold an object of given size.
static void neuron_impl_add_inputs(index_t synapse_type_index, index_t neuron_index, input_t weights_this_timestep)
Add inputs to the neuron.
static additional_input_t * additional_input_array
Additional input array.
void neuron_impl_print_inputs(uint32_t n_neurons)
Print the inputs to the neurons.
static bool neuron_impl_initialise(uint32_t n_neurons)
Initialise the particular implementation of the data.
static uint n_steps_per_timestep
The number of steps to run per timestep.
static synapse_types_t * synapse_types_array
The synapse shaping parameters.
static void neuron_impl_store_neuron_parameters(address_t address, uint32_t next, uint32_t n_neurons)
Stores neuron parameters back into SDRAM.
The API for neuron models themselves.
static void neuron_model_print_state_variables(const neuron_t *neuron)
printout of state variables i.e. those values that might change
static state_t neuron_model_get_membrane_voltage(const neuron_t *neuron)
get the neuron membrane voltage for a given neuron parameter set
static state_t neuron_model_state_update(uint16_t num_excitatory_inputs, const input_t *exc_input, uint16_t num_inhibitory_inputs, const input_t *inh_input, input_t external_bias, REAL current_offset, neuron_t *restrict neuron)
primary function called in timer loop after synaptic updates
static void neuron_model_has_spiked(neuron_t *restrict neuron)
Indicates that the neuron has spiked.
static void neuron_model_print_parameters(const neuron_t *neuron)
printout of parameters i.e. those values that don't change
definition of neuron parameters
definition for LIF neuron state
Recording of the state of a neuron (spiking, voltage, etc.)
static void neuron_recording_record_accum(uint32_t var_index, uint32_t neuron_index, accum value)
stores a recording of an accum variable only; this is faster than neuron_recording_record_value for t...
static void neuron_recording_record_bit(uint32_t var_index, uint32_t neuron_index)
stores a recording of a set bit; this is the only way to set a bit in a bitfield; neuron_recording_re...
RTE_SWERR
void rt_error(uint code,...)
#define NULL
void spin1_memcpy(void *dst, void const *src, uint len)
unsigned int uint
static stdp_params params
Configuration parameters.
API for synaptic behaviour types (see also src/neuron/input_types)
static void synapse_types_save_state(synapse_types_t *state, synapse_types_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
static const char * synapse_types_get_type_char(index_t synapse_type_index)
returns a human readable character for the type of synapse.
static input_t * synapse_types_get_excitatory_input(input_t *excitatory_response, synapse_types_t *parameters)
extracts the excitatory input buffers from the buffers available for a given neuron ID
static void synapse_types_initialise(synapse_types_t *state, synapse_types_params_t *params, uint32_t n_steps_per_time_step)
initialise the structure from the parameters
static void synapse_types_add_neuron_input(index_t synapse_type_index, synapse_types_t *parameters, input_t input)
adds the inputs for a give timer period to a given neuron that is being simulated by this model
static void synapse_types_print_input(synapse_types_t *parameters)
prints the input for a neuron ID given the available inputs currently only executed when the models a...
static void synapse_types_print_parameters(synapse_types_t *parameters)
prints the parameters of the synapse type
static void synapse_types_shape_input(synapse_types_t *parameters)
decays the stuff thats sitting in the input buffers as these have not yet been processed and applied ...
static input_t * synapse_types_get_inhibitory_input(input_t *inhibitory_response, synapse_types_t *parameters)
extracts the inhibitory input buffers from the buffers available for a given neuron ID
Delta synapses support just a single excitatory and inhibitory input each.
API for threshold types.
static void threshold_type_initialise(threshold_type_t *state, threshold_type_params_t *params, uint32_t n_steps_per_timestep)
initialise the state from the parameters
static void threshold_type_save_state(threshold_type_t *state, threshold_type_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
static bool threshold_type_is_above_threshold(state_t value, threshold_type_t *threshold_type)
Determines if the value given is above the threshold value.
Stochastic threshold parameters.
Stochastic threshold configuration.