sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
neuron_impl_stoc_exp_stable.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 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
20#ifndef _NEURON_IMPL_STOC_EXP_
21#define _NEURON_IMPL_STOC_EXP_
22
24#include <spin1_api.h>
25#include <debug.h>
26#include <random.h>
27#include <stdfix-full-iso.h>
28#include <common/maths-util.h>
29
30#define V_RECORDING_INDEX 0
31#define EX_INPUT_INDEX 1
32#define IN_INPUT_INDEX 2
33#define PROB_INDEX 3
34#define N_RECORDED_VARS 4
35
36#define SPIKE_RECORDING_BITFIELD 0
37#define N_BITFIELD_VARS 1
38
40
43
44#include "stoc_exp_common.h"
45
47typedef struct neuron_params_t {
48
51
54
57
60
63
65 REAL bias;
66
68 uint32_t refract_init;
69
73
74
76typedef struct neuron_impl_t {
77
80
83
86
88 REAL bias;
89
91 uint32_t t_refract;
92
94 uint32_t refract_timer;
95
98
100 input_t inputs[2];
102
105
106static bool neuron_impl_initialise(uint32_t n_neurons) {
107 // Allocate DTCM for neuron array
108 neuron_array = spin1_malloc(n_neurons * sizeof(neuron_impl_t));
109 if (neuron_array == NULL) {
110 log_error("Unable to allocate neuron array - Out of DTCM");
111 return false;
112 }
113
114 return true;
115}
116
117static inline void neuron_model_initialise(
119 state->v_membrane = params->v_init;
120 state->v_reset = params->v_reset;
121 UREAL ts = params->time_step;
122 state->tau = params->tau;
123 state->bias = params->bias;
124 state->t_refract = stoc_exp_ceil_accum(ukdivuk(params->tau_refract, ts));
125 state->refract_timer = params->refract_init;
126 spin1_memcpy(state->random_seed, params->random_seed, sizeof(mars_kiss64_seed_t));
128
129 // Reset the inputs
130 state->inputs[0] = ZERO;
131 state->inputs[1] = ZERO;
132}
133
134static inline void neuron_model_save_state(neuron_impl_t *state, neuron_params_t *params) {
135 params->v_init = state->v_membrane;
136 params->refract_init = state->refract_timer;
137 spin1_memcpy(params->random_seed, state->random_seed, sizeof(mars_kiss64_seed_t));
138}
139
140static void neuron_impl_load_neuron_parameters(
141 address_t address, uint32_t next, uint32_t n_neurons,
142 address_t save_initial_state) {
143
144 neuron_params_t *params = (neuron_params_t *) &address[next];
145 for (uint32_t i = 0; i < n_neurons; i++) {
146 neuron_model_initialise(&neuron_array[i], &params[i]);
147 }
148
149 // If we are to save the initial state, copy the whole of the parameters
150 // to the initial state
151 if (save_initial_state) {
152 spin1_memcpy(save_initial_state, address,
153 n_neurons * sizeof(neuron_params_t));
154 }
155}
156
157static void neuron_impl_store_neuron_parameters(
158 address_t address, uint32_t next, uint32_t n_neurons) {
159 neuron_params_t *params = (neuron_params_t *) &address[next];
160 for (uint32_t i = 0; i < n_neurons; i++) {
161 neuron_model_save_state(&neuron_array[i], &params[i]);
162 }
163}
164
165static void neuron_impl_add_inputs(
166 index_t synapse_type_index, index_t neuron_index,
167 input_t weights_this_timestep) {
168 // Get the neuron itself
169 neuron_impl_t *neuron = &neuron_array[neuron_index];
170
171 // Do something to store the inputs for the next state update
172 neuron->inputs[synapse_type_index] += weights_this_timestep;
173}
174
175static inline void do_refrac_update(uint32_t timer_count, uint32_t time,
176 uint32_t neuron_index, neuron_impl_t *neuron) {
177 neuron->refract_timer -= 1;
178
179 // Record things
180 neuron_recording_record_int32(PROB_INDEX, neuron_index, 0);
181 neuron_recording_record_accum(V_RECORDING_INDEX, neuron_index, neuron->v_membrane);
182 neuron_recording_record_accum(EX_INPUT_INDEX, neuron_index, neuron->inputs[0]);
183 neuron_recording_record_accum(IN_INPUT_INDEX, neuron_index, neuron->inputs[1]);
184
185 // Reset the inputs
186 neuron->inputs[0] = ZERO;
187 neuron->inputs[1] = ZERO;
188
189 // Send a spike
190 neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index);
191 send_spike(timer_count, time, neuron_index);
192}
193
194static inline void do_non_refrac_update(uint32_t timer_count, uint32_t time,
195 uint32_t neuron_index, neuron_impl_t *neuron) {
196 // Work out the membrane voltage
197 neuron->v_membrane += (neuron->bias + neuron->inputs[0]) - neuron->inputs[1];
198
199 // Record things
200 neuron_recording_record_accum(V_RECORDING_INDEX, neuron_index, neuron->v_membrane);
201 neuron_recording_record_accum(EX_INPUT_INDEX, neuron_index, neuron->inputs[0]);
202 neuron_recording_record_accum(IN_INPUT_INDEX, neuron_index, neuron->inputs[1]);
203
204 // Reset the inputs
205 neuron->inputs[0] = ZERO;
206 neuron->inputs[1] = ZERO;
207
208 // Work out the probability
209 uint32_t prob = get_probability(neuron->tau, neuron->v_membrane);
210
211 // Record the probability
212 neuron_recording_record_int32(PROB_INDEX, neuron_index, (int32_t) prob);
213
214 // Get a random number
215 uint32_t random = mars_kiss64_seed(neuron->random_seed);
216
217 // If the random number is less than the probability value, spike
218 if (random < prob) {
219 neuron->v_membrane = neuron->v_reset;
220 neuron->refract_timer = neuron->t_refract - 1;
221 neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index);
222 send_spike(timer_count, time, neuron_index);
223 }
224
225 if (neuron->v_membrane < neuron->v_reset) {
226 neuron->v_membrane = neuron->v_reset;
227 }
228}
229
230static void neuron_impl_do_timestep_update(
231 uint32_t timer_count, uint32_t time, uint32_t n_neurons) {
232 for (uint32_t neuron_index = 0; neuron_index < n_neurons; neuron_index++) {
233 // Get the neuron itself
234 neuron_impl_t *neuron = &neuron_array[neuron_index];
235
236 // If in refractory, count down and spike!
237 if (neuron->refract_timer > 0) {
238 do_refrac_update(timer_count, time, neuron_index, neuron);
239 } else {
240 do_non_refrac_update(timer_count, time, neuron_index, neuron);
241 }
242
243
244 }
245}
246
247#if LOG_LEVEL >= LOG_DEBUG
248static void neuron_impl_print_inputs(uint32_t n_neurons) {
249 log_debug("-------------------------------------\n");
250 for (index_t i = 0; i < n_neurons; i++) {
251 neuron_impl_t *neuron = &neuron_array[i];
252 log_debug("inputs: %k %k", neuron->inputs[0], neuron->inputs[1]);
253 }
254 log_debug("-------------------------------------\n");
255}
256
258 // there aren't any accessible
259 use(n_neurons);
260}
261
262static const char *neuron_impl_get_synapse_type_char(uint32_t synapse_type) {
263 if (synapse_type == 0) {
264 return 'E';
265 } else if (synapse_type == 1) {
266 return 'I';
267 }
268 return 'U';
269}
270#endif // LOG_LEVEL >= LOG_DEBUG
271
272
273#endif // _NEURON_IMPL_STOC_EXP_
uint32_t index_t
#define use(x)
uint32_t * address_t
General API of a current source implementation.
Implement all current sources.
void log_error(const char *message,...)
void log_debug(const char *message,...)
maths-util.h - first created 7/10/2013 version 0.1
unsigned accum UREAL
Type used for "unsigned real" numbers.
Definition maths-util.h:94
accum REAL
Type used for "real" numbers.
Definition maths-util.h:91
static UREAL ukdivuk(UREAL a, UREAL b)
Divides an unsigned accum by another unsigned accum.
Definition maths-util.h:242
#define ZERO
A REAL 0.0.
Definition maths-util.h:123
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.
void neuron_impl_print_synapse_parameters(uint32_t n_neurons)
Print the synapse parameters of the neurons.
const char * neuron_impl_get_synapse_type_char(uint32_t synapse_type)
Get the synapse type character for a synapse type.
void neuron_impl_print_inputs(uint32_t n_neurons)
Print the inputs to the neurons.
static neuron_impl_t * neuron_array
Array of neuron states.
uint32_t t_refract
The refractory timer countdown value.
input_t inputs[2]
The inputs to add in the next timestep.
mars_kiss64_seed_t random_seed
The random state.
REAL v_reset
The reset voltage after a spike.
UREAL tau
The tau value of the neuron.
REAL v_membrane
The membrane voltage.
REAL bias
The bias value.
uint32_t refract_timer
The refractory timer.
definition of neuron state
REAL bias
The bias value.
UREAL tau
The tau value of the neuron, multiplied by 2^v to get probability.
mars_kiss64_seed_t random_seed
Random seed to use.
UREAL tau_refract
The refractory period of the neuron in milliseconds.
UREAL time_step
The timestep of the neuron being used.
REAL v_init
The initial membrane voltage.
uint32_t refract_init
The initial refractory timer.
REAL v_reset
The reset membrane voltage after a spike.
definition of neuron parameters
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...
static void neuron_recording_record_int32(uint32_t var_index, uint32_t neuron_index, int32_t value)
stores a recording of an int32_t variable only; this is faster than neuron_recording_record_value for...
uint32_t mars_kiss64_seed(mars_kiss64_seed_t seed)
uint32_t mars_kiss64_seed_t[4]
void validate_mars_kiss64_seed(mars_kiss64_seed_t seed)
#define random
#define NULL
void spin1_memcpy(void *dst, void const *src, uint len)
Stochastic common code.
static uint32_t get_probability(UREAL tau, REAL p)
Calculates the probability as a uint32_t from 0 to 0xFFFFFFFF (which is 1)
static stdp_params params
Configuration parameters.