Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions neural_modelling/src/bit_field_expander/bit_field_expander.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ uint32_t n_vertex_regions = 0;
bit_field_t* fake_bit_fields;

//! Holds SDRAM read row
uint32_t * row_data;
synaptic_row_t row_data;

//! Says if we should run
bool can_run = true;
Expand Down Expand Up @@ -271,9 +271,8 @@ bool process_synaptic_row(synaptic_row_t row) {
}

// Get address of non-plastic region from row
address_t fixed_region_address = synapse_row_fixed_region(row);
uint32_t fixed_synapse =
synapse_row_num_fixed_synapses(fixed_region_address);
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
uint32_t fixed_synapse = synapse_row_num_fixed_synapses(fixed_region);
if (fixed_synapse == 0) {
log_debug("Plastic and fixed do not have entries, so can be pruned");
return false;
Expand All @@ -289,8 +288,8 @@ bool process_synaptic_row(synaptic_row_t row) {
//! how many bytes to read to get the synaptic row
//! \return Whether there is target
static bool do_sdram_read_and_test(
address_t row_address, uint32_t n_bytes_to_transfer) {
spin1_memcpy(row_data, row_address, n_bytes_to_transfer);
synaptic_row_t row, uint32_t n_bytes_to_transfer) {
spin1_memcpy(row_data, row, n_bytes_to_transfer);
log_debug("Process synaptic row");
return process_synaptic_row(row_data);
}
Expand Down Expand Up @@ -388,10 +387,10 @@ bool generate_bit_field(void) {

// used to store the row from the master pop / synaptic matrix,
// not going to be used in reality.
address_t row_address;
synaptic_row_t row;
if (!bit_found) {
if (population_table_get_first_address(
new_key, &row_address, &n_bytes_to_transfer)) {
new_key, &row, &n_bytes_to_transfer)) {
log_debug("%d", neuron_id);

// This is a direct row to process, so will have 1 target,
Expand All @@ -403,11 +402,11 @@ bool generate_bit_field(void) {
// sdram read (faking dma transfer)
log_debug("DMA read synapse");
bit_found = do_sdram_read_and_test(
row_address, n_bytes_to_transfer);
row, n_bytes_to_transfer);
}

while (!bit_found && population_table_get_next_address(
&new_key, &row_address, &n_bytes_to_transfer)){
&new_key, &row, &n_bytes_to_transfer)){
log_debug("%d", neuron_id);

// This is a direct row to process, so will have 1
Expand All @@ -419,7 +418,7 @@ bool generate_bit_field(void) {
// sdram read (faking dma transfer)
log_debug("DMA read synapse");
bit_found = do_sdram_read_and_test(
row_address, n_bytes_to_transfer);
row, n_bytes_to_transfer);
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions neural_modelling/src/common/neuron-typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,28 @@ static inline payload_t spike_payload(UNUSED spike_t s) {
#endif /*SPIKES_WITH_PAYLOADS*/
#endif /*__SPIKE_T__*/

//! The type of a synaptic row
typedef address_t synaptic_row_t;
//! \brief The type of a synaptic row.
//! \details There is no definition of `struct synaptic row` because it is a
//! form of memory structure that C cannot encode as a single `struct`.
//!
//! It's actually this, with multiple variable length arrays intermixed with
//! size counts:
//! ~~~~~~{.c}
//! struct synaptic_row {
//! uint32_t n_plastic_synapse_words;
//! uint32_t plastic_synapse_data[n_plastic_synapse_words]; // VLA
//! uint32_t n_fixed_synapse_words;
//! uint32_t n_plastic_controls;
//! uint32_t fixed_synapse_data[n_fixed_synapse_words]; // VLA
//! control_t plastic_control_data[n_plastic_controls]; // VLA
//! }
//! ~~~~~~
//!
//! The relevant implementation structures are:
//! * ::synapse_row_plastic_part_t
//! * ::synapse_row_fixed_part_t
//! * ::single_synaptic_row_t
typedef struct synaptic_row *synaptic_row_t;

//! The type of an input
typedef REAL input_t;
Expand Down
47 changes: 28 additions & 19 deletions neural_modelling/src/neuron/direct_synapses.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,50 @@
#include <spin1_api.h>
#include <common/neuron-typedefs.h>

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

//! Working buffer for direct synapse access
static uint32_t single_fixed_synapse[SIZE_OF_SINGLE_FIXED_SYNAPSE];
static single_synaptic_row_t single_fixed_synapse = {0, 1, 0, 0};

//! The layout of the direct matrix region
typedef struct {
const uint32_t size; //!< Size of data, _not_ number of elements
const uint32_t data[]; //!< Direct matrix data
} direct_matrix_data_t;

bool direct_synapses_initialise(
address_t direct_matrix_address, address_t *direct_synapses_address) {
void *direct_matrix_address, address_t *direct_synapses_address) {
Comment thread
rowleya marked this conversation as resolved.
direct_matrix_data_t *direct_matrix = direct_matrix_address;
// Work out the positions of the direct and indirect synaptic matrices
// and copy the direct matrix to DTCM
uint32_t direct_matrix_size = direct_matrix_address[0];
uint32_t direct_matrix_size = direct_matrix->size;
log_info("Direct matrix malloc size is %d", direct_matrix_size);

if (direct_matrix_size != 0) {
*direct_synapses_address = spin1_malloc(direct_matrix_size);
if (*direct_synapses_address == NULL) {
void *dtcm_copy = spin1_malloc(direct_matrix_size);
if (dtcm_copy == NULL) {
log_error("Not enough memory to allocate direct matrix");
return false;
}
log_debug("Copying %u bytes of direct synapses to 0x%08x",
direct_matrix_size, *direct_synapses_address);
spin1_memcpy(*direct_synapses_address, &direct_matrix_address[1],
direct_matrix_size);
direct_matrix_size, dtcm_copy);
spin1_memcpy(dtcm_copy, direct_matrix->data, direct_matrix_size);
*direct_synapses_address = dtcm_copy;
}

// Set up for single fixed synapses
// (data that is consistent per direct row)
single_fixed_synapse[0] = 0;
single_fixed_synapse[1] = 1;
single_fixed_synapse[2] = 0;

return true;
}

synaptic_row_t direct_synapses_get_direct_synapse(address_t row_address) {
single_fixed_synapse[3] = (uint32_t) row_address[0];
return (synaptic_row_t) single_fixed_synapse;
synaptic_row_t direct_synapses_get_direct_synapse(void *row_address) {
uint32_t *data = row_address;
single_fixed_synapse.synapse_datum = *data;
return (synaptic_row_t) &single_fixed_synapse;
}
4 changes: 2 additions & 2 deletions neural_modelling/src/neuron/direct_synapses.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
//! the DTCM address for the direct matrix
//! \return true if successful, false otherwise.
bool direct_synapses_initialise(
address_t direct_matrix_address, address_t *direct_synapses_address);
void *direct_matrix_address, address_t *direct_synapses_address);

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

#endif /* _DIRECT_SYNAPSES_H_ */
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ typedef struct {
post_event_history_t *post_event_history;

//! The format of the plastic data region of a synaptic row
typedef struct {
struct synapse_row_plastic_data_t {
//! The pre-event history
pre_event_history_t history;
//! The per-synapse information
plastic_synapse_t synapses[];
} synapse_row_plastic_data_t;
};

/* PRIVATE FUNCTIONS */

Expand Down Expand Up @@ -205,22 +205,19 @@ static inline final_state_t plasticity_update_synapse(
//---------------------------------------

void synapse_dynamics_print_plastic_synapses(
address_t plastic_region_address, address_t fixed_region_address,
synapse_row_plastic_data_t *plastic_region_data,
synapse_row_fixed_part_t *fixed_region,
uint32_t *ring_buffer_to_input_buffer_left_shifts) {
__use(plastic_region_address);
__use(fixed_region_address);
__use(plastic_region_data);
__use(fixed_region);
__use(ring_buffer_to_input_buffer_left_shifts);

#if LOG_LEVEL >= LOG_DEBUG
synapse_row_plastic_data_t *data_ptr = plastic_region_address;

// Extract separate arrays of weights (from plastic region),
// Control words (from fixed region) and number of plastic synapses
const plastic_synapse_t *plastic_words = data_ptr->synapses;
const control_t *control_words =
synapse_row_plastic_controls(fixed_region_address);
size_t plastic_synapse =
synapse_row_num_plastic_controls(fixed_region_address);
const plastic_synapse_t *plastic_words = plastic_region_data->synapses;
const control_t *control_words = synapse_row_plastic_controls(fixed_region);
size_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);

log_debug("Plastic region %u synapses\n", plastic_synapse);

Expand Down Expand Up @@ -319,28 +316,25 @@ bool synapse_dynamics_initialise(
}

bool synapse_dynamics_process_plastic_synapses(
address_t plastic_region_address, address_t fixed_region_address,
synapse_row_plastic_data_t *plastic_region_address,
synapse_row_fixed_part_t *fixed_region,
weight_t *ring_buffers, uint32_t time) {
synapse_row_plastic_data_t *plastic_data =
(synapse_row_plastic_data_t *) plastic_region_address;
// Extract separate arrays of plastic synapses (from plastic region),
// Control words (from fixed region) and number of plastic synapses
plastic_synapse_t *plastic_words = plastic_data->synapses;
const control_t *control_words =
synapse_row_plastic_controls(fixed_region_address);
size_t plastic_synapse =
synapse_row_num_plastic_controls(fixed_region_address);
plastic_synapse_t *plastic_words = plastic_region_address->synapses;
const control_t *control_words = synapse_row_plastic_controls(fixed_region);
size_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);

num_plastic_pre_synaptic_events += plastic_synapse;

// Get last pre-synaptic event from event history
const uint32_t last_pre_time = plastic_data->history.prev_time;
const pre_trace_t last_pre_trace = plastic_data->history.prev_trace;
const uint32_t last_pre_time = plastic_region_address->history.prev_time;
const pre_trace_t last_pre_trace = plastic_region_address->history.prev_trace;

// Update pre-synaptic trace
log_debug("Adding pre-synaptic event to trace at time:%u", time);
plastic_data->history.prev_time = time;
plastic_data->history.prev_trace =
plastic_region_address->history.prev_time = time;
plastic_region_address->history.prev_trace =
timing_add_pre_spike(time, last_pre_time, last_pre_trace);

// Loop through plastic synapses
Expand Down Expand Up @@ -377,7 +371,7 @@ bool synapse_dynamics_process_plastic_synapses(
}
final_state_t final_state = plasticity_update_synapse(
time, last_pre_time, last_pre_trace,
plastic_data->history.prev_trace,
plastic_region_address->history.prev_trace,
post_delay, delay_axonal, current_state,
&post_event_history[index]);

Expand Down Expand Up @@ -430,11 +424,10 @@ uint32_t synapse_dynamics_get_plastic_saturation_count(void) {
}

bool synapse_dynamics_find_neuron(
uint32_t id, address_t row, weight_t *weight, uint16_t *delay,
uint32_t id, synaptic_row_t row, weight_t *weight, uint16_t *delay,
uint32_t *offset, uint32_t *synapse_type) {
address_t fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = (void *)
synapse_row_plastic_region(row);
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
const plastic_synapse_t *plastic_words = plastic_data->synapses;
const control_t *control_words = synapse_row_plastic_controls(fixed_region);
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
Expand All @@ -458,10 +451,9 @@ bool synapse_dynamics_find_neuron(
return false;
}

bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row) {
address_t fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = (void *)
synapse_row_plastic_region(row);
bool synapse_dynamics_remove_neuron(uint32_t offset, synaptic_row_t row) {
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
plastic_synapse_t *plastic_words = plastic_data->synapses;
control_t *control_words = synapse_row_plastic_controls(fixed_region);
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
Expand All @@ -474,12 +466,11 @@ bool synapse_dynamics_remove_neuron(uint32_t offset, address_t row) {
control_words[plastic_synapse - 1] = 0;

// Decrement FP
fixed_region[1]--;

fixed_region->num_plastic--;
return true;
}

//! \brief packing all of the information into the required plastic control word
//! \brief Pack all of the information into the required plastic control word
//! \param[in] id: The spike ID
//! \param[in] delay: The delay
//! \param[in] type: The synapse type
Expand All @@ -493,14 +484,13 @@ static inline control_t control_conversion(
return new_control;
}

bool synapse_dynamics_add_neuron(uint32_t id, address_t row,
bool synapse_dynamics_add_neuron(uint32_t id, synaptic_row_t row,
weight_t weight, uint32_t delay, uint32_t type) {
plastic_synapse_t new_weight = synapse_structure_create_synapse(weight);
control_t new_control = control_conversion(id, delay, type);

address_t fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = (void *)
synapse_row_plastic_region(row);
synapse_row_fixed_part_t *fixed_region = synapse_row_fixed_region(row);
synapse_row_plastic_data_t *plastic_data = synapse_row_plastic_region(row);
plastic_synapse_t *plastic_words = plastic_data->synapses;
control_t *control_words = synapse_row_plastic_controls(fixed_region);
int32_t plastic_synapse = synapse_row_num_plastic_controls(fixed_region);
Expand All @@ -512,10 +502,11 @@ bool synapse_dynamics_add_neuron(uint32_t id, address_t row,
control_words[plastic_synapse] = new_control;

// Increment FP
fixed_region[1]++;
fixed_region->num_plastic++;
return true;
}

uint32_t synapse_dynamics_n_connections_in_row(address_t fixed) {
uint32_t synapse_dynamics_n_connections_in_row(
synapse_row_fixed_part_t *fixed) {
return synapse_row_num_plastic_controls(fixed);
}
Loading