Skip to content

Commit 4da572e

Browse files
committed
Use structs to access synaptic rows
Complicated because rows have multiple VLAs within them. Code recovered from #857 which was becoming too unwieldy to keep up to date.
1 parent 265b44d commit 4da572e

21 files changed

Lines changed: 350 additions & 323 deletions

neural_modelling/src/common/neuron-typedefs.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,28 @@ static inline payload_t spike_payload(UNUSED spike_t s) {
9595
#endif /*SPIKES_WITH_PAYLOADS*/
9696
#endif /*__SPIKE_T__*/
9797

98-
//! The type of a synaptic row
99-
typedef address_t synaptic_row_t;
98+
//! \brief The type of a synaptic row.
99+
//! \details There is no definition of `struct synaptic row` because it is a
100+
//! form of memory structure that C cannot encode as a single `struct`.
101+
//!
102+
//! It's actually this, with multiple variable length arrays intermixed with
103+
//! size counts:
104+
//! ~~~~~~{.c}
105+
//! struct synaptic_row {
106+
//! uint32_t n_plastic_synapse_words;
107+
//! uint32_t plastic_synapse_data[n_plastic_synapse_words]; // VLA
108+
//! uint32_t n_fixed_synapse_words;
109+
//! uint32_t n_plastic_controls;
110+
//! uint32_t fixed_synapse_data[n_fixed_synapse_words]; // VLA
111+
//! control_t plastic_control_data[n_plastic_controls]; // VLA
112+
//! }
113+
//! ~~~~~~
114+
//!
115+
//! The relevant implementation structures are:
116+
//! * ::synapse_row_plastic_part_t
117+
//! * ::synapse_row_fixed_part_t
118+
//! * ::single_synaptic_row_t
119+
typedef struct synaptic_row *synaptic_row_t;
100120

101121
//! The type of an input
102122
typedef REAL input_t;

neural_modelling/src/neuron/direct_synapses.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,50 @@
2121
#include <spin1_api.h>
2222
#include <common/neuron-typedefs.h>
2323

24-
//! The size of the fixed synapse buffer, in words
25-
#define SIZE_OF_SINGLE_FIXED_SYNAPSE 4
24+
//! \brief The type of a singleton synaptic row.
25+
//! \details The counts are constant. See ::synapse_row_plastic_part_t and
26+
//! ::synapse_row_fixed_part_t for what this is a packed version of.
27+
typedef struct single_synaptic_row_t {
28+
const uint32_t n_plastic; //!< Number of plastic synapses. Always zero
29+
const uint32_t n_fixed; //!< Number of fixed synapses. Always one
30+
const uint32_t n_plastic_controls; //!< Number of plastic controls. Always zero
31+
uint32_t synapse_datum; //!< The value of the single synapse
32+
} single_synaptic_row_t;
2633

2734
//! Working buffer for direct synapse access
28-
static uint32_t single_fixed_synapse[SIZE_OF_SINGLE_FIXED_SYNAPSE];
35+
static single_synaptic_row_t single_fixed_synapse = {0, 1, 0, 0};
36+
37+
//! The layout of the direct matrix region
38+
typedef struct {
39+
const uint32_t size; //!< Size of data, _not_ number of elements
40+
const uint32_t data[]; //!< Direct matrix data
41+
} direct_matrix_data_t;
2942

3043
bool direct_synapses_initialise(
31-
address_t direct_matrix_address, address_t *direct_synapses_address) {
44+
void *direct_matrix_address, address_t *direct_synapses_address) {
45+
direct_matrix_data_t *direct_matrix = direct_matrix_address;
3246
// Work out the positions of the direct and indirect synaptic matrices
3347
// and copy the direct matrix to DTCM
34-
uint32_t direct_matrix_size = direct_matrix_address[0];
48+
uint32_t direct_matrix_size = direct_matrix->size;
3549
log_info("Direct matrix malloc size is %d", direct_matrix_size);
3650

3751
if (direct_matrix_size != 0) {
38-
*direct_synapses_address = spin1_malloc(direct_matrix_size);
39-
if (*direct_synapses_address == NULL) {
52+
void *dtcm_copy = spin1_malloc(direct_matrix_size);
53+
if (dtcm_copy == NULL) {
4054
log_error("Not enough memory to allocate direct matrix");
4155
return false;
4256
}
4357
log_debug("Copying %u bytes of direct synapses to 0x%08x",
44-
direct_matrix_size, *direct_synapses_address);
45-
spin1_memcpy(*direct_synapses_address, &direct_matrix_address[1],
46-
direct_matrix_size);
58+
direct_matrix_size, dtcm_copy);
59+
spin1_memcpy(dtcm_copy, direct_matrix->data, direct_matrix_size);
60+
*direct_synapses_address = dtcm_copy;
4761
}
4862

49-
// Set up for single fixed synapses
50-
// (data that is consistent per direct row)
51-
single_fixed_synapse[0] = 0;
52-
single_fixed_synapse[1] = 1;
53-
single_fixed_synapse[2] = 0;
54-
5563
return true;
5664
}
5765

58-
synaptic_row_t direct_synapses_get_direct_synapse(address_t row_address) {
59-
single_fixed_synapse[3] = (uint32_t) row_address[0];
60-
return (synaptic_row_t) single_fixed_synapse;
66+
synaptic_row_t direct_synapses_get_direct_synapse(void *row_address) {
67+
uint32_t *data = row_address;
68+
single_fixed_synapse.synapse_datum = *data;
69+
return (synaptic_row_t) &single_fixed_synapse;
6170
}

neural_modelling/src/neuron/direct_synapses.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
//! the DTCM address for the direct matrix
2828
//! \return true if successful, false otherwise.
2929
bool direct_synapses_initialise(
30-
address_t direct_matrix_address, address_t *direct_synapses_address);
30+
void *direct_matrix_address, address_t *direct_synapses_address);
3131

3232
//! \brief Get the synapse for a given direct synaptic row.
3333
//! \param[in] row_address: the row address to read.
3434
//! \return the synaptic row synapse data.
35-
synaptic_row_t direct_synapses_get_direct_synapse(address_t row_address);
35+
synaptic_row_t direct_synapses_get_direct_synapse(void *row_address);
3636

3737
#endif /* _DIRECT_SYNAPSES_H_ */

neural_modelling/src/neuron/plasticity/stdp/synapse_dynamics_stdp_mad_impl.c

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,10 @@ uint32_t synapse_dynamics_get_plastic_saturation_count(void) {
430430
}
431431

432432
bool synapse_dynamics_find_neuron(
433-
uint32_t id, address_t row, weight_t *weight, uint16_t *delay,
433+
uint32_t id, synaptic_row_t row, weight_t *weight, uint16_t *delay,
434434
uint32_t *offset, uint32_t *synapse_type) {
435-
address_t fixed_region = synapse_row_fixed_region(row);
436-
synapse_row_plastic_data_t *plastic_data = (void *)
437-
synapse_row_plastic_region(row);
435+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
436+
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
438437
const plastic_synapse_t *plastic_words = plastic_data->synapses;
439438
const control_t *control_words = synapse_row_plastic_controls(fixed_region);
440439
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
@@ -458,10 +457,9 @@ bool synapse_dynamics_find_neuron(
458457
return false;
459458
}
460459

461-
bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row) {
462-
address_t fixed_region = synapse_row_fixed_region(row);
463-
synapse_row_plastic_data_t *plastic_data = (void *)
464-
synapse_row_plastic_region(row);
460+
bool synapse_dynamics_remove_neuron(uint32_t offset, synaptic_row_t row) {
461+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
462+
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
465463
plastic_synapse_t *plastic_words = plastic_data->synapses;
466464
control_t *control_words = synapse_row_plastic_controls(fixed_region);
467465
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
@@ -474,12 +472,11 @@ bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row) {
474472
control_words[plastic_synapse - 1] = 0;
475473

476474
// Decrement FP
477-
fixed_region[1]--;
478-
475+
fixed_region->num_plastic--;
479476
return true;
480477
}
481478

482-
//! \brief packing all of the information into the required plastic control word
479+
//! \brief Pack all of the information into the required plastic control word
483480
//! \param[in] id: The spike ID
484481
//! \param[in] delay: The delay
485482
//! \param[in] type: The synapse type
@@ -493,14 +490,13 @@ static inline control_t control_conversion(
493490
return new_control;
494491
}
495492

496-
bool synapse_dynamics_add_neuron(uint32_t id, address_t row,
493+
bool synapse_dynamics_add_neuron(uint32_t id, synaptic_row_t row,
497494
weight_t weight, uint32_t delay, uint32_t type) {
498495
plastic_synapse_t new_weight = synapse_structure_create_synapse(weight);
499496
control_t new_control = control_conversion(id, delay, type);
500497

501-
address_t fixed_region = synapse_row_fixed_region(row);
502-
synapse_row_plastic_data_t *plastic_data = (void *)
503-
synapse_row_plastic_region(row);
498+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
499+
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
504500
plastic_synapse_t *plastic_words = plastic_data->synapses;
505501
control_t *control_words = synapse_row_plastic_controls(fixed_region);
506502
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
@@ -512,10 +508,11 @@ bool synapse_dynamics_add_neuron(uint32_t id, address_t row,
512508
control_words[plastic_synapse] = new_control;
513509

514510
// Increment FP
515-
fixed_region[1]++;
511+
fixed_region->num_plastic++;
516512
return true;
517513
}
518514

519-
uint32_t synapse_dynamics_n_connections_in_row(address_t fixed) {
515+
uint32_t synapse_dynamics_n_connections_in_row(
516+
synapse_row_fixed_part_t *fixed) {
520517
return synapse_row_num_plastic_controls(fixed);
521518
}

neural_modelling/src/neuron/plasticity/synapse_dynamics.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,18 @@ bool synapse_dynamics_initialise(
3636
address_t address, uint32_t n_neurons, uint32_t n_synapse_types,
3737
uint32_t *ring_buffer_to_input_buffer_left_shifts);
3838

39-
//! \brief Processes the dynamics of the synapses
39+
//! \brief Process the dynamics of the synapses
4040
//! \param[in,out] plastic_region_address: Where the plastic data is
41-
//! \param[in] fixed_region_address: Where the fixed data is
41+
//! \param[in] fixed_region: Where the fixed data is
4242
//! \param[in,out] ring_buffers: The ring buffers
4343
//! \param[in] time: The current simulation time
4444
//! \return ???
4545
bool synapse_dynamics_process_plastic_synapses(
46-
address_t plastic_region_address, address_t fixed_region_address,
46+
address_t plastic_region_address,
47+
synapse_row_fixed_part_t *fixed_region,
4748
weight_t *ring_buffers, uint32_t time);
4849

49-
//! \brief Informs the synapses that the neuron fired
50+
//! \brief Inform the synapses that the neuron fired
5051
//! \param[in] time: The current simulation time
5152
//! \param[in] neuron_index: Which neuron are we processing
5253
void synapse_dynamics_process_post_synaptic_event(
@@ -61,19 +62,20 @@ input_t synapse_dynamics_get_intrinsic_bias(
6162

6263
//! \brief Print the synapse dynamics
6364
//! \param[in] plastic_region_address: Where the plastic data is
64-
//! \param[in] fixed_region_address: Where the fixed data is
65+
//! \param[in] fixed_region: Where the fixed data is
6566
//! \param[in] ring_buffer_to_input_buffer_left_shifts:
6667
//! How to interpret the values from the ring buffers
6768
void synapse_dynamics_print_plastic_synapses(
68-
address_t plastic_region_address, address_t fixed_region_address,
69+
address_t plastic_region_address,
70+
synapse_row_fixed_part_t *fixed_region,
6971
uint32_t *ring_buffer_to_input_buffer_left_shifts);
7072

71-
//! \brief returns the counters for plastic pre synaptic events based on (if
73+
//! \brief Get the counters for plastic pre synaptic events based on (if
7274
//! the model was compiled with SYNAPSE_BENCHMARK parameter) or returns 0
7375
//! \return counters for plastic pre synaptic events or 0
7476
uint32_t synapse_dynamics_get_plastic_pre_synaptic_events(void);
7577

76-
//! \brief returns the number of ring buffer saturation events due to adding
78+
//! \brief Get the number of ring buffer saturation events due to adding
7779
//! plastic weights.
7880
//! \return counter for saturation events or 0
7981
uint32_t synapse_dynamics_get_plastic_saturation_count(void);
@@ -82,25 +84,25 @@ uint32_t synapse_dynamics_get_plastic_saturation_count(void);
8284
// Synaptic rewiring functions
8385
//-----------------------------------------------------------------------------
8486

85-
//! \brief Searches the synaptic row for the the connection with the
87+
//! \brief Search the synaptic row for the the connection with the
8688
//! specified post-synaptic ID
8789
//! \param[in] id: the (core-local) ID of the neuron to search for in the
8890
//! synaptic row
8991
//! \param[in] row: the core-local address of the synaptic row
9092
//! \param[out] weight: address to contain the weight of the connection
9193
//! \param[out] delay: address to contain the delay of the connection
9294
//! \param[out] offset: address to contain the offset of the connection
93-
//! \param[out] synapse_type: address to contain the synapse type of the connection
95+
//! \param[out] synapse_type: the synapse type of the connection
9496
//! \return was the search successful?
9597
bool synapse_dynamics_find_neuron(
96-
uint32_t id, address_t row, weight_t *weight, uint16_t *delay,
98+
uint32_t id, synaptic_row_t row, weight_t *weight, uint16_t *delay,
9799
uint32_t *offset, uint32_t *synapse_type);
98100

99101
//! \brief Remove the entry at the specified offset in the synaptic row
100102
//! \param[in] offset: the offset in the row at which to remove the entry
101103
//! \param[in] row: the core-local address of the synaptic row
102104
//! \return was the removal successful?
103-
bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row);
105+
bool synapse_dynamics_remove_neuron(uint32_t offset, synaptic_row_t row);
104106

105107
//! \brief Add an entry in the synaptic row
106108
//! \param[in] id: the (core-local) ID of the post-synaptic neuron to be added
@@ -110,12 +112,12 @@ bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row);
110112
//! \param[in] type: the type of the connection (e.g. inhibitory)
111113
//! \return was the addition successful?
112114
bool synapse_dynamics_add_neuron(
113-
uint32_t id, address_t row, weight_t weight,
115+
uint32_t id, synaptic_row_t row, weight_t weight,
114116
uint32_t delay, uint32_t type);
115117

116118
//! \brief Get the number of connections in the given row
117119
//! \param[in] fixed: the fixed region of the synaptic row
118120
//! \return The number of connections in the row
119-
uint32_t synapse_dynamics_n_connections_in_row(address_t fixed);
121+
uint32_t synapse_dynamics_n_connections_in_row(synapse_row_fixed_part_t *fixed);
120122

121123
#endif // _SYNAPSE_DYNAMICS_H_

neural_modelling/src/neuron/plasticity/synapse_dynamics_static_impl.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void synapse_dynamics_process_post_synaptic_event(
7171
//---------------------------------------
7272
bool synapse_dynamics_process_plastic_synapses(
7373
UNUSED address_t plastic_region_address,
74-
UNUSED address_t fixed_region_address,
74+
UNUSED synapse_row_fixed_part_t *fixed_region,
7575
UNUSED weight_t *ring_buffer, UNUSED uint32_t time) {
7676
log_error("There should be no plastic synapses!");
7777
return false;
@@ -85,7 +85,7 @@ input_t synapse_dynamics_get_intrinsic_bias(
8585

8686
void synapse_dynamics_print_plastic_synapses(
8787
UNUSED address_t plastic_region_address,
88-
UNUSED address_t fixed_region_address,
88+
UNUSED synapse_row_fixed_part_t *fixed_region,
8989
UNUSED uint32_t *ring_buffer_to_input_left_shifts) {
9090
}
9191

@@ -98,9 +98,9 @@ uint32_t synapse_dynamics_get_plastic_saturation_count(void) {
9898
}
9999

100100
bool synapse_dynamics_find_neuron(
101-
uint32_t id, address_t row, weight_t *weight, uint16_t *delay,
101+
uint32_t id, synaptic_row_t row, weight_t *weight, uint16_t *delay,
102102
uint32_t *offset, uint32_t *synapse_type) {
103-
address_t fixed_region = synapse_row_fixed_region(row);
103+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
104104
int32_t fixed_synapse = synapse_row_num_fixed_synapses(fixed_region);
105105
uint32_t *synaptic_words = synapse_row_fixed_weight_controls(fixed_region);
106106

@@ -125,16 +125,16 @@ bool synapse_dynamics_find_neuron(
125125
return false;
126126
}
127127

128-
bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row) {
129-
address_t fixed_region = synapse_row_fixed_region(row);
128+
bool synapse_dynamics_remove_neuron(uint32_t offset, synaptic_row_t row) {
129+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
130130
int32_t fixed_synapse = synapse_row_num_fixed_synapses(fixed_region);
131131
uint32_t *synaptic_words = synapse_row_fixed_weight_controls(fixed_region);
132132

133-
// Delete control word at offset (contains weight)
134-
synaptic_words[offset] = synaptic_words[fixed_synapse-1];
133+
// Delete control word at offset (contains weight)
134+
synaptic_words[offset] = synaptic_words[fixed_synapse - 1];
135135

136136
// Decrement FF
137-
fixed_region[0] = fixed_region[0] - 1;
137+
fixed_region->num_fixed--;
138138
return true;
139139
}
140140

@@ -151,21 +151,22 @@ static inline uint32_t _fixed_synapse_convert(
151151
}
152152

153153
bool synapse_dynamics_add_neuron(
154-
uint32_t id, address_t row, weight_t weight,
154+
uint32_t id, synaptic_row_t row, weight_t weight,
155155
uint32_t delay, uint32_t type) {
156-
address_t fixed_region = synapse_row_fixed_region(row);
156+
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
157157
int32_t fixed_synapse = synapse_row_num_fixed_synapses(fixed_region);
158158
uint32_t *synaptic_words = synapse_row_fixed_weight_controls(fixed_region);
159159
uint32_t new_synapse = _fixed_synapse_convert(id, weight, delay, type);
160160

161161
// Add control word at offset
162162
synaptic_words[fixed_synapse] = new_synapse;
163163

164-
// Increment FF
165-
fixed_region[0] = fixed_region[0] + 1;
164+
// Increment FF
165+
fixed_region->num_fixed++;
166166
return true;
167167
}
168168

169-
uint32_t synapse_dynamics_n_connections_in_row(address_t fixed) {
169+
uint32_t synapse_dynamics_n_connections_in_row(
170+
synapse_row_fixed_part_t *fixed) {
170171
return synapse_row_num_fixed_synapses(fixed);
171172
}

neural_modelling/src/neuron/population_table/population_table.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extern uint32_t failed_bit_field_reads;
3939
//! they don't hit anything
4040
extern uint32_t bit_field_filtered_packets;
4141

42-
//! \brief Sets up the table
42+
//! \brief Set up the table
4343
//! \param[in] table_address: The address of the start of the table data
4444
//! \param[in] synapse_rows_address: The address of the start of the synapse
4545
//! data
@@ -63,7 +63,8 @@ bool population_table_load_bitfields(filter_region_t *filter_region);
6363
//! \param[out] n_bytes_to_transfer: Updated with the number of bytes to read
6464
//! \return True if there is a row to read, False if not
6565
bool population_table_get_first_address(
66-
spike_t spike, address_t* row_address, size_t* n_bytes_to_transfer);
66+
spike_t spike, synaptic_row_t* row_address,
67+
size_t* n_bytes_to_transfer);
6768

6869
//! \brief Get the next row data for a previously given spike. If no spike has
6970
//! been given, return False.
@@ -72,7 +73,7 @@ bool population_table_get_first_address(
7273
//! \param[out] n_bytes_to_transfer: Updated with the number of bytes to read
7374
//! \return True if there is a row to read, False if not
7475
bool population_table_get_next_address(
75-
spike_t *spike, address_t* row_address, size_t* n_bytes_to_transfer);
76-
76+
spike_t *spike, synaptic_row_t* row_address,
77+
size_t* n_bytes_to_transfer);
7778

7879
#endif // _POPULATION_TABLE_H_

0 commit comments

Comments
 (0)