sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
synapse_expander.c
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
23#include "matrix_generator.h"
25#include "param_generator.h"
26#include "rng.h"
27
28#include <spin1_api.h>
29#include <data_specification.h>
30#include <debug.h>
31#include <key_atom_map.h>
32#include "common_mem.h"
33#include "bit_field_expander.h"
34
35#define INVALID_REGION_ID 0xFFFFFFFF
36
38typedef struct connection_builder_config {
39 // the per-connector parameters
40 uint32_t pre_lo;
41 uint32_t pre_hi;
42 uint32_t post_lo;
43 uint32_t post_hi;
44 uint32_t synapse_type;
45 // The types of the various components
46 uint32_t matrix_type;
47 uint32_t connector_type;
48 uint32_t weight_type;
49 uint32_t delay_type;
51
53__attribute__((aligned(4)))
54typedef struct expander_config {
55 uint32_t synaptic_matrix_region;
56 uint32_t master_pop_region;
57 uint32_t bitfield_filter_region;
58 uint32_t structural_region;
59 uint32_t n_in_edges;
60 uint32_t post_slice_start;
61 uint32_t post_slice_count;
62 uint32_t post_index;
63 uint32_t n_synapse_types;
64 accum timestep_per_delay;
67 unsigned long accum weight_scales[];
68} expander_config_t;
69
72
89 void *synaptic_matrix, uint32_t post_slice_start,
90 uint32_t post_slice_count, uint32_t post_index,
91 unsigned long accum *weight_scales, accum timestep_per_delay) {
94 *region = &sdram_config[1];
95
96 // Get the matrix, connector, weight and delay parameter generators
97 matrix_generator_t matrix_generator =
98 matrix_generator_init(config.matrix_type, region, synaptic_matrix);
99 connection_generator_t connection_generator =
100 connection_generator_init(config.connector_type, region);
101 param_generator_t weight_generator =
102 param_generator_init(config.weight_type, region);
103 param_generator_t delay_generator =
105
106 // If any components couldn't be created return false
108 || delay_generator == NULL || weight_generator == NULL) {
109 return false;
110 }
111
113 connection_generator, config.pre_lo, config.pre_hi, config.post_lo,
114 config.post_hi, post_index, post_slice_start, post_slice_count,
115 weight_scales[config.synapse_type], timestep_per_delay,
116 weight_generator, delay_generator, matrix_generator)) {
117 return false;
118 }
119
120 // Free the neuron four!
123 param_generator_free(weight_generator);
124 param_generator_free(delay_generator);
125
126 // Return success!
127 return true;
128}
129
138 void *params_address) {
139 // Read in the global parameters
140 expander_config_t *sdram_config = params_address;
141 uint32_t data_size = sizeof(expander_config_t)
142 + (sizeof(long accum) * sdram_config->n_synapse_types);
143 expander_config_t *config = spin1_malloc(data_size);
144 fast_memcpy(config, sdram_config, data_size);
145 log_info("Generating %u edges for %u atoms starting at %u",
146 config->n_in_edges, config->post_slice_count, config->post_slice_start);
147
148 // Get the synaptic matrix region
149 void *synaptic_matrix = data_specification_get_region(
150 config->synaptic_matrix_region, ds_regions);
151
152 // We are changing this region, so void the checksum
153 ds_regions->regions[config->synaptic_matrix_region].n_words = 0;
154 ds_regions->regions[config->synaptic_matrix_region].checksum = 0;
155
156 // Store the RNGs
157 population_rng = &(config->population_rng);
158 core_rng = &(config->core_rng);
159
160 log_info("Population RNG: %u %u %u %u", population_rng->seed[0],
161 population_rng->seed[1], population_rng->seed[2],
162 population_rng->seed[3]);
163
164 log_info("Core RNG: %u %u %u %u", core_rng->seed[0],
165 core_rng->seed[1], core_rng->seed[2], core_rng->seed[3]);
166
167
168 // Go through each connector and generate
169 void *address = &(sdram_config->weight_scales[config->n_synapse_types]);
170 for (uint32_t edge = 0; edge < config->n_in_edges; edge++) {
172 &address, synaptic_matrix, config->post_slice_start,
173 config->post_slice_count, config->post_index,
174 config->weight_scales, config->timestep_per_delay)) {
175 return false;
176 }
177 }
178
179 // Do bitfield generation on the whole matrix
180 uint32_t *n_atom_data_sdram = address;
181 void *master_pop = data_specification_get_region(
182 config->master_pop_region, ds_regions);
183 void *bitfield_filter = data_specification_get_region(
184 config->bitfield_filter_region, ds_regions);
185 void *structural_matrix = NULL;
186 if (config->structural_region != INVALID_REGION_ID) {
187 structural_matrix = data_specification_get_region(
188 config->structural_region, ds_regions);
189 }
190
191 // We are changing this region, so void the checksum
192 ds_regions->regions[config->bitfield_filter_region].n_words = 0;
193 ds_regions->regions[config->bitfield_filter_region].checksum = 0;
194 log_info("Region %u set to 0 at 0x%08x and 0x%08x",
195 config->bitfield_filter_region,
196 &(ds_regions->regions[config->bitfield_filter_region].n_words),
197 &(ds_regions->regions[config->bitfield_filter_region].checksum));
198 return do_bitfield_generation(n_atom_data_sdram, master_pop,
199 synaptic_matrix, bitfield_filter, structural_matrix);
200}
201
203void c_main(void) {
205
206 log_info("Starting To Build Connectors");
207
208 // Get pointer to 1st virtual processor info struct in SRAM and get USER1;
209 // This is the ID of the connection builder region from which to read the
210 // rest of the data
211 vcpu_t *virtual_processor_table = (vcpu_t*) SV_VCPU;
212 uint user1 = virtual_processor_table[spin1_get_core_id()].user1;
213
214 // Get the addresses of the regions
217 void *params_address = data_specification_get_region(user1, ds_regions);
218 log_info("\tReading SDRAM at 0x%08x", params_address);
219
220 // Run the expander
221 if (!run_synapse_expander(ds_regions, params_address)) {
222 log_info("!!! Error reading SDRAM data !!!");
224 }
225
226 log_info("Finished On Machine Connectors!");
227}
Expands bitfields on SpiNNaker to reduce data transfer times.
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.
Utility functions for working with memory.
static void fast_memcpy(void *restrict to, const void *restrict from, size_t num_bytes)
A small and fast version of memcpy().
Definition common_mem.h:33
connection_generator_t connection_generator_init(uint32_t hash, void **in_region)
Initialise a specific connection generator.
bool connection_generator_generate(connection_generator_t generator, uint32_t pre_lo, uint32_t pre_hi, uint32_t post_lo, uint32_t post_hi, uint32_t post_index, uint32_t post_slice_start, uint32_t post_slice_count, unsigned long accum weight_scale, accum timestep_per_delay, param_generator_t weight_generator, param_generator_t delay_generator, matrix_generator_t matrix_generator)
Generate connections with a connection generator.
void connection_generator_free(connection_generator_t generator)
Finish with a connection generator.
The data for a connection generator.
Connection Generator interface.
data_specification_metadata_t * data_specification_get_data_address(void)
uint32_t n_words
uint32_t checksum
void log_info(const char *message,...)
matrix_generator_t matrix_generator_init(uint32_t hash, void **in_region, void *synaptic_matrix)
Initialise a specific matrix generator.
void matrix_generator_free(matrix_generator_t generator)
Finish with a matrix generator.
The data for a matrix generator.
Interface for matrix generation.
static uint32_t n_synapse_types
The number of synapse types.
Definition neuron.c:51
void param_generator_free(param_generator_t generator)
Finish with a parameter generator.
param_generator_t param_generator_init(uint32_t hash, void **in_region)
Initialise a specific parameter generator.
Interface for parameter generator.
Random number generator interface.
The Random number generator parameters.
Definition rng.h:30
#define SV_VCPU
CPU_STATE_RUN
RTE_ABORT
uint user1
void sark_cpu_state(cpu_state state)
void rt_error(uint code,...)
region
spike source array region IDs in human readable form
A region of SDRAM used to transfer synapses.
#define NULL
uint spin1_get_core_id(void)
unsigned int uint
static bool read_connection_builder_region(void **region, void *synaptic_matrix, uint32_t post_slice_start, uint32_t post_slice_count, uint32_t post_index, unsigned long accum *weight_scales, accum timestep_per_delay)
Generate the synapses for a single connector.
rng_t * core_rng
An RNG that is local to the current core.
void c_main(void)
Entry point.
rng_t * population_rng
An RNG that starts in the same place on every core of the Population.
static bool run_synapse_expander(data_specification_metadata_t *ds_regions, void *params_address)
Read the data for the expander.
The configuration of the connection builder.