sPyNNaker neural_modelling  7.4.2
neuron_impl_stoc_sigma.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_SIGMA_
21 #define _NEURON_IMPL_STOC_SIGMA_
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 
45 #define PROB_HALF 0x7FFFFFFF
46 
48 #define MAX_POWER REAL_CONST(5)
49 
50 #define MIN_POWER REAL_CONST(-5)
51 
53 typedef struct neuron_params_t {
54 
57 
60 
63 
65  REAL bias;
66 
68  uint32_t refract_init;
69 
71  mars_kiss64_seed_t random_seed;
73 
74 
76 typedef struct neuron_impl_t {
77 
80 
82  REAL bias;
83 
85  uint32_t t_refract;
86 
88  uint32_t refract_timer;
89 
91  mars_kiss64_seed_t random_seed;
92 
94  input_t inputs[2];
96 
99 
100 static bool neuron_impl_initialise(uint32_t n_neurons) {
101  // Allocate DTCM for neuron array
102  neuron_array = spin1_malloc(n_neurons * sizeof(neuron_impl_t));
103  if (neuron_array == NULL) {
104  log_error("Unable to allocate neuron array - Out of DTCM");
105  return false;
106  }
107 
108  return true;
109 }
110 
111 static inline uint32_t stoc_sigma_ceil_accum(UREAL value) {
112  uint32_t bits = bitsuk(value);
113  uint32_t integer = bits >> 16;
114  uint32_t fraction = bits & 0xFFFF;
115  if (fraction > 0) {
116  return integer + 1;
117  }
118  return integer;
119 }
120 
121 static inline void neuron_model_initialise(
123  UREAL ts = params->time_step;
124  state->alpha = params->alpha;
125  state->bias = params->bias;
126  state->t_refract = stoc_sigma_ceil_accum(ukdivuk(params->tau_refract, ts));
127  state->refract_timer = params->refract_init;
128  spin1_memcpy(state->random_seed, params->random_seed, sizeof(mars_kiss64_seed_t));
129  validate_mars_kiss64_seed(state->random_seed);
130  log_info("%u %u %u %u", state->random_seed[0], state->random_seed[1],
131  state->random_seed[2], state->random_seed[3]);
132  state->inputs[0] = ZERO;
133  state->inputs[1] = ZERO;
134 }
135 
136 static inline void neuron_model_save_state(neuron_impl_t *state, neuron_params_t *params) {
137  params->refract_init = state->refract_timer;
138  spin1_memcpy(params->random_seed, state->random_seed, sizeof(mars_kiss64_seed_t));
139 }
140 
141 static void neuron_impl_load_neuron_parameters(
142  address_t address, uint32_t next, uint32_t n_neurons,
143  address_t save_initial_state) {
144 
145  neuron_params_t *params = (neuron_params_t *) &address[next];
146  for (uint32_t i = 0; i < n_neurons; i++) {
148  }
149 
150  // If we are to save the initial state, copy the whole of the parameters
151  // to the initial state
152  if (save_initial_state) {
153  spin1_memcpy(save_initial_state, address,
154  n_neurons * sizeof(neuron_params_t));
155  }
156 }
157 
158 static void neuron_impl_store_neuron_parameters(
159  address_t address, uint32_t next, uint32_t n_neurons) {
160  neuron_params_t *params = (neuron_params_t *) &address[next];
161  for (uint32_t i = 0; i < n_neurons; i++) {
163  }
164 }
165 
166 static void neuron_impl_add_inputs(
167  index_t synapse_type_index, index_t neuron_index,
168  input_t weights_this_timestep) {
169  // Get the neuron itself
170  neuron_impl_t *neuron = &neuron_array[neuron_index];
171 
172  // Do something to store the inputs for the next state update
173  neuron->inputs[synapse_type_index] += weights_this_timestep;
174 }
175 
176 static inline void do_refrac_update(uint32_t timer_count, uint32_t time,
177  uint32_t neuron_index, neuron_impl_t *neuron) {
178  neuron->refract_timer -= 1;
179 
180  // Record things
181  neuron_recording_record_int32(PROB_INDEX, neuron_index, 0);
182  neuron_recording_record_accum(V_RECORDING_INDEX, neuron_index, ZERO);
183  neuron_recording_record_accum(EX_INPUT_INDEX, neuron_index, neuron->inputs[0]);
184  neuron_recording_record_accum(IN_INPUT_INDEX, neuron_index, neuron->inputs[1]);
185 
186  // Reset the inputs
187  neuron->inputs[0] = ZERO;
188  neuron->inputs[1] = ZERO;
189 
190  // Send a spike
192  send_spike(timer_count, time, neuron_index);
193 }
194 
195 static inline void do_non_refrac_update(uint32_t timer_count, uint32_t time,
196  uint32_t neuron_index, neuron_impl_t *neuron) {
197  // Work out the membrane voltage
198  REAL v_membrane = (neuron->inputs[0] - neuron->inputs[1]) - neuron->bias;
199 
200  // Record things
201  neuron_recording_record_accum(V_RECORDING_INDEX, neuron_index, v_membrane);
202  neuron_recording_record_accum(EX_INPUT_INDEX, neuron_index, neuron->inputs[0]);
203  neuron_recording_record_accum(IN_INPUT_INDEX, neuron_index, neuron->inputs[1]);
204 
205  // Reset the inputs
206  neuron->inputs[0] = ZERO;
207  neuron->inputs[1] = ZERO;
208 
209  // Work out the probability of spiking
210  REAL power = v_membrane * neuron->alpha;
211  REAL next_power = (REAL) pow_of_2(power * REAL_CONST(-1));
212  UREAL val = pow_of_2(next_power * REAL_CONST(-1));
213  uint32_t prob = muliuk(0xFFFFFFFF, val);
214 
215  // Record the probability
216  neuron_recording_record_int32(PROB_INDEX, neuron_index, (int32_t) prob);
217 
218  // Get a random number
219  uint32_t random = mars_kiss64_seed(neuron->random_seed);
220 
221  // If the random number is less than the probability value, spike
222  if (random < prob) {
223  neuron->refract_timer = neuron->t_refract - 1;
225  send_spike(timer_count, time, neuron_index);
226  }
227 }
228 
229 static void neuron_impl_do_timestep_update(
230  uint32_t timer_count, uint32_t time, uint32_t n_neurons) {
231  for (uint32_t neuron_index = 0; neuron_index < n_neurons; neuron_index++) {
232  // Get the neuron itself
233  neuron_impl_t *neuron = &neuron_array[neuron_index];
234 
235  // If in refractory, count down and spike!
236  if (neuron->refract_timer > 0) {
237  do_refrac_update(timer_count, time, neuron_index, neuron);
238  } else {
239  do_non_refrac_update(timer_count, time, neuron_index, neuron);
240  }
241 
242 
243  }
244 }
245 
246 #if LOG_LEVEL >= LOG_DEBUG
247 static void neuron_impl_print_inputs(uint32_t n_neurons) {
248  log_debug("-------------------------------------\n");
249  for (index_t i = 0; i < n_neurons; i++) {
250  neuron_impl_t *neuron = &neuron_array[i];
251  log_debug("inputs: %k %k", neuron->inputs[0], neuron->inputs[1]);
252  }
253  log_debug("-------------------------------------\n");
254 }
255 
256 static void neuron_impl_print_synapse_parameters(uint32_t n_neurons) {
257  // there aren't any accessible
258  use(n_neurons);
259 }
260 
261 static const char *neuron_impl_get_synapse_type_char(uint32_t synapse_type) {
262  if (synapse_type == 0) {
263  return 'E';
264  } else if (synapse_type == 1) {
265  return 'I';
266  }
267  return 'U';
268 }
269 #endif // LOG_LEVEL >= LOG_DEBUG
270 
271 
272 #endif // _NEURON_IMPL_STOC_EXP_
General API of a current source implementation.
Implement all current sources.
static uint32_t time
Simulation time.
maths-util.h - first created 7/10/2013 version 0.1
static UREAL pow_of_2(REAL p)
Calculates 2^p where p is a real number (rather than just an integer). This is still quicker than gen...
Definition: maths-util.h:283
#define REAL_CONST(x)
Define a constant of type REAL.
Definition: maths-util.h:104
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.
void neuron_impl_print_inputs(uint32_t n_neurons)
Print the inputs to the neurons.
const char * neuron_impl_get_synapse_type_char(uint32_t synapse_type)
Get the synapse type character for a synapse type.
@ SPIKE_RECORDING_BITFIELD
Spike event recording index.
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 bias
The bias value.
uint32_t refract_timer
The refractory timer.
REAL alpha
The alpha value of the neuron prob = (2^(-2^(alpha x voltage)))
definition of neuron state
static void neuron_model_initialise(neuron_t *state, neuron_params_t *params, uint32_t n_steps_per_timestep)
initialise the structure from the parameters
static void neuron_model_save_state(neuron_t *state, neuron_params_t *params)
save parameters and state back to SDRAM for reading by host and recovery on restart
REAL alpha
The alpha value of the neuron prob = (2^(-2^(alpha x voltage)))
REAL bias
The bias value.
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.
uint32_t refract_init
The initial refractory timer.
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...
static stdp_params params
Configuration parameters.