sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
bit_field_expander.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 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#include <bit_field.h>
20#include <neuron/synapse_row.h>
23#include <filter_info.h>
24#include <key_atom_map.h>
25
26/***************************************************************/
27
28static uint32_t master_pop_table_length;
29static master_population_table_entry* master_pop_table;
30static address_list_entry *address_list;
31
39 synaptic_row_t row_data, pop_table_lookup_result_t *result) {
40 spin1_memcpy(row_data, result->row_address, result->n_bytes_to_transfer);
41 log_debug("Process synaptic row");
42
43 // get address of plastic region from row
44 if (synapse_row_plastic_size(row_data) > 0) {
45 log_debug("Plastic row had entries, so cant be pruned");
46 return true;
47 }
48
49 // Get address of non-plastic region from row
50 synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row_data);
51 uint32_t fixed_synapse = synapse_row_num_fixed_synapses(fixed_region);
52 if (fixed_synapse == 0) {
53 log_debug("Plastic and fixed do not have entries, so can be pruned");
54 return false;
55 } else {
56 log_debug("Fixed row has entries, so cant be pruned");
57 return true;
58 }
59}
60
62static inline void determine_redundancy(filter_region_t *bitfield_filters) {
63 // Semantic sugar to keep the code a little shorter
64 filter_info_t *filters = bitfield_filters->filters;
65 for (uint32_t i = 0; i < bitfield_filters->n_filters; i++) {
66 filters[i].merged = 0;
67 filters[i].all_ones = 0;
68 int i_atoms = filters[i].n_atoms;
69 int i_words = get_bit_field_size(i_atoms);
70 if (i_atoms == count_bit_field(filters[i].data, i_words)) {
71 filters[i].all_ones = 1;
72 }
73 }
74}
75
78static inline bool generate_bit_field(filter_region_t *bitfield_filters,
79 uint32_t *n_atom_data, void *synaptic_matrix, void *structural_matrix,
81
82 // Get the location just after the structs for the actual bit fields
83 uint32_t *bit_field_words_location = (uint32_t *)
84 &bitfield_filters->filters[master_pop_table_length];
85 int position = 0;
86
87 // iterate through the master pop entries
88 log_info("Generating %u bitfields", master_pop_table_length);
89 for (uint32_t i = 0; i < master_pop_table_length; i++) {
90
91 // determine n_neurons and bit field size
92 uint32_t n_neurons = n_atom_data[i];
93 uint32_t n_words = get_bit_field_size(n_neurons);
94
95 // Make and clear a bit field
97 if (bit_field == NULL) {
98 log_error("Could not allocate dtcm for bit field");
99 return false;
100 }
101 clear_bit_field(bit_field, n_words);
102
103 master_population_table_entry mp_entry = master_pop_table[i];
104
105 if (structural_matrix != NULL) {
106
107 // If this is a structural entry, set all the bits
108 uint32_t dummy1 = 0, dummy2 = 0, dummy3 = 0, dummy4 = 0;
110 &dummy1, &dummy2, &dummy3, &dummy4)) {
111 for (uint32_t n = 0; n < n_neurons; n++) {
112 bit_field_set(bit_field, n);
113 }
114 }
115 } else {
116
117 // Go through the addresses of the master pop entry
118 uint32_t pos = mp_entry.start;
119 for (uint32_t j = mp_entry.count; j > 0; j--, pos++) {
120
121 // Find the base address and row length of the address entry
122 address_list_entry entry = address_list[pos];
123
124 // Skip invalid addresses
125 if (entry.address == INVALID_ADDRESS) {
126 continue;
127 }
128
129 // Go through each neuron and check the row
130 for (uint32_t n = 0; n < n_neurons; n++) {
131
132 // If this neuron is already set, skip it this round
133 if (bit_field_test(bit_field, n)) {
134 continue;
135 }
136
138 get_row_addr_and_size(entry, (uint32_t) synaptic_matrix,
139 n, &result);
140
141 // Check if the row is non-empty and if so set a bit
142 if (do_sdram_read_and_test(row_data, &result)) {
143 bit_field_set(bit_field, n);
144 }
145 }
146 }
147 }
148
149 // Copy details into SDRAM
150 bitfield_filters->filters[i].key = mp_entry.key;
151 bitfield_filters->filters[i].n_atoms = n_neurons;
152 bitfield_filters->filters[i].n_atoms_per_core = mp_entry.n_neurons;
153 bitfield_filters->filters[i].core_shift = mp_entry.mask_shift;
154 spin1_memcpy(&bit_field_words_location[position], bit_field,
155 n_words * sizeof(uint32_t));
156 bitfield_filters->filters[i].data = &bit_field_words_location[position];
157
158 // Move to the next location in SDRAM for bit fields
159 position += n_words;
160
161 // free dtcm of bitfield.
162 log_debug("Freeing the bitfield dtcm");
163 sark_free(bit_field);
164 }
165
166 // write how many entries (thus bitfields) have been generated into sdram
167 bitfield_filters->n_filters = master_pop_table_length;
168 return true;
169}
170
173 uint32_t *n_atom_data_sdram, void *master_pop,
174 void *synaptic_matrix, void *bitfield_filters, void *structural_matrix) {
175
177 master_pop_table_length = config->table_length;
178
179 if (master_pop_table_length == 0) {
180 return true;
181 }
182
183 master_pop_table = &config->data[0];
184 address_list = (address_list_entry *) &config->data[master_pop_table_length];
185
186 uint32_t n_atom_bytes = master_pop_table_length * sizeof(uint32_t);
187 uint32_t *n_atom_data = spin1_malloc(n_atom_bytes);
188 if (n_atom_data == NULL) {
189 log_error("Couldn't allocate memory for key_to_max_atoms");
191 }
192 spin1_memcpy(n_atom_data, n_atom_data_sdram, n_atom_bytes);
193
194
195 uint32_t row_max_n_words = 0xFF + N_SYNAPSE_ROW_HEADER_WORDS;
196 synaptic_row_t row_data = spin1_malloc(row_max_n_words * sizeof(uint32_t));
197 if (row_data == NULL) {
198 log_error("Could not allocate dtcm for the row data");
199 return false;
200 }
201
205 if (structural_matrix != NULL) {
207 structural_matrix, &rewiring_data, &pre_info, &post_to_pre_table);
208 }
209
210 if (!generate_bit_field(bitfield_filters, n_atom_data, synaptic_matrix,
211 structural_matrix, &pre_info, row_data)) {
212 log_error("Failed to generate bit fields");
213 return false;
214 }
215 determine_redundancy(bitfield_filters);
216 return true;
217}
uint32_t * bit_field_t
bit_field_t bit_field_alloc(uint32_t n_atoms)
static void determine_redundancy(filter_region_t *bitfield_filters)
Determine which bit fields are redundant.
static bool do_bitfield_generation(uint32_t *n_atom_data_sdram, void *master_pop, void *synaptic_matrix, void *bitfield_filters, void *structural_matrix)
Entry point.
static bool generate_bit_field(filter_region_t *bitfield_filters, uint32_t *n_atom_data, void *synaptic_matrix, void *structural_matrix, pre_pop_info_table_t *pre_info, synaptic_row_t row_data)
Create the bitfield for this master pop table and synaptic matrix.
static bool do_sdram_read_and_test(synaptic_row_t row_data, pop_table_lookup_result_t *result)
Read row and test if there are any synapses.
void log_error(const char *message,...)
void log_debug(const char *message,...)
void log_info(const char *message,...)
uint32_t merged
filter_info_t filters[]
uint32_t all_ones
uint32_t core_shift
bit_field_t data
uint32_t n_filters
uint32_t key
uint32_t n_atoms
uint32_t n_atoms_per_core
struct synaptic_row * synaptic_row_t
The type of a synaptic row.
static uint32_t n_neurons
The number of neurons on the core.
Definition neuron.c:45
Master pop(ulation) table API.
uint32_t key
The key to match against the incoming message.
uint32_t count
The number of entries in address_list for this entry.
uint32_t n_neurons
The number of neurons per core.
uint32_t address
the address
static void get_row_addr_and_size(address_list_entry item, uint32_t synaptic_rows_base_address, uint32_t neuron_id, pop_table_lookup_result_t *result)
Get the row address and size for a given neuron.
#define INVALID_ADDRESS
An Invalid address and row length.
uint32_t mask_shift
The shift to apply to the key to get the core part.
uint32_t start
The index into address_list for this entry.
A packed address and row length (note: same size as extra info)
An entry in the master population table.
The memory layout in SDRAM of the first part of the population table configuration....
A structure to hold a response to a population table lookup.
RTE_SWERR
void sark_free(void *ptr)
void rt_error(uint code,...)
Miscellaneous structures.
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
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
Entry of map from post-connection to pre-connection neural indices.
Definition sp_structs.h:41
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)
implementation for handling the processing of synapse rows.
static synapse_row_fixed_part_t * synapse_row_fixed_region(synaptic_row_t row)
Get the address of the non-plastic (or fixed) region.
static size_t synapse_row_num_fixed_synapses(const synapse_row_fixed_part_t *fixed)
Get the number of fixed synapses in the row.
static size_t synapse_row_plastic_size(const synaptic_row_t row)
Get the size of the plastic region.
#define N_SYNAPSE_ROW_HEADER_WORDS
Number of header words per synaptic row.
The type of the fixed part of the row. The fixed-plastic part follows.
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