void read_parameters(address_t region_address) { log_info("Reading parameters from 0x%.8x", region_address); key = region_address[0]; speed = region_address[1]; sample_time = region_address[2]; update_time = region_address[3]; delay_time = region_address[4]; delta_threshold = region_address[5]; continue_if_not_different = region_address[6]; // Allocate the space for the schedule counters = (uint32_t*) spin1_malloc(N_COUNTERS * sizeof(uint32_t)); last_speed = (uint32_t*) spin1_malloc(N_COUNTERS * sizeof(uint32_t)); for (uint32_t i = 0; i < N_COUNTERS; i++) { counters[i] = 0; last_speed[i] = 0; } log_info("Key = %d, speed = %d, sample_time = %d, update_time = %d," " delay_time = %d, delta_threshold = %d," " continue_if_not_different = %d", key, speed, sample_time, update_time, delay_time, delta_threshold, continue_if_not_different); }
bool synaptic_current_data_filled (address_t address, uint32_t flags) { use(flags); log_info("synaptic_current_data_filled: starting"); // Loop through synapse types for(index_t s = 0; s < SYNAPSE_TYPE_COUNT; s++) { log_info("\tCopying %u synapse type %u parameters of size %u", num_neurons, s, sizeof(synapse_param_t)); // Allocate block of memory for this synapse type's pre-calculated per-neuron decay neuron_synapse_params[s] = (synapse_param_t*) spin1_malloc(sizeof(synapse_param_t) * num_neurons); // Check for success if(neuron_synapse_params[s] == NULL) { sentinel("Cannot allocate neuron synapse decay parameters - Out of DTCM"); return false; } log_info("\tCopying %u bytes to %u", num_neurons * sizeof(synapse_param_t), address + ((num_neurons * s * sizeof(synapse_param_t)) / 4)); memcpy(neuron_synapse_params[s], address + ((num_neurons * s * sizeof(synapse_param_t)) / 4), num_neurons * sizeof(synapse_param_t)); } log_info("synaptic_current_data_filled: completed successfully"); return true; }
static inline void _mark_spike(uint32_t neuron_id, uint32_t n_spikes) { if (recording_flags > 0) { if (n_spike_buffers_allocated < n_spikes) { uint32_t new_size = 8 + (n_spikes * spike_buffer_size); timed_out_spikes *new_spikes = (timed_out_spikes *) spin1_malloc( new_size); if (new_spikes == NULL) { log_error("Cannot reallocate spike buffer"); rt_error(RTE_SWERR); } uint32_t *data = (uint32_t *) new_spikes; for (uint32_t n = new_size >> 2; n > 0; n--) { data[n - 1] = 0; } if (spikes != NULL) { uint32_t old_size = 8 + (n_spike_buffers_allocated * spike_buffer_size); spin1_memcpy(new_spikes, spikes, old_size); sark_free(spikes); } spikes = new_spikes; n_spike_buffers_allocated = n_spikes; } if (spikes->n_buffers < n_spikes) { spikes->n_buffers = n_spikes; } for (uint32_t n = n_spikes; n > 0; n--) { bit_field_set(_out_spikes(n - 1), neuron_id); } }
param_generator_t param_generator_init(uint32_t hash, address_t *in_region) { // Look through the known generators for (uint32_t i = 0; i < N_PARAM_GENERATORS; i++) { // If the hash requested matches the hash of the generator, use it if (hash == param_generators[i].hash) { // Prepare a space for the data address_t region = *in_region; param_generator_t generator = spin1_malloc( sizeof(param_generator_t)); if (generator == NULL) { log_error("Could not create generator"); return NULL; } // Store the index generator->index = i; // Initialise the generator and store the data generator->data = param_generators[i].initialize(®ion); *in_region = region; return generator; } } log_error("Param generator with hash %u not found", hash); return NULL; }
//! \brief method for reading the parameters stored in Poisson parameter region //! \param[in] address the absolute SDRAm memory address to which the //! Poisson parameter region starts. //! \return a boolean which is True if the parameters were read successfully or //! False otherwise static bool read_poisson_parameters(address_t address) { // Allocate DTCM for array of spike sources and copy block of data if (global_parameters.n_spike_sources > 0) { // the first time around, the array is set to NULL, afterwards, // assuming all goes well, there's an address here. if (poisson_parameters == NULL){ poisson_parameters = (spike_source_t*) spin1_malloc( global_parameters.n_spike_sources * sizeof(spike_source_t)); } // if failed to alloc memory, report and fail. if (poisson_parameters == NULL) { log_error("Failed to allocate poisson_parameters"); return false; } // store spike source data into DTCM uint32_t spikes_offset = sizeof(global_parameters) / 4; spin1_memcpy( poisson_parameters, &address[spikes_offset], global_parameters.n_spike_sources * sizeof(spike_source_t)); } log_info("read_poisson_parameters: completed successfully"); return true; }
bool synapses_initialise(address_t address, uint32_t n_neurons_value, input_t **input_buffers_value, uint32_t **ring_buffer_to_input_buffer_left_shifts) { log_info("synapses_initialise: starting"); n_neurons = n_neurons_value; *input_buffers_value = input_buffers; // Set the initial values to 0 for (uint32_t i = 0; i < INPUT_BUFFER_SIZE; i++) { input_buffers[i] = 0; } for (uint32_t i = 0; i < RING_BUFFER_SIZE; i++) { ring_buffers[i] = 0; } // Get the synapse shaping data for (index_t synapse_index = 0; synapse_index < SYNAPSE_TYPE_COUNT; synapse_index++) { log_debug("\tCopying %u synapse type %u parameters of size %u", n_neurons, synapse_index, sizeof(synapse_param_t)); // Allocate block of memory for this synapse type'synapse_index // pre-calculated per-neuron decay neuron_synapse_shaping_params[synapse_index] = (synapse_param_t *) spin1_malloc( sizeof(synapse_param_t) * n_neurons); // Check for success if (neuron_synapse_shaping_params[synapse_index] == NULL) { log_error("Cannot allocate neuron synapse parameters" "- Out of DTCM"); return false; } log_debug( "\tCopying %u bytes from %u", n_neurons * sizeof(synapse_param_t), address + ((n_neurons * synapse_index * sizeof(synapse_param_t)) / 4)); memcpy(neuron_synapse_shaping_params[synapse_index], address + ((n_neurons * synapse_index * sizeof(synapse_param_t)) / 4), n_neurons * sizeof(synapse_param_t)); } // Get the ring buffer left shifts uint32_t ring_buffer_input_left_shifts_base = ((n_neurons * SYNAPSE_TYPE_COUNT * sizeof(synapse_param_t)) / 4); for (index_t synapse_index = 0; synapse_index < SYNAPSE_TYPE_COUNT; synapse_index++) { ring_buffer_to_input_left_shifts[synapse_index] = address[ring_buffer_input_left_shifts_base + synapse_index]; } *ring_buffer_to_input_buffer_left_shifts = ring_buffer_to_input_left_shifts; log_info("synapses_initialise: completed successfully"); return true; }
/****f* simple.c/app_init * * SUMMARY * This function is called at application start-up. * It's used to say hello, setup multicast routing table entries, * and initialise application variables. * * SYNOPSIS * void app_init () * * SOURCE */ void app_init () { uint i; /* ------------------------------------------------------------------- */ /* initialise routing entries */ /* ------------------------------------------------------------------- */ /* set a MC routing table entry to send my packets back to me */ spin1_set_mc_table_entry(coreID, // entry coreID, // key 0xffffffff, // mask (uint) (1 << (coreID+6)) // route ); /* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */ /* initialize the application processor resources */ /* ------------------------------------------------------------------- */ /* say hello */ io_printf (IO_STD, "[core %d] -----------------------\n", coreID); spin1_delay_us (PRINT_DLY); io_printf (IO_STD, "[core %d] starting simulation\n", coreID); spin1_delay_us (PRINT_DLY); /* use a buffer in the middle of system RAM - avoid conflict with RTK */ sysram_buffer = (uint *) (SPINN_SYSRAM_BASE + SPINN_SYSRAM_SIZE/2 + (coreID * BUFFER_SIZE * sizeof(uint))); /* use a buffer somewhere in SDRAM */ sdram_buffer = (uint *) (SPINN_SDRAM_BASE + SPINN_SDRAM_SIZE/8 + (coreID * BUFFER_SIZE * sizeof(uint))); /* allocate buffer in DTCM */ if ((dtcm_buffer = (uint *) spin1_malloc(BUFFER_SIZE*sizeof(uint))) == 0) { test_DMA = FALSE; io_printf (IO_STD, "[core %d] error - cannot allocate dtcm buffer\n", coreID); spin1_delay_us (PRINT_DLY); } else { test_DMA = TRUE; /* initialize sections of DTCM, system RAM and SDRAM */ for (i=0; i<BUFFER_SIZE; i++) { dtcm_buffer[i] = i; sysram_buffer[i] = 0xa5a5a5a5; sdram_buffer[i] = 0x5a5a5a5a; } io_printf (IO_STD, "[core %d] dtcm buffer @ 0x%8z\n", coreID, (uint) dtcm_buffer); spin1_delay_us (PRINT_DLY); } /* ------------------------------------------------------------------- */ }
//! \brief initialise the recording of spikes //! \param[in] max_spike_sources the number of spike sources to be recorded //! \return True if the initialisation was successful, false otherwise bool out_spikes_initialize(size_t max_spike_sources) { out_spikes_size = get_bit_field_size(max_spike_sources); log_debug("Out spike size is %u words, allowing %u spike sources", out_spikes_size, max_spike_sources); spikes = (timed_out_spikes *) spin1_malloc( sizeof(timed_out_spikes) + (out_spikes_size * sizeof(uint32_t))); if (spikes == NULL) { log_error("Out of DTCM when allocating out_spikes"); return false; } out_spikes = &(spikes->out_spikes[0]); out_spikes_reset(); return true; }
neuron_pointer_t create_izh_neuron( REAL A, REAL B, REAL C, REAL D, REAL V, REAL U, REAL I ) { neuron_pointer_t neuron = spin1_malloc( sizeof( neuron_t ) ); neuron->A = A; io_printf( WHERE_TO, "\nA = %11.4k \n", neuron->A ); neuron->B = B; io_printf( WHERE_TO, "B = %11.4k \n", neuron->B ); neuron->C = C; io_printf( WHERE_TO, "C = %11.4k mV\n", neuron->C ); neuron->D = D; io_printf( WHERE_TO, "D = %11.4k ??\n\n", neuron->D ); neuron->V = V; io_printf( WHERE_TO, "V = %11.4k mV\n", neuron->V ); neuron->U = U; io_printf( WHERE_TO, "U = %11.4k ??\n\n", neuron->U ); neuron->I_offset = I; io_printf( WHERE_TO, "I = %11.4k nA?\n", neuron->I_offset ); neuron->this_h = machine_timestep * REAL_CONST(1.001); io_printf( WHERE_TO, "h = %11.4k ms\n", neuron->this_h ); return neuron; }
void configure_model() { // Initialize spike queue delay_us = ((neuron_t *)population->neuron)[0].delay; spike_ring = (spike_ring_t*)spin1_malloc((3+SPIKE_QUEUE_SIZE)*sizeof(uint)); if (spike_ring == NULL) { io_printf(IO_STD, "DendriticDelay: Impossible to allocate memory for the event ring\n"); while(1) ; } spike_ring->ring_start = 0; spike_ring->ring_end = 0; spike_ring->ring_empty = 1; missed_events = 0; events_received = 0; events_sent = 0; io_printf(IO_STD, "Running DendriticDelay model with delay %u...\n", delay_us); }
void configure_recording_space() { record_v = (short *) 0x72136400 + 0x200000 * (app_data.virtual_core_id - 1); record_i = (short *) 0x7309a400 + 0x200000 * (app_data.virtual_core_id - 1); // cleaning for (uint i = 0; i < 0x100000; i++) record_v[i] = 0; for (uint i = 0; i < 0x100000; i++) record_i[i] = 0; record_spikes = (uint *) 0x72040000; for(uint i = 0; i < 1000; i++) record_spikes[i] = 0; //TODO improve // spike count int *spike_count_dest = NULL; spike_count_dest = (int *) spin1_malloc(num_populations); spike_count = (int *) spike_count_dest; for(uint i = 0; i < num_populations; i++) spike_count[i] = 0; //TODO improve }
/** *! \brief Read the data for the generator *! \param[in] delay_params_address The address of the delay extension *! parameters *! \param[in] params_address The address of the expander parameters *! \return True if the expander finished correctly, False if there was an *! error */ bool read_sdram_data( address_t delay_params_address, address_t params_address) { // Read the global parameters from the delay extension uint32_t num_neurons = delay_params_address[N_ATOMS]; uint32_t neuron_bit_field_words = get_bit_field_size(num_neurons); uint32_t n_stages = delay_params_address[N_DELAY_STAGES]; // Set up the bit fields bit_field_t *neuron_delay_stage_config = (bit_field_t*) spin1_malloc( n_stages * sizeof(bit_field_t)); for (uint32_t d = 0; d < n_stages; d++) { neuron_delay_stage_config[d] = (bit_field_t) &(delay_params_address[DELAY_BLOCKS]) + (d * neuron_bit_field_words); clear_bit_field(neuron_delay_stage_config[d], neuron_bit_field_words); } // Read the global parameters from the expander region uint32_t n_out_edges = *params_address++; uint32_t pre_slice_start = *params_address++; uint32_t pre_slice_count = *params_address++; log_debug("Generating %u delay edges for %u atoms starting at %u", n_out_edges, pre_slice_count, pre_slice_start); // Go through each connector and make the delay data for (uint32_t edge = 0; edge < n_out_edges; edge++) { if (!read_delay_builder_region( ¶ms_address, neuron_delay_stage_config, pre_slice_start, pre_slice_count)) { return false; } } return true; }
//! \brief Set up the neuron models //! \param[in] address the absolute address in SDRAM for the start of the //! NEURON_PARAMS data region in SDRAM //! \param[in] recording_flags_param the recordings parameters //! (contains which regions are active and how big they are) //! \param[out] n_neurons_value The number of neurons this model is to emulate //! \return True is the initialisation was successful, otherwise False bool neuron_initialise(address_t address, uint32_t recording_flags_param, uint32_t *n_neurons_value, uint32_t *incoming_spike_buffer_size) { log_info("neuron_initialise: starting"); // Check if there is a key to use use_key = address[HAS_KEY]; // Read the spike key to use key = address[TRANSMISSION_KEY]; // output if this model is expecting to transmit if (!use_key){ log_info("\tThis model is not expecting to transmit as it has no key"); } else{ log_info("\tThis model is expected to transmit with key = %08x", key); } // Read the neuron details n_neurons = address[N_NEURONS_TO_SIMULATE]; *n_neurons_value = n_neurons; // Read the size of the incoming spike buffer to use *incoming_spike_buffer_size = address[INCOMING_SPIKE_BUFFER_SIZE]; uint32_t next = START_OF_GLOBAL_PARAMETERS; // Read the global parameter details if (sizeof(global_neuron_params_t) > 0) { global_parameters = (global_neuron_params_t *) spin1_malloc( sizeof(global_neuron_params_t)); if (global_parameters == NULL) { log_error("Unable to allocate global neuron parameters" "- Out of DTCM"); return false; } memcpy(global_parameters, &address[next], sizeof(global_neuron_params_t)); next += sizeof(global_neuron_params_t) / 4; } log_info( "\t neurons = %u, spike buffer size = %u, params size = %u," "input type size = %u, threshold size = %u", n_neurons, *incoming_spike_buffer_size, sizeof(neuron_t), sizeof(input_type_t), sizeof(threshold_type_t)); // Allocate DTCM for neuron array and copy block of data if (sizeof(neuron_t) != 0) { neuron_array = (neuron_t *) spin1_malloc(n_neurons * sizeof(neuron_t)); if (neuron_array == NULL) { log_error("Unable to allocate neuron array - Out of DTCM"); return false; } memcpy(neuron_array, &address[next], n_neurons * sizeof(neuron_t)); next += (n_neurons * sizeof(neuron_t)) / 4; } // Allocate DTCM for input type array and copy block of data if (sizeof(input_type_t) != 0) { input_type_array = (input_type_t *) spin1_malloc( n_neurons * sizeof(input_type_t)); if (input_type_array == NULL) { log_error("Unable to allocate input type array - Out of DTCM"); return false; } memcpy(input_type_array, &address[next], n_neurons * sizeof(input_type_t)); next += (n_neurons * sizeof(input_type_t)) / 4; } // Allocate DTCM for additional input array and copy block of data if (sizeof(additional_input_t) != 0) { additional_input_array = (additional_input_pointer_t) spin1_malloc( n_neurons * sizeof(additional_input_t)); if (additional_input_array == NULL) { log_error("Unable to allocate additional input array" " - Out of DTCM"); return false; } memcpy(additional_input_array, &address[next], n_neurons * sizeof(additional_input_t)); next += (n_neurons * sizeof(additional_input_t)) / 4; } // Allocate DTCM for threshold type array and copy block of data if (sizeof(threshold_type_t) != 0) { threshold_type_array = (threshold_type_t *) spin1_malloc( n_neurons * sizeof(threshold_type_t)); if (threshold_type_array == NULL) { log_error("Unable to allocate threshold type array - Out of DTCM"); return false; } memcpy(threshold_type_array, &address[next], n_neurons * sizeof(threshold_type_t)); } // Set up the out spikes array if (!out_spikes_initialize(n_neurons)) { return false; } // Set up the neuron model neuron_model_set_global_neuron_params(global_parameters); recording_flags = recording_flags_param; voltages_size = sizeof(uint32_t) + sizeof(state_t) * n_neurons; voltages = (timed_state_t *) spin1_malloc(voltages_size); input_size = sizeof(uint32_t) + sizeof(input_struct_t) * n_neurons; inputs = (timed_input_t *) spin1_malloc(input_size); _print_neuron_parameters(); return true; }
void c_main(void) { // Set the system up io_printf(IO_BUF, "[Ensemble] C_MAIN\n"); address_t address = system_load_sram(); if (!data_system(region_start(1, address))) { io_printf(IO_BUF, "[Ensemble] Failed to start.\n"); return; } // Get data data_get_bias(region_start(2, address), g_ensemble.n_neurons); data_get_encoders(region_start(3, address), g_ensemble.n_neurons, g_input.n_dimensions); data_get_decoders(region_start(4, address), g_ensemble.n_neurons, g_n_output_dimensions); data_get_keys(region_start(5, address), g_n_output_dimensions); // Get the inhibitory gains g_ensemble.inhib_gain = spin1_malloc(g_ensemble.n_neurons * sizeof(value_t)); if (g_ensemble.inhib_gain == NULL) { io_printf(IO_BUF, "[Ensemble] Failed to malloc inhib gains.\n"); return; } spin1_memcpy(g_ensemble.inhib_gain, region_start(10, address), g_ensemble.n_neurons * sizeof(value_t)); for (uint n = 0; n < g_ensemble.n_neurons; n++) { io_printf(IO_BUF, "Inhib gain[%d] = %k\n", n, g_ensemble.inhib_gain[n]); } // Load subcomponents if (!input_filter_get_filters(&g_input, region_start(6, address)) || !input_filter_get_filter_routes(&g_input, region_start(7, address)) || !input_filter_get_filters(&g_input_inhibitory, region_start(8, address)) || !input_filter_get_filter_routes(&g_input_inhibitory, region_start(9, address)) || !input_filter_get_filters(&g_input_modulatory, region_start(11, address)) || !input_filter_get_filter_routes(&g_input_modulatory, region_start(12, address))) { io_printf(IO_BUF, "[Ensemble] Failed to start.\n"); return; } if(!get_pes(region_start(13, address))) { io_printf(IO_BUF, "[Ensemble] Failed to start.\n"); return; } // Set up recording if (!record_buffer_initialise(&g_ensemble.recd, region_start(15, address), simulation_ticks, g_ensemble.n_neurons)) { io_printf(IO_BUF, "[Ensemble] Failed to start.\n"); return; } // Set up routing tables io_printf(IO_BUF, "[Ensemble] C_MAIN Configuring system.\n"); if(leadAp){ system_lead_app_configured(); } // Setup timer tick, start io_printf(IO_BUF, "[Ensemble] C_MAIN Set timer and spin1_start.\n"); spin1_set_timer_tick(g_ensemble.machine_timestep); spin1_start(SYNC_WAIT); }
static bool read_parameters(address_t address) { log_info("read_parameters: starting"); // changed from above for new file format 13-1-2014 key = address[0]; log_info("\tkey = %08x", key); num_neurons = address[1]; neuron_bit_field_words = get_bit_field_size(num_neurons); num_delay_stages = address[2]; uint32_t num_delay_slots = num_delay_stages * DELAY_STAGE_LENGTH; uint32_t num_delay_slots_pot = round_to_next_pot(num_delay_slots); num_delay_slots_mask = (num_delay_slots_pot - 1); log_info("\tparrot neurons = %u, neuron bit field words = %u," " num delay stages = %u, num delay slots = %u (pot = %u)," " num delay slots mask = %08x", num_neurons, neuron_bit_field_words, num_delay_stages, num_delay_slots, num_delay_slots_pot, num_delay_slots_mask); // Create array containing a bitfield specifying whether each neuron should // emit spikes after each delay stage neuron_delay_stage_config = (bit_field_t*) spin1_malloc( num_delay_stages * sizeof(bit_field_t)); // Loop through delay stages for (uint32_t d = 0; d < num_delay_stages; d++) { log_info("\tdelay stage %u", d); // Allocate bit-field neuron_delay_stage_config[d] = (bit_field_t) spin1_malloc( neuron_bit_field_words * sizeof(uint32_t)); // Copy delay stage configuration bits into delay stage configuration bit-field address_t neuron_delay_stage_config_data_address = &address[3] + (d * neuron_bit_field_words); memcpy(neuron_delay_stage_config[d], neuron_delay_stage_config_data_address, neuron_bit_field_words * sizeof(uint32_t)); for (uint32_t w = 0; w < neuron_bit_field_words; w++) { log_debug("\t\tdelay stage config word %u = %08x", w, neuron_delay_stage_config[d][w]); } } // Allocate array of counters for each delay slot spike_counters = (uint8_t**) spin1_malloc( num_delay_slots_pot * sizeof(uint8_t*)); for (uint32_t s = 0; s < num_delay_slots_pot; s++) { // Allocate an array of counters for each neuron and zero spike_counters[s] = (uint8_t*) spin1_malloc( num_neurons * sizeof(uint8_t)); memset(spike_counters[s], 0, num_neurons * sizeof(uint8_t)); } log_info("read_parameters: completed successfully"); return true; }