sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
current_source.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
21#ifndef _CURRENT_SOURCE_H_
22#define _CURRENT_SOURCE_H_
23
25
26// Struct for current source id type and current source index of that type
27typedef struct cs_id_index_t {
28 uint32_t cs_id;
29 uint32_t cs_index;
31
32// Global struct for each neuron's current source IDs and indices
34 uint32_t n_current_sources; // the number of current sources for this neuron
35 cs_id_index_t cs_id_index_list[]; // the list of CS type ID and index in that type
37
38// Global values for the total number of current sources and number of each type
39static uint32_t n_current_sources;
40static uint32_t n_dc_sources;
41static uint32_t n_ac_sources;
42static uint32_t n_step_sources;
43static uint32_t n_noisy_sources;
44
45static uint32_t n_neurons_on_core;
46
47static neuron_current_source_t **neuron_current_source;
48
49#ifndef SOMETIMES_UNUSED
50#define SOMETIMES_UNUSED __attribute__((unused))
51#endif // !SOMETIMES_UNUSED
52
53SOMETIMES_UNUSED // Marked unused as only used sometimes
58static bool current_source_initialise(address_t cs_address, uint32_t n_neurons) {
59 // Avoid the loops if no current sources
60 #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \
61 !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_)
62 return true;
63 #else
64
65 n_neurons_on_core = n_neurons;
66
67 // Read from cs_address; the first value is the number of current sources
68 n_current_sources = cs_address[0];
69
70 // Don't initialise if no current sources
71 if (n_current_sources != 0) {
72
73 neuron_current_source = spin1_malloc(n_neurons * sizeof(uint32_t*));
74
75 // Loop over neurons and read in the current IDs and indices
76 uint32_t next = 1;
77 for (uint32_t n=0; n < n_neurons; n++) {
78 uint32_t n_sources = (uint32_t) cs_address[next];
79 uint32_t struct_size = (1 + (2 * n_sources)) * sizeof(uint32_t);
80 neuron_current_source[n] = spin1_malloc(struct_size);
81 spin1_memcpy(neuron_current_source[n], &cs_address[next], struct_size);
82
83 next += 1 + (n_sources * 2);
84
85 }
86
87 // Read number of each type of current source
88 n_dc_sources = (uint32_t) cs_address[next++];
89 n_ac_sources = (uint32_t) cs_address[next++];
90 n_step_sources = (uint32_t) cs_address[next++];
91 n_noisy_sources = (uint32_t) cs_address[next++];
92
93 // Now initialise separate sources
94#ifdef _CURRENT_SOURCE_DC_H_
95 if (!current_source_dc_init(n_dc_sources, &next)) {
96 return false;
97 }
98#else
99 if (n_dc_sources > 0) {
100 log_error("DC current source is not supported for this build");
101 return false;
102 }
103#endif
104
105#ifdef _CURRENT_SOURCE_AC_H_
106 if (!current_source_ac_init(n_ac_sources, &next)) {
107 return false;
108 }
109#else
110 if (n_ac_sources > 0) {
111 log_error("AC current source is not supported for this build");
112 return false;
113 }
114#endif
115
116#ifdef _CURRENT_SOURCE_STEP_H_
117 if (!current_source_step_init(cs_address, n_step_sources, &next)) {
118 return false;
119 }
120#else
121 if (n_step_sources > 0) {
122 log_error("Step current source is not supported for this build");
123 return false;
124 }
125#endif
126
127#ifdef _CURRENT_SOURCE_NOISY_H_
128 if (!current_source_noisy_init(n_noisy_sources, &next)) {
129 return false;
130 }
131#else
132 if (n_noisy_sources > 0) {
133 log_error("Noisy current source is not supported for this build");
134 return false;
135 }
136#endif
137
138 }
139
140 return true;
141
142 #endif
143}
144
145SOMETIMES_UNUSED // Marked unused as only used sometimes
150 // Avoid the loops if no current sources
151 #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \
152 !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_)
153 io_printf(IO_BUF, "no current sources defined \n");
154 return true;
155 #else
156
157 // Read the number of current sources
158 n_current_sources = cs_address[0];
159
160 // Don't load if no current sources
161 if (n_current_sources != 0) {
162 uint32_t next = 1;
163
164 // Copy data into neuron_current_source array
165 for (uint32_t n=0; n < n_neurons_on_core; n++) {
166 uint32_t n_sources = (uint32_t) cs_address[next];
167 uint32_t struct_size = (1 + (2 * n_sources)) * sizeof(uint32_t);
168 neuron_current_source[n] = spin1_malloc(struct_size);
169 spin1_memcpy(neuron_current_source[n], &cs_address[next], struct_size);
170
171 next += 1 + (n_sources * 2);
172 }
173
174 // Read number of each type of current source
175 n_dc_sources = (uint32_t) cs_address[next++];
176 n_ac_sources = (uint32_t) cs_address[next++];
177 n_step_sources = (uint32_t) cs_address[next++];
178 n_noisy_sources = (uint32_t) cs_address[next++];
179
180 // Copy into individual source arrays
181#ifdef _CURRENT_SOURCE_DC_H_
182 current_source_dc_load_parameters(cs_address, n_dc_sources, &next);
183#endif
184#ifdef _CURRENT_SOURCE_AC_H_
185 current_source_ac_load_parameters(cs_address, n_ac_sources, &next);
186#endif
187#ifdef _CURRENT_SOURCE_STEP_H_
188 current_source_step_load_parameters(cs_address, n_step_sources, &next);
189#endif
190#ifdef _CURRENT_SOURCE_NOISY_H_
191 current_source_noisy_load_parameters(cs_address, n_noisy_sources, &next);
192#endif
193
194 }
195
196 return true;
197
198 #endif
199}
200
201
202SOMETIMES_UNUSED // Marked unused as only used sometimes
207static inline REAL current_source_get_offset(uint32_t time, uint32_t neuron_index) {
208 // Avoid the loops if no current sources defined
209 #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \
210 !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_)
211 return ZERO;
212 #else
213
214 REAL current_offset = ZERO;
215
216 // Also avoid the loop if no current sources set by user
217 if (n_current_sources != 0) {
218 uint32_t n_current_sources_neuron =
219 neuron_current_source[neuron_index]->n_current_sources;
220 if (n_current_sources_neuron > 0) {
221 for (uint32_t n_cs=0; n_cs < n_current_sources_neuron; n_cs++) {
222 uint32_t cs_id =
223 neuron_current_source[neuron_index]->cs_id_index_list[n_cs].cs_id;
224 uint32_t cs_index =
225 neuron_current_source[neuron_index]->cs_id_index_list[n_cs].cs_index;
226 // Now do the appropriate calculation based on the ID value
227 #ifdef _CURRENT_SOURCE_DC_H_
228 if (cs_id == 1) { // DCSource
229 current_offset += current_source_dc_get_offset(cs_index, time);
230 }
231 #endif
232 #ifdef _CURRENT_SOURCE_AC_H_
233 if (cs_id == 2) { // ACSource
234 current_offset += current_source_ac_get_offset(cs_index, time);
235 }
236 #endif
237 #ifdef _CURRENT_SOURCE_STEP_H_
238 if (cs_id == 3) { // StepCurrentSource
239 current_offset += current_source_step_get_offset(cs_index, time);
240 }
241 #endif
242 #ifdef _CURRENT_SOURCE_NOISY_H_
243 if (cs_id == 4) { // NoisyCurrentSource
244 current_offset += current_source_noisy_get_offset(cs_index, time);
245 }
246 #endif
247 }
248
249 }
250 }
251
252 return current_offset;
253
254 #endif
255}
256
257#endif // _CURRENT_SOURCE_H_
uint32_t time
The current timer tick value.
Definition c_main.c:94
uint32_t * address_t
static bool current_source_initialise(address_t cs_address, uint32_t n_neurons)
Initialise the particular implementation of the data.
static REAL current_source_get_offset(uint32_t time, uint32_t neuron_index)
Calculate the current offset from all injected current sources.
static bool current_source_load_parameters(address_t cs_address)
Load the data into the allocated array structures.
void log_error(const char *message,...)
accum REAL
Type used for "real" numbers.
Definition maths-util.h:91
#define ZERO
A REAL 0.0.
Definition maths-util.h:123
Data type definitions for SpiNNaker Neuron-modelling.
static uint32_t n_neurons
The number of neurons on the core.
Definition neuron.c:45
void io_printf(char *stream, char *format,...)
#define IO_BUF
void spin1_memcpy(void *dst, void const *src, uint len)