sPyNNaker neural_modelling 7.1.1
Loading...
Searching...
No Matches
connection_generator_fixed_post.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
24#include <log.h>
26
36
46
54 // Allocate memory for the parameters
55 struct fixed_post *obj = spin1_malloc(sizeof(struct fixed_post));
56
57 // Copy the parameters in
58 struct fixed_post_params *params_sdram = *region;
59 obj->params = *params_sdram;
60 *region = &params_sdram[1];
61
62 log_debug("Fixed Number Post Connector, allow self connections = %u, "
63 "with replacement = %u, n_post = %u",
66 return obj;
67}
68
73static void connection_generator_fixed_post_free(void *generator) {
74 sark_free(generator);
75}
76
84static uint32_t post_random_in_range(rng_t *rng, uint32_t range) {
85 uint32_t u01 = rng_generator(rng) & 0x00007fff;
86 return (u01 * range) >> 15;
87}
88
89static bool fixed_post_write(uint32_t pre, uint32_t post, accum weight_scale,
90 accum timestep_per_delay, param_generator_t weight_generator,
91 param_generator_t delay_generator, matrix_generator_t matrix_generator) {
92 accum weight = param_generator_generate(weight_generator);
93 uint16_t delay = rescale_delay(
94 param_generator_generate(delay_generator), timestep_per_delay);
96 matrix_generator, pre, post, weight, delay, weight_scale);
97}
98
119 void *generator, uint32_t pre_lo, uint32_t pre_hi,
120 uint32_t post_lo, uint32_t post_hi, UNUSED uint32_t post_index,
121 uint32_t post_slice_start, uint32_t post_slice_count,
122 unsigned long accum weight_scale, accum timestep_per_delay,
123 param_generator_t weight_generator, param_generator_t delay_generator,
124 matrix_generator_t matrix_generator) {
125
126 // Get the actual ranges to generate within
127 uint32_t post_slice_end = post_slice_start + post_slice_count;
128
129 struct fixed_post *obj = generator;
130 // Get how many values can be sampled from
131 uint32_t n_values = post_hi - post_lo + 1;
132 // Get the number of connections on each row
133 uint32_t n_conns = obj->params.n_post;
134
135 // We have to generate everything for each row, then just take our share,
136 // so we use the population_rng here to ensure all cores do the same thing
137 for (uint32_t pre = pre_lo; pre <= pre_hi; pre++) {
138 if (obj->params.with_replacement) {
139 // If with replacement just repeated pick
140 for (uint32_t j = 0; j < n_conns; j++) {
141 uint32_t post;
142 do {
143 post = post_random_in_range(population_rng, n_values) + post_lo;
144 } while (!obj->params.allow_self_connections && post == pre);
145 // We can only use post neurons in range here
146 if (post >= post_slice_start && post < post_slice_end) {
147 post -= post_slice_start;
148 if (!fixed_post_write(pre, post, weight_scale, timestep_per_delay,
149 weight_generator, delay_generator, matrix_generator)) {
150 log_error("Matrix not sized correctly!");
151 return false;
152 }
153 }
154 }
155 } else {
156 // Without replacement uses reservoir sampling to save space
157 uint16_t values[n_conns];
158 uint32_t replace_start = n_conns;
159 for (uint32_t j = 0; j < n_conns; j++) {
160 if (j == pre && !obj->params.allow_self_connections) {
161 values[j] = n_conns;
162 replace_start = n_conns + 1;
163 } else {
164 values[j] = j + post_lo;
165 }
166 }
167 for (uint32_t j = replace_start; j < n_values; j++) {
168 // r = random(0, j) (inclusive); swap j into array if r
169 // is in range
170 if (j != pre || obj->params.allow_self_connections) {
171 uint32_t r = post_random_in_range(population_rng, j + 1);
172 if (r < n_conns) {
173 values[r] = j + post_lo;
174 }
175 }
176 }
177 for (uint32_t j = 0; j < n_conns; j++) {
178 if (values[j] >= post_slice_start && values[j] < post_slice_end) {
179 uint32_t post = values[j] - post_slice_start;
180 if (!fixed_post_write(pre, post, weight_scale, timestep_per_delay,
181 weight_generator, delay_generator, matrix_generator)) {
182 log_error("Matrix not sized correctly!");
183 return false;
184 }
185 }
186 }
187 }
188 }
189 return true;
190}
static uint32_t post_random_in_range(rng_t *rng, uint32_t range)
Generates a uniformly-distributed random number.
static void * connection_generator_fixed_post_initialise(void **region)
Initialise the fixed-post connection generator.
static bool connection_generator_fixed_post_generate(void *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 the fixed-post connection generator.
struct fixed_post_params params
Parameters read from SDRAM.
uint32_t allow_self_connections
Do we allow self connections?
uint32_t with_replacement
Do we allow any neuron to be multiply connected by this connector?
static void connection_generator_fixed_post_free(void *generator)
Free the fixed-post connection generator.
uint32_t n_post
Number of connections per pre-neuron in total.
The state of this connection generator.
The parameters that can be copied from SDRAM.
void log_error(const char *message,...)
void log_debug(const char *message,...)
static uint16_t rescale_delay(accum delay, accum timestep_per_delay)
Rescales a delay to account for timesteps and type-converts it.
bool matrix_generator_write_synapse(matrix_generator_t generator, uint32_t pre_index, uint16_t post_index, accum weight, uint16_t delay, unsigned long accum weight_scale)
Write a synapse with a matrix generator.
The data for a matrix generator.
rng_t * population_rng
An RNG that starts in the same place on every core of the Population.
accum param_generator_generate(param_generator_t generator)
Generate value with a parameter generator.
uint32_t rng_generator(rng_t *rng)
Generate a uniformly-distributed random number.
Definition rng.c:26
Random number generator interface.
The Random number generator parameters.
Definition rng.h:30
void sark_free(void *ptr)
region
spike source array region IDs in human readable form
static uint32_t rng(void)
Random number generation for the Poisson sources. This is a local version for speed of operation.