sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
sp_structs.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 _SP_STRUCTS_H_
22#define _SP_STRUCTS_H_
23
25#include <neuron/synapse_row.h>
26#include <debug.h>
27#include <random.h>
28
29// Define the formation and elimination params
31struct formation_params;
32
34#define IS_CONNECTION_LAT 1
35
36#ifndef SOMETIMES_UNUSED
37#define SOMETIMES_UNUSED __attribute__((unused))
38#endif // !SOMETIMES_UNUSED
39
41typedef struct post_to_pre_entry {
42 uint8_t pop_index;
43 uint8_t sub_pop_index;
44 uint16_t neuron_index;
46
48typedef struct {
49 uint32_t key;
50 uint32_t mask;
51 uint32_t n_colour_bits;
52 uint32_t n_atoms;
53 uint32_t lo_atom;
54 uint32_t m_pop_index;
56
58typedef struct {
59 uint16_t no_pre_vertices;
60 uint16_t sp_control;
61 uint16_t delay_lo;
62 uint16_t delay_hi;
63 uint32_t weight;
64 uint32_t connection_type;
65 uint32_t total_no_atoms;
66 key_atom_info_t key_atom_info[];
68
70typedef struct {
71 uint32_t no_pre_pops;
72 pre_info_t **prepop_info;
74
76typedef struct {
77 uint32_t fast;
78 uint32_t p_rew;
79 uint32_t s_max;
80 uint32_t app_no_atoms;
81 uint32_t machine_no_atoms;
82 uint32_t low_atom;
83 uint32_t high_atom;
84 uint32_t with_replacement;
85 // the 2 seeds that are used: shared for sync, local for everything else
86 mars_kiss64_seed_t shared_seed;
87 mars_kiss64_seed_t local_seed;
88 uint32_t no_pre_pops;
90
92typedef struct {
96 uint32_t post_low_atom;
97 // with_replacement copied from rewiring data
98 uint32_t with_replacement;
99 // what are the currently selecting pre- and post-synaptic neurons
100 uint32_t pre_syn_id;
101 uint32_t post_syn_id;
104 // information extracted from the post to pre table
105 post_to_pre_entry *post_to_pre_table_entry;
106 pre_info_t *pre_population_info;
107 key_atom_info_t *key_atom_info;
108 post_to_pre_entry post_to_pre;
110 uint32_t offset;
112 uint16_t delay;
114 uint16_t weight;
116 uint32_t synapse_type;
118
123static inline uint32_t rand_int(uint32_t max, mars_kiss64_seed_t seed) {
124 return muliulr(max, ulrbits(mars_kiss64_seed(seed)));
125}
126
136static inline bool sp_structs_find_by_spike(
137 const pre_pop_info_table_t *pre_pop_info_table, spike_t spike,
138 uint32_t *restrict neuron_id, uint32_t *restrict population_id,
139 uint32_t *restrict sub_population_id, uint32_t *restrict m_pop_index) {
140 // Amazing linear search inc.
141 // Loop over all populations
142 for (uint32_t i = 0; i < pre_pop_info_table->no_pre_pops; i++) {
143 const pre_info_t *pre_pop_info = pre_pop_info_table->prepop_info[i];
144
145 // Loop over all sub-populations and check if the KEY matches
146 // (with neuron ID masked out)
147 for (int j = 0; j < pre_pop_info->no_pre_vertices; j++) {
148 const key_atom_info_t *kai = &pre_pop_info->key_atom_info[j];
149 if ((spike & kai->mask) == kai->key) {
150 *population_id = i;
151 *sub_population_id = j;
152 *neuron_id = (spike & ~kai->mask) >> kai->n_colour_bits;
153 *m_pop_index = kai->m_pop_index;
154 return true;
155 }
156 }
157 }
158 return false;
159}
160
172 const pre_pop_info_table_t *pre_pop_info_table, uint32_t population_id,
173 uint32_t pop_neuron_id, uint32_t *restrict sub_population_id,
174 uint32_t *restrict sub_pop_neuron_id, uint32_t *restrict spike) {
175 const pre_info_t *app_pop_info =
176 pre_pop_info_table->prepop_info[population_id];
177 uint32_t neuron_id = pop_neuron_id;
178 for (uint32_t i = 0; i < app_pop_info->no_pre_vertices; i++) {
179 const key_atom_info_t *kai = &app_pop_info->key_atom_info[i];
180 uint32_t n_atoms = kai->n_atoms;
181 if (neuron_id < n_atoms) {
182 *sub_population_id = i;
183 *sub_pop_neuron_id = neuron_id;
184 *spike = kai->key | (neuron_id << kai->n_colour_bits);
185 return true;
186 }
187 neuron_id -= n_atoms;
188 }
189 return false;
190}
191
196static inline bool sp_structs_remove_synapse(
197 current_state_t *restrict current_state, synaptic_row_t restrict row) {
198 if (!synapse_dynamics_remove_neuron(current_state->offset, row)) {
199 return false;
200 }
201
202 current_state->post_to_pre_table_entry->neuron_index = 0xFFFF;
203 return true;
204}
205
210static inline bool sp_structs_add_synapse(
211 current_state_t *restrict current_state, synaptic_row_t restrict row) {
212 uint32_t appr_scaled_weight = current_state->pre_population_info->weight;
213
214 uint32_t actual_delay;
215 uint32_t offset = current_state->pre_population_info->delay_hi -
216 current_state->pre_population_info->delay_lo;
217 actual_delay = rand_int(offset, *(current_state->local_seed)) +
218 current_state->pre_population_info->delay_lo;
219
221 current_state->post_syn_id, row, appr_scaled_weight, actual_delay,
222 current_state->pre_population_info->connection_type)) {
223 return false;
224 }
225
226 // Critical: tell the compiler that this pointer is aligned so it doesn't
227 // internally convert the assignment to a memcpy(), which is a saving of
228 // hundreds of bytes...
229 post_to_pre_entry *ppentry = __builtin_assume_aligned(
230 current_state->post_to_pre_table_entry, 4);
231 *ppentry = current_state->post_to_pre;
232 return true;
233}
234
246static inline uint8_t *sp_structs_read_in_common(
247 address_t sdram_sp_address, rewiring_data_t *rewiring_data,
249 uint8_t *data = (uint8_t *) sdram_sp_address;
251 data += sizeof(rewiring_data_t);
252
253 pre_info->no_pre_pops = rewiring_data->no_pre_pops;
254 pre_info->prepop_info = spin1_malloc(
255 rewiring_data->no_pre_pops * sizeof(pre_info_t *));
256 if (pre_info->prepop_info == NULL) {
257 log_error("Could not initialise pre population info");
259 }
260 for (uint32_t i = 0; i < rewiring_data->no_pre_pops; i++) {
261 pre_info->prepop_info[i] = (pre_info_t *) data;
262 uint32_t pre_size = (pre_info->prepop_info[i]->no_pre_vertices
263 * sizeof(key_atom_info_t)) + sizeof(pre_info_t);
264 pre_info->prepop_info[i] = spin1_malloc(pre_size);
265 if (pre_info->prepop_info[i] == NULL) {
266 log_error("Could not initialise pre population info %d", i);
268 }
269 spin1_memcpy(pre_info->prepop_info[i], data, pre_size);
270
271 log_debug("no_pre = %u, sp_control %u, "
272 "delay lo %u, delay hi %u, weight %d",
273 pre_info->prepop_info[i]->no_pre_vertices,
274 pre_info->prepop_info[i]->sp_control,
275 pre_info->prepop_info[i]->delay_lo,
276 pre_info->prepop_info[i]->delay_hi,
277 pre_info->prepop_info[i]->weight);
278 log_debug("connection_type = %d, total_no_atoms=%d",
279 pre_info->prepop_info[i]->connection_type,
280 pre_info->prepop_info[i]->total_no_atoms);
281 data += pre_size;
282 }
283
285 uint32_t n_elements =
286 rewiring_data->s_max * rewiring_data->machine_no_atoms;
287
288 for (uint32_t i=0; i < n_elements; i++){
289 log_debug("index %d, pop index %d, sub pop index %d, neuron_index %d",
290 i, (*post_to_pre_table)[i].pop_index,
291 (*post_to_pre_table)[i].sub_pop_index,
292 (*post_to_pre_table)[i].neuron_index);
293 }
294 data += n_elements * sizeof(post_to_pre_entry);
295 return (uint8_t *) data;
296}
297
298#endif // _SP_STRUCTS_H_
uint32_t * address_t
void log_error(const char *message,...)
void log_debug(const char *message,...)
static uint32_t key
Base multicast key for sending messages.
static uint32_t n_colour_bits
The number of colour bits (both from source and to send)
Configuration of synapse elimination rule.
Configuration of synapse formation rule.
struct synaptic_row * synaptic_row_t
The type of a synaptic row.
uint32_t spike_t
The type of a spike.
uint32_t mars_kiss64_seed(mars_kiss64_seed_t seed)
uint32_t mars_kiss64_seed_t[4]
static mars_kiss64_seed_t seed
YUCK copy and pasted RNG to allow inlining and also to avoid horrific executable bloat.
Definition random_util.h:31
RTE_SWERR
void rt_error(uint code,...)
uint32_t offset
offset in synaptic row (if exists)
Definition sp_structs.h:110
uint32_t element_exists
does the connection already exist
Definition sp_structs.h:103
static uint8_t * sp_structs_read_in_common(address_t sdram_sp_address, rewiring_data_t *rewiring_data, pre_pop_info_table_t *pre_info, post_to_pre_entry **post_to_pre_table)
Common code for structural plasticity initialisation.
Definition sp_structs.h:246
uint32_t synapse_type
synapse type
Definition sp_structs.h:116
static bool sp_structs_add_synapse(current_state_t *restrict current_state, synaptic_row_t restrict row)
Adds a synapse to the relevant structures.
Definition sp_structs.h:210
uint32_t post_low_atom
Low atom copied from rewiring data.
Definition sp_structs.h:96
static bool sp_structs_remove_synapse(current_state_t *restrict current_state, synaptic_row_t restrict row)
Removes a synapse from the relevant structures.
Definition sp_structs.h:196
uint16_t weight
current weight (if exists)
Definition sp_structs.h:114
mars_kiss64_seed_t * local_seed
Seed referenced from rewiring data.
Definition sp_structs.h:94
static uint32_t rand_int(uint32_t max, mars_kiss64_seed_t seed)
Definition sp_structs.h:123
uint16_t delay
current delay (if exists)
Definition sp_structs.h:112
static bool sp_structs_find_by_spike(const pre_pop_info_table_t *pre_pop_info_table, spike_t spike, uint32_t *restrict neuron_id, uint32_t *restrict population_id, uint32_t *restrict sub_population_id, uint32_t *restrict m_pop_index)
unpack the spike into key and identifying information for the neuron; Identify pop,...
Definition sp_structs.h:136
static bool sp_structs_get_sub_pop_info(const pre_pop_info_table_t *pre_pop_info_table, uint32_t population_id, uint32_t pop_neuron_id, uint32_t *restrict sub_population_id, uint32_t *restrict sub_pop_neuron_id, uint32_t *restrict spike)
Get the sub-population id and sub-population-based neuron id given the population id and the populati...
Definition sp_structs.h:171
struct representing the current state of rewiring
Definition sp_structs.h:92
information per atom
Definition sp_structs.h:48
Entry of map from post-connection to pre-connection neural indices.
Definition sp_structs.h:41
individual pre-synaptic sub-population information
Definition sp_structs.h:58
table of individual pre-synaptic information
Definition sp_structs.h:70
parameters of the synaptic rewiring model
Definition sp_structs.h:76
#define NULL
void spin1_memcpy(void *dst, void const *src, uint len)
API for synapse dynamics.
bool synapse_dynamics_add_neuron(uint32_t id, synaptic_row_t row, weight_t weight, uint32_t delay, uint32_t type)
Add an entry in the synaptic row.
bool synapse_dynamics_remove_neuron(uint32_t offset, synaptic_row_t row)
Remove the entry at the specified offset in the synaptic row.
implementation for handling the processing of synapse rows.
rewiring_data_t rewiring_data
the instantiation of the rewiring data
pre_pop_info_table_t pre_info
pre-population information table
static post_to_pre_entry * post_to_pre_table
inverse of synaptic matrix