25#include <common/send_mc.h>
42#define UNUSED __attribute__((__unused__))
47#define END_OF_TIME 0xFFFFFFFF
93#define NUMBER_OF_REGIONS_TO_RECORD 1
95#define BYTE_TO_WORD_CONVERTER 4
97#define ISI_SCALE_FACTOR 1000
100typedef enum ssp_callback_priorities {
152__attribute__((aligned(4)))
153typedef struct source_details {
154 unsigned long accum rate;
155 unsigned long accum start;
156 unsigned long accum duration;
265static inline uint32_t
rng(
void) {
289 p = ulrbits(__stdfix_smul_ulr(bitsulr(p),
rng()));
290 }
while (bitsulr(p) > bitsulr(exp_minus_lambda));
298 uint32_t U, U0, USTAR;
307 return A + (
REAL) ulrbits(U0);
324 uint32_t mean_inter_spike_interval_in_ticks) {
326 uint32_t value = (uint32_t) roundk(
329 uint32_t exp_variate = value * mean_inter_spike_interval_in_ticks;
340 UFRACT exp_minus_lambda) {
343 if (bitsulr(exp_minus_lambda) == bitsulr(
UFRACT_CONST(0.0))) {
359 REAL x = (norminv_urt(U) *
HALF) + sqrt_lambda;
361 return (uint32_t) roundk(x * x, 15);
370 UREAL rate_per_tick = ukbits(
372 log_debug(
"Setting rate of %u to %KHz (%K per tick)",
373 sub_id, rate, rate_per_tick);
412 log_debug(
"writing other provenance data");
417 log_debug(
"finished other provenance data");
420static inline uint32_t ms_to_ticks(
unsigned long accum ms) {
424static inline void set_spike_source_details(uint32_t
id,
bool rate_changed) {
426 log_debug(
"Source %u is at index %u",
id, index);
435 if (details.duration == END_OF_TIME) {
436 log_debug(
"Duration of %u is forever",
id);
439 uint32_t duration_ticks = ms_to_ticks(details.duration);
444 log_debug(
"Next of %u never happens",
id);
469#if LOG_LEVEL >= LOG_DEBUG
498 log_info(
"read global_parameters: starting");
503 keys = spin1_malloc(keys_size);
505 log_error(
"Couldn't allocate space %u for %u keys",
519 log_info(
"\tspike sources = %u, starting at %u",
524 log_info(
"slow_rate_per_tick_cutoff = %K",
526 log_info(
"fast_rate_per_tick_cutoff = %K",
528#if LOG_LEVEL >= LOG_DEBUG
534 log_info(
"read_global_parameters: completed successfully");
543 set_spike_source_details(
id,
true);
562 log_error(
"Failed to allocate local sources");
568 log_error(
"Failed to allocate SDRAM source links");
587 while ((index + 1) < n_rates
588 && next_time >= ms_to_ticks(
source_data[i]->details[index + 1].start)) {
593 set_spike_source_details(i, rate_changed || new_index);
596 log_info(
"read_poisson_parameters: completed successfully");
614 for (uint32_t i = 0; i < items->n_items; i++) {
619 source_details details[n_rates];
620 for (uint32_t k = 0; k < n_rates; k++) {
623 (accum) details[k].rate, item->
count);
627 for (uint32_t j = 0; j < item->
count; j++) {
628 source->n_rates = n_rates;
630 for (uint32_t k = 0; k < n_rates; k++) {
631 source->details[k] = details[k];
651 void *recording_region = data_specification_get_region(
665 if (new_spikes ==
NULL) {
666 log_error(
"Cannot reallocate spike buffer");
671 uint32_t *data = (uint32_t *) new_spikes;
672 for (uint32_t n = new_size >> 2; n > 0; n--) {
705 data_specification_get_region(
SYSTEM, ds_regions),
726 void *rates_region = data_specification_get_region(
RATES, ds_regions);
727 bool rates_changed = expand_rates(
730 if (!
read_rates(rates_region, rates_changed, 0)) {
735#if LOG_LEVEL >= LOG_DEBUG
750 struct sdram_config *sdram_conf = data_specification_get_region(
752 uint32_t sdram_inputs_size =
sizeof(
struct sdram_config) + (
753 ssp_params.n_spike_sources *
sizeof(uint16_t));
756 log_error(
"Could not allocate %d bytes for SDRAM inputs",
761 log_info(
"Writing output to address 0x%08x, size in total %d,"
768 log_error(
"Could not allocate %d bytes for input this timestep",
782 log_error(
"Could not allocate rate change buffer!");
786 log_info(
"Initialise: completed successfully");
799 bool rates_changed =
false;
800 if (
time == UINT32_MAX) {
803 log_error(
"failed to reread the Poisson params");
806 rates_changed =
true;
809 void *rates_region = data_specification_get_region(
RATES, ds_regions);
810 bool expand_rates_changed = expand_rates(
813 rates_changed = rates_changed || expand_rates_changed;
816 log_error(
"failed to reread the Poisson rates from SDRAM");
820 log_info(
"Successfully resumed Poisson spike source at time: %u",
time);
823#if LOG_LEVEL >= LOG_DEBUG
839 for (uint32_t n =
n_spikes; n > 0; n--) {
855static inline void add_sdram_spikes(uint32_t s_id, uint32_t num_spikes) {
858 uint32_t sat_test = accumulation & 0xFFFF0000;
860 accumulation = 0xFFFF;
872 uint32_t num_spikes = 0;
877 profiler_write_entry_disable_irq_fiq(
878 PROFILER_ENTER | PROFILER_PROB_FUNC);
881 profiler_write_entry_disable_irq_fiq(
882 PROFILER_EXIT | PROFILER_PROB_FUNC);
885 profiler_write_entry_disable_irq_fiq(
886 PROFILER_ENTER | PROFILER_PROB_FUNC);
889 profiler_write_entry_disable_irq_fiq(
890 PROFILER_EXIT | PROFILER_PROB_FUNC);
893 log_debug(
"Generating %d spikes", num_spikes);
896 if (num_spikes > 0) {
904 send_spike_mc_payload(
spike_key, num_spikes);
906 add_sdram_spikes(s_id, num_spikes);
925 profiler_write_entry_disable_irq_fiq(
926 PROFILER_ENTER | PROFILER_PROB_FUNC);
929 profiler_write_entry_disable_irq_fiq(
930 PROFILER_EXIT | PROFILER_PROB_FUNC);
942 add_sdram_spikes(s_id, count);
958 profiler_write_entry_disable_irq_fiq(PROFILER_ENTER |
PROFILER_TIMER);
969 profiler_write_entry_disable_irq_fiq(PROFILER_EXIT |
PROFILER_TIMER);
1015#if LOG_LEVEL >= LOG_DEBUG
1031 profiler_write_entry_disable_irq_fiq(PROFILER_EXIT |
PROFILER_TIMER);
1065 log_error(
"Error in initialisation - exiting!");
circular_buffer circular_buffer_initialize(uint32_t size)
data_specification_metadata_t * data_specification_get_data_address(void)
bool data_specification_read_header(data_specification_metadata_t *ds_regions)
void log_error(const char *message,...)
void log_debug(const char *message,...)
void log_info(const char *message,...)
static uint32_t key
Base multicast key for sending messages.
uint32_t n_spikes[2]
Spike buffer counters.
maths-util.h - first created 7/10/2013 version 0.1
#define REAL_CONST(x)
Define a constant of type REAL.
unsigned accum UREAL
Type used for "unsigned real" numbers.
#define REAL_COMPARE(x, op, y)
Compare two REAL numbers.
#define EXPU(x)
This calculates the exponential (to base e) of the argument.
accum REAL
Type used for "real" numbers.
#define UFRACT_CONST(x)
Define a constant of type UFRACT.
#define SQRTU(x)
This calculates the square-root of the argument.
unsigned long fract UFRACT
Type used for "unsigned fractional" numbers.
static key_t spike_key(spike_t s)
helper method to retrieve the key from a spike
void profiler_init(uint32_t *data_region)
void profiler_finalise(void)
bool recording_initialize(void **recording_data_address, uint32_t *recording_flags)
void recording_finalise(void)
bool recording_record(channel_index_t channel, void *data, size_t size_bytes)
void recording_reset(void)
void sark_free(void *ptr)
void rt_error(uint code,...)
void sark_word_set(void *dest, uint data, uint n)
void simulation_handle_pause_resume(resume_callback_t callback)
void simulation_set_provenance_function(prov_callback_t provenance_function, address_t provenance_data_address)
bool simulation_is_finished(void)
void simulation_ready_to_read(void)
void simulation_run(void)
bool simulation_initialise(address_t address, uint32_t expected_application_magic_number, uint32_t *timer_period, uint32_t *simulation_ticks_pointer, uint32_t *infinite_run_pointer, uint32_t *time_pointer, int sdp_packet_callback_priority, int dma_transfer_complete_priority)
static void process_slow_source(index_t s_id, spike_source_t *source)
Handle a slow spike source.
static void print_spike_source(index_t s)
Print a spike source.
uint32_t n_buffers
Number of spike-recording buffers.
static bool initialize(void)
Initialise the model by reading in the regions and checking recording data.
static void expand_spike_recording_buffer(uint32_t n_spikes)
Expand the space for recording spikes.
uint32_t count
The number of items to expand.
uint16_t weights[]
The weight to send for each active Poisson source.
uint32_t size_in_bytes
The size of the input data to be transferred per core.
static uint16_t * input_this_timestep
The inputs to be sent at the end of this timestep.
static circular_buffer rate_change_buffer
Buffer for rate change packets.
uint32_t n_colour_bits
Number of bits to use for colour.
region
spike source array region IDs in human readable form
@ PROFILER_REGION
profiling region
@ SPIKE_HISTORY_REGION
spike history recording region
@ PROVENANCE_REGION
provenance region
@ SYSTEM
simulation interface master control
@ EXPANDER_REGION
Expanding of parameters.
@ POISSON_PARAMS
application configuration; global_parameters
@ RATES
rates to apply; source_info
@ SDRAM_PARAMS_REGION
SDRAM transfer parameters region.
static uint32_t simulation_ticks
the number of timer ticks that this model should run for before exiting.
static bool initialise_recording(data_specification_metadata_t *ds_regions)
Initialise the recording parts of the model.
static void mark_spike(uint32_t neuron_id, uint32_t n_spikes)
records spikes as needed
UREAL fast_rate_per_tick_cutoff
The border rate between fast and faster sources.
uint8_t * address
The start address of the input data to be transferred.
uint32_t time
Time of recording.
static global_parameters ssp_params
The global_parameters for the sub-population.
static UREAL ts_per_second
The timesteps per second.
uint32_t first_source_id
The ID of the first source relative to the population as a whole.
static uint32_t faster_spike_source_get_num_spikes(REAL sqrt_lambda)
Determine how many spikes to transmit this timer tick, for a faster source (where λ is large enough t...
static REAL n_steps_until_next(void)
How many time steps until the next spike for a slow Poisson source.
static source_info ** source_data
Array of pointers to sequences of rate data.
static uint32_t colour_mask
The mask to apply to the time to get the colour.
static bool read_rates(source_info *sdram_sources, bool rate_changed, uint32_t next_time)
Read the rates of the Poisson.
uint32_t rate_changed
Determine if any rates have been changed.
uint32_t n_saturations
number of saturations
source_details details[]
Array of rates.
static bool read_global_parameters(global_parameters *sdram_globals)
Read the global parameters stored in Poisson parameter region.
static uint32_t colour
The colour of the current time step.
uint32_t index
Where in the array of rate descriptors we are.
static void read_next_rates(uint32_t id)
Get the next chunk of rates read.
uint32_t out_spikes[]
Spike recording buffers; sort of a bit_field_t[].
uint32_t n_rates
The number of rates.
static uint32_t rng(void)
Random number generation for the Poisson sources. This is a local version for speed of operation.
static void record_spikes(uint32_t time)
writing spikes to SDRAM
uint32_t end_ticks
When the current control regime ends, in timer ticks.
callback_priorities
Priorities for interrupt handlers.
@ TIMER
Regular timer interrupt is lowest priority.
@ MULTICAST
Multicast packet reception uses the FIQ.
@ DMA
DMA complete handling is medium priority.
@ SDP
SDP handling is highest ordinary priority.
static void print_spike_sources(void)
Print all spike sources.
static void reset_spikes(void)
Reset the spike buffer by clearing the bit field.
uint32_t start_ticks
When the current control regime starts, in timer ticks.
static void store_provenance_data(address_t provenance_region)
Writes the provenance data.
static uint32_t fast_spike_source_get_num_spikes(UFRACT exp_minus_lambda)
Determine how many spikes to transmit this timer tick, for a fast source.
UREAL ticks_per_ms
The number of ticks per millisecond for setting the start and duration.
static uint32_t * keys
The keys to send spikes with.
uint32_t max_spikes_per_tick
Maximum expected spikes per tick (for recording)
uint32_t is_fast_source
Flag for whether we're in fast or slow mode.
static struct sdram_config * sdram_inputs
Where synaptic input is to be written.
static uint32_t n_spikes_poisson_fast(UFRACT exp_minus_lambda)
How many spikes to generate for a fast Poisson source.
static spike_source_t * source
The currently applied rate descriptors.
void set_spike_source_rate(uint32_t sub_id, UREAL rate)
Set the spike source rate as required.
uint32_t time_to_spike_ticks
Planned time to spike, in ticks.
static uint32_t recording_flags
keeps track of which types of recording should be done to this model.
static uint32_t n_spike_buffers_allocated
The number of recording spike buffers that have been allocated.
static uint32_t infinite_run
the int that represents the bool for if the run is infinite or not.
static timed_out_spikes * spikes
The recorded spikes.
source_info info
The details for the given number of items.
void c_main(void)
The entry point for this model.
static uint32_t slow_spike_source_get_time_to_spike(uint32_t mean_inter_spike_interval_in_ticks)
Determine the time in timer ticks multiplied by ISI_SCALE_FACTOR until the next spike is to occur giv...
uint32_t next_ticks
When we should load the next control regime, in timer ticks.
uint32_t mean_isi_ticks
Mean interspike interval, in ticks.
static uint32_t n_saturations
static void timer_callback(uint timer_count, uint unused)
Timer interrupt callback.
uint32_t set_rate_neuron_id_mask
The mask to work out the neuron ID when setting the rate.
static uint32_t n_spike_buffer_words
The number of words needed for 1 bit per source.
static uint32_t timer_period
The timer period.
UREAL slow_rate_per_tick_cutoff
The border rate between slow and fast sources.
UFRACT exp_minus_lambda
exp(-λ)
static void process_fast_source(index_t s_id, spike_source_t *source)
Handle a fast spike source.
UFRACT seconds_per_tick
The time between ticks in seconds for setting the rate.
rng_seed_t spike_source_seed
The seed for the Poisson generation process.
uint32_t has_key
True if there is a key to transmit, False otherwise.
static bit_field_t out_spikes_bitfield(uint32_t n)
Set specific spikes for recording.
static void multicast_packet_callback(uint key, uint payload)
Multicast callback used to set rate when injected in a live example.
#define ISI_SCALE_FACTOR
A scale factor to allow the use of integers for "inter-spike intervals".
static void resume_callback(void)
Run any functions needed at resume time.
uint32_t n_spike_sources
The number of sources in this sub-population.
static uint32_t spike_buffer_size
The size of each spike buffer in bytes.
Parameters of the SpikeSourcePoisson.
Structure of the provenance data.
A region of SDRAM used to transfer synapses.
Collection of rates to apply over time to a particular spike source.
data structure for Poisson sources
data structure for recording spikes
uint spin1_dma_transfer(uint tag, void *system_address, void *tcm_address, uint direction, uint length)
void spin1_memcpy(void *dst, void const *src, uint len)
void spin1_callback_on(uint event_id, callback_t cback, int priority)