From b6dab81e618c730dba67f9e5a354b1146deb0999 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Thu, 31 Oct 2019 14:35:40 +0000 Subject: [PATCH 01/66] resolving weight scaling issues for purkinje cells --- .../connectors/from_list_connector.py | 6 +++--- .../neuron/input_types/input_type_conductance.py | 2 +- .../neuron/synapse_io/synapse_io_row_based.py | 3 ++- spynnaker/pyNN/models/neuron/synaptic_manager.py | 16 ++++++++++++---- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py index cc6c9fa53bf..c80bb0b63d3 100644 --- a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py +++ b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py @@ -186,7 +186,7 @@ def get_n_connections_to_post_vertex_maximum(self): @overrides(AbstractConnector.get_weight_mean) def get_weight_mean(self, weights): if self.__weights is None: - return numpy.mean(weights) + return super(FromListConnector, self).get_weight_mean(weights) else: return numpy.mean(numpy.abs(self.__weights)) @@ -194,7 +194,7 @@ def get_weight_mean(self, weights): def get_weight_maximum(self, weights): # pylint: disable=too-many-arguments if self.__weights is None: - return numpy.amax(weights) + return self._get_weight_maximum(weights, len(self.__conn_list)) else: return numpy.amax(numpy.abs(self.__weights)) @@ -202,7 +202,7 @@ def get_weight_maximum(self, weights): def get_weight_variance(self, weights): # pylint: disable=too-many-arguments if self.__weights is None: - return numpy.var(weights) + return super(FromListConnector, self).get_weight_variance(weights) else: return numpy.var(numpy.abs(self.__weights)) diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py index a60bfdeaf6f..4b1723028b9 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py @@ -76,7 +76,7 @@ def update_values(self, values, parameters, state_variables): @overrides(AbstractInputType.get_global_weight_scale) def get_global_weight_scale(self): - return 1024.0 + return float(2**5) @property def e_rev_E(self): diff --git a/spynnaker/pyNN/models/neuron/synapse_io/synapse_io_row_based.py b/spynnaker/pyNN/models/neuron/synapse_io/synapse_io_row_based.py index 6967334f779..55aef75a39f 100644 --- a/spynnaker/pyNN/models/neuron/synapse_io/synapse_io_row_based.py +++ b/spynnaker/pyNN/models/neuron/synapse_io/synapse_io_row_based.py @@ -18,6 +18,7 @@ from six import raise_from from spinn_utilities.overrides import overrides from spinn_front_end_common.utilities.constants import BYTES_PER_WORD +from spynnaker.pyNN.utilities.constants import MAX_SUPPORTED_DELAY_TICS from spynnaker.pyNN.models.neural_projections.connectors import ( AbstractConnector) from spynnaker.pyNN.exceptions import SynapseRowTooBigException @@ -42,7 +43,7 @@ class SynapseIORowBased(AbstractSynapseIO): @overrides(AbstractSynapseIO.get_maximum_delay_supported_in_ms) def get_maximum_delay_supported_in_ms(self, machine_time_step): # There are 16 slots, one per time step - return 16 * (machine_time_step / 1000.0) + return MAX_SUPPORTED_DELAY_TICS * (machine_time_step / 1000.0) @staticmethod def _n_words(n_bytes): diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index d8409637fd0..d0b3fb9e374 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -446,6 +446,7 @@ def _get_ring_buffer_to_input_left_shifts( weights_signed = False rate_stats = [RunningStats() for _ in range(n_synapse_types)] steps_per_second = 1000000.0 / machine_timestep + min_max_weight = numpy.ones(n_synapse_types) * 2 ** 32 for app_edge in application_graph.get_edges_ending_at_vertex( application_vertex): @@ -472,6 +473,8 @@ def _get_ring_buffer_to_input_left_shifts( weight_max = (synapse_dynamics.get_weight_maximum( connector, synapse_info.weight) * weight_scale) + min_max_weight[synapse_type] = \ + min(min_max_weight[synapse_type], weight_max) biggest_weight[synapse_type] = max( biggest_weight[synapse_type], weight_max) @@ -519,23 +522,29 @@ def _get_ring_buffer_to_input_left_shifts( total_weights[synapse_type]) max_weights[synapse_type] = max( max_weights[synapse_type], biggest_weight[synapse_type]) + # This is to deal with very small weights that are floored to 0 + mmw = 2**math.floor(math.log(min_max_weight[synapse_type], 2)) + print("max_weights[", synapse_type, "]", max_weights[synapse_type], + "mmw", mmw) + max_weights[synapse_type] = min(mmw * 2 ** 15, + max_weights[synapse_type]) + # Convert these to powers max_weight_powers = ( - 0 if w <= 0 else int(math.ceil(max(0, math.log(w, 2)))) + 0 if w <= 1 else int(math.ceil(max(0, math.log(w, 2)))) for w in max_weights) # If 2^max_weight_power equals the max weight, we have to add another # power, as range is 0 - (just under 2^max_weight_power)! max_weight_powers = ( - w + 1 if (2 ** w) <= a else w + w + 1 if (2 ** w) < a else w for w, a in zip(max_weight_powers, max_weights)) # If we have synapse dynamics that uses signed weights, # Add another bit of shift to prevent overflows if weights_signed: max_weight_powers = (m + 1 for m in max_weight_powers) - return list(max_weight_powers) @staticmethod @@ -565,7 +574,6 @@ def _write_padding( next_block_allowed_address = self.__poptable_type\ .get_next_allowed_address(next_block_start_address) if next_block_allowed_address != next_block_start_address: - # Pad out data file with the added alignment bytes: spec.comment("\nWriting population table required padding\n") spec.switch_write_focus(synaptic_matrix_region) From a73821e03285aab7397b8c4a7390ec5fee8d4ac2 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Thu, 31 Oct 2019 14:36:17 +0000 Subject: [PATCH 02/66] hardcoded right shift of 5 instead of 10 --- .../src/neuron/input_types/input_type_conductance.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neural_modelling/src/neuron/input_types/input_type_conductance.h b/neural_modelling/src/neuron/input_types/input_type_conductance.h index 4d3577d6dee..59f9d16afb8 100644 --- a/neural_modelling/src/neuron/input_types/input_type_conductance.h +++ b/neural_modelling/src/neuron/input_types/input_type_conductance.h @@ -44,7 +44,7 @@ static inline input_t* input_type_get_input_value( input_t* value, input_type_pointer_t input_type, uint16_t num_receptors) { use(input_type); for (int i = 0; i < num_receptors; i++) { - value[i] = value[i] >> 10; + value[i] = value[i] >> 5; } return &value[0]; } From 7f130258d14c97e8202b22204669725f8a336276 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Wed, 6 Nov 2019 13:02:51 +0000 Subject: [PATCH 03/66] I should probably report weight scaling in a nicer way anyway --- spynnaker/pyNN/models/neuron/synaptic_manager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index d0b3fb9e374..9d281835c10 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -524,8 +524,6 @@ def _get_ring_buffer_to_input_left_shifts( max_weights[synapse_type], biggest_weight[synapse_type]) # This is to deal with very small weights that are floored to 0 mmw = 2**math.floor(math.log(min_max_weight[synapse_type], 2)) - print("max_weights[", synapse_type, "]", max_weights[synapse_type], - "mmw", mmw) max_weights[synapse_type] = min(mmw * 2 ** 15, max_weights[synapse_type]) From 91930158ec066ee6e9a64fbe71c6bcff0f7eb328 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Tue, 26 Nov 2019 10:47:19 +0000 Subject: [PATCH 04/66] syn_info.weight -> weights, better call for weight variance --- .../models/neural_projections/connectors/from_list_connector.py | 2 +- spynnaker/pyNN/models/neuron/synaptic_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py index 0b59b9c9335..ed8a88f65f6 100644 --- a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py +++ b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py @@ -196,7 +196,7 @@ def get_weight_mean(self, weights): def get_weight_maximum(self, synapse_info): # pylint: disable=too-many-arguments if self.__weights is None: - return numpy.amax(synapse_info.weights) + return self._get_weight_maximum(self.__weights, len(self.__conn_list)) else: return numpy.amax(numpy.abs(self.__weights)) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index fec3e80edc8..6fb94380568 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -473,7 +473,7 @@ def _get_ring_buffer_to_input_left_shifts( 0.0, delay_variance, n_connections) weight_max = (synapse_dynamics.get_weight_maximum( - connector, synapse_info.weight) * weight_scale) + connector, synapse_info.weights) * weight_scale) min_max_weight[synapse_type] = \ min(min_max_weight[synapse_type], weight_max) From 15e5a0c929a697c323ea75abbb193ae594b90a27 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Tue, 26 Nov 2019 16:24:43 +0000 Subject: [PATCH 05/66] printing ring buffer left shifts --- spynnaker/pyNN/models/neuron/synaptic_manager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index 6fb94380568..fdea10eb95b 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -529,7 +529,6 @@ def _get_ring_buffer_to_input_left_shifts( max_weights[synapse_type] = min(mmw * 2 ** 15, max_weights[synapse_type]) - # Convert these to powers max_weight_powers = ( 0 if w <= 1 else int(math.ceil(max(0, math.log(w, 2)))) @@ -545,6 +544,10 @@ def _get_ring_buffer_to_input_left_shifts( # Add another bit of shift to prevent overflows if weights_signed: max_weight_powers = (m + 1 for m in max_weight_powers) + print("=" * 60) + print("RB left shifts for {:20}".format(application_vertex.label), + "=", list(max_weight_powers)) + print("-" * 60) return list(max_weight_powers) @staticmethod From cc11b09a972534b5254bdcc0748a8b2253348893 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Tue, 26 Nov 2019 16:29:05 +0000 Subject: [PATCH 06/66] correctly interrogating a GENERATOR --- spynnaker/pyNN/models/neuron/synaptic_manager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index fdea10eb95b..a3764a00012 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -544,11 +544,12 @@ def _get_ring_buffer_to_input_left_shifts( # Add another bit of shift to prevent overflows if weights_signed: max_weight_powers = (m + 1 for m in max_weight_powers) + rb_ls = list(max_weight_powers) print("=" * 60) print("RB left shifts for {:20}".format(application_vertex.label), - "=", list(max_weight_powers)) + "=", rb_ls) print("-" * 60) - return list(max_weight_powers) + return rb_ls @staticmethod def _get_weight_scale(ring_buffer_to_input_left_shift): From a0b095ad3a5a327026dc62684f0edaef6ac8e656 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Thu, 28 Nov 2019 11:38:54 +0000 Subject: [PATCH 07/66] MAX SPIKES PER TICK PROVENANCE --- neural_modelling/src/neuron/c_main.c | 55 +++++++++++++++++++ .../src/neuron/spike_processing.c | 44 +++++++++++++++ .../src/neuron/spike_processing.h | 16 ++++++ .../neuron/population_machine_vertex.py | 52 +++++++++++++++++- 4 files changed, 166 insertions(+), 1 deletion(-) diff --git a/neural_modelling/src/neuron/c_main.c b/neural_modelling/src/neuron/c_main.c index 5263ea535a4..accad1b236a 100644 --- a/neural_modelling/src/neuron/c_main.c +++ b/neural_modelling/src/neuron/c_main.c @@ -41,6 +41,7 @@ #include "plasticity/synapse_dynamics.h" #include "structural_plasticity/synaptogenesis_dynamics.h" #include "profile_tags.h" +#include "spike_profiling.h" #include #include @@ -61,6 +62,11 @@ struct neuron_provenance { uint32_t n_input_buffer_overflows; uint32_t current_timer_tick; uint32_t n_plastic_synaptic_weight_saturations; + uint32_t max_spikes_in_a_tick; + uint32_t max_dmas_in_a_tick; + uint32_t max_pipeline_restarts; + uint32_t timer_callback_completed; + uint32_t spike_pipeline_deactivated; }; //! values for the priority for each callback @@ -73,6 +79,24 @@ typedef enum callback_priorities { // Globals +// Counters to assess maximum spikes per timer tick +uint32_t max_spikes_in_a_tick = 0; +uint32_t max_dmas_in_a_tick = 0; +uint32_t max_pipeline_restarts = 0; + +uint32_t timer_callback_completed = 20000000; +uint32_t temp_timer_callback_completed = 0; +uint32_t spike_pipeline_deactivated = 0; + +uint32_t last_spikes = 0; +uint32_t last_restarts = 0; +uint32_t deactivation_time = 0; + +struct spike_holder_t spike_counter; +struct spike_holder_t spike_cache; +struct spike_holder_t spike_counter_inh; +struct spike_holder_t spike_cache_inh; + //! the current timer tick value //! the timer tick callback returning the same value. uint32_t time; @@ -123,6 +147,11 @@ void c_main_store_provenance_data(address_t provenance_region) { prov->current_timer_tick = time; prov->n_plastic_synaptic_weight_saturations = synapse_dynamics_get_plastic_saturation_count(); + prov->max_spikes_in_a_tick = max_spikes_in_a_tick; + prov->max_dmas_in_a_tick = max_dmas_in_a_tick; + prov->max_pipeline_restarts = max_pipeline_restarts; + prov->timer_callback_completed = timer_callback_completed; + prov->spike_pipeline_deactivated = spike_pipeline_deactivated; log_debug("finished other provenance data"); } @@ -230,6 +259,11 @@ static bool initialise(void) { void resume_callback(void) { recording_reset(); + // reset high water mark for spike counter + max_spikes_in_a_tick = 0; + max_dmas_in_a_tick = 0; + max_pipeline_restarts = 0; + // try reloading neuron parameters data_specification_metadata_t *ds_regions = data_specification_get_data_address(); @@ -248,6 +282,27 @@ void resume_callback(void) { void timer_callback(uint timer_count, uint unused) { use(unused); + // Get number of spikes in last tick, and reset spike counter + last_spikes = spike_processing_get_and_reset_spikes_this_tick(); + uint32_t last_dmas = spike_processing_get_and_reset_dmas_this_tick(); + last_restarts = + spike_processing_get_and_reset_pipeline_restarts_this_tick(); + deactivation_time = spike_processing_get_pipeline_deactivation_time(); + + // cache and flush spike counters + spike_profiling_cache_and_flush_spike_holder(&spike_counter, + &spike_cache); + spike_profiling_cache_and_flush_spike_holder(&spike_counter_inh, + &spike_cache_inh); + + if (last_spikes > max_spikes_in_a_tick){ + max_spikes_in_a_tick = last_spikes; + max_dmas_in_a_tick = last_dmas; + max_pipeline_restarts = last_restarts; + timer_callback_completed = temp_timer_callback_completed; + spike_pipeline_deactivated = deactivation_time; + } + profiler_write_entry_disable_irq_fiq(PROFILER_ENTER | PROFILER_TIMER); time++; diff --git a/neural_modelling/src/neuron/spike_processing.c b/neural_modelling/src/neuron/spike_processing.c index 8181cf53eff..0ba9de6664f 100644 --- a/neural_modelling/src/neuron/spike_processing.c +++ b/neural_modelling/src/neuron/spike_processing.c @@ -80,6 +80,13 @@ static uint32_t dma_n_rewires; static uint32_t dma_n_spikes; +// counter for number of spikes between timer events +uint32_t spikes_this_tick = 0; +uint32_t dmas_this_tick = 0; +uint32_t pipeline_restarts_this_tick = 0; +uint32_t spike_pipeline_deactivation_time = 0; + + /* PRIVATE FUNCTIONS - static for inlining */ static inline void do_dma_read( @@ -234,6 +241,9 @@ static void multicast_packet_received_callback(uint key, uint payload) { use(payload); log_debug("Received spike %x at %d, DMA Busy = %d", key, time, dma_busy); + // Increment the count of number of spikes received this tick by this core + spikes_this_tick++; + // If there was space to add spike to incoming spike queue if (in_spikes_add_spike(key)) { // If we're not already processing synaptic DMAs, @@ -258,6 +268,10 @@ static void dma_complete_callback(uint unused, uint tag) { log_debug("DMA transfer complete at time %u with tag %u", time, tag); + // Increment the counter tracking the number of DMAs completed this + // timestep on a particular core + dmas_this_tick++; + // Get pointer to current buffer uint32_t current_buffer_index = buffer_being_read; dma_buffer *current_buffer = &dma_buffers[current_buffer_index]; @@ -325,6 +339,9 @@ void user_event_callback(uint unused0, uint unused1) { dma_n_rewires = 0; dma_n_spikes = 0; + // Increment counter for spike processing pipeline restarts + pipeline_restarts_this_tick++; + if (buffer_being_read < N_DMA_BUFFERS) { // If the DMA buffer is full of valid data, attempt to reuse it on the // next data to be used, as this might be able to make use of the buffer @@ -412,3 +429,30 @@ bool spike_processing_do_rewiring(int number_of_rewires) { spin1_mode_restore(cpsr); return true; } + +uint32_t spike_processing_get_and_reset_spikes_this_tick(){ + + uint32_t spikes_to_return = spikes_this_tick; + spikes_this_tick = 0; + + return spikes_to_return; +} + +uint32_t spike_processing_get_and_reset_dmas_this_tick(){ + + uint32_t dmas_to_return = dmas_this_tick; + dmas_this_tick = 0; + + return dmas_to_return; +} + +uint32_t spike_processing_get_and_reset_pipeline_restarts_this_tick(){ + uint32_t pipeline_restarts_to_return = pipeline_restarts_this_tick; + pipeline_restarts_this_tick = 0; + + return pipeline_restarts_to_return; +} + +uint32_t spike_processing_get_pipeline_deactivation_time(){ + return spike_pipeline_deactivation_time; +} \ No newline at end of file diff --git a/neural_modelling/src/neuron/spike_processing.h b/neural_modelling/src/neuron/spike_processing.h index 23f5f269182..5d63bfb8f69 100644 --- a/neural_modelling/src/neuron/spike_processing.h +++ b/neural_modelling/src/neuron/spike_processing.h @@ -34,4 +34,20 @@ uint32_t spike_processing_get_buffer_overflows(void); //! \return bool: currently, always true bool spike_processing_do_rewiring(int number_of_rew); +//! \brief get number of spikes received since last timer event +//! \return uint32_t number of spikes +uint32_t spike_processing_get_and_reset_spikes_this_tick(); + +//! \brief get number of dmas completed since last timer event +//! \return uint32_t number of DMAs +uint32_t spike_processing_get_and_reset_dmas_this_tick(); + +//! \brief get number of time pipeline was restarted since last timer event +//! \return uint32_t number of pipeline restarts +uint32_t spike_processing_get_and_reset_pipeline_restarts_this_tick(); + +//! \brief get time from T1 clock at which spike pipeline completed +//! \return uint32_t pipeline deactivation time +uint32_t spike_processing_get_pipeline_deactivation_time(); + #endif // _SPIKE_PROCESSING_H_ diff --git a/spynnaker/pyNN/models/neuron/population_machine_vertex.py b/spynnaker/pyNN/models/neuron/population_machine_vertex.py index 2372339cd5d..4b5350125be 100644 --- a/spynnaker/pyNN/models/neuron/population_machine_vertex.py +++ b/spynnaker/pyNN/models/neuron/population_machine_vertex.py @@ -46,6 +46,11 @@ class EXTRA_PROVENANCE_DATA_ENTRIES(Enum): BUFFER_OVERFLOW_COUNT = 2 CURRENT_TIMER_TIC = 3 PLASTIC_SYNAPTIC_WEIGHT_SATURATION_COUNT = 4 + MAX_SPIKES_IN_A_TICK = 5 + MAX_DMAS_IN_A_TICK = 6 + MAX_PIPELINE_RESTARTS = 7 + TIMER_CALLBACK_COMPLETED = 8 + SPIKES_PIPELINE_ACTIVATED = 9 PROFILE_TAG_LABELS = { 0: "TIMER", @@ -108,7 +113,22 @@ def get_provenance_data_from_machine(self, transceiver, placement): self.EXTRA_PROVENANCE_DATA_ENTRIES.CURRENT_TIMER_TIC.value] n_plastic_saturations = provenance_data[ self.EXTRA_PROVENANCE_DATA_ENTRIES. - PLASTIC_SYNAPTIC_WEIGHT_SATURATION_COUNT.value] + PLASTIC_SYNAPTIC_WEIGHT_SATURATION_COUNT.value] + max_spikes_in_a_tick = provenance_data[ + self.EXTRA_PROVENANCE_DATA_ENTRIES. + MAX_SPIKES_IN_A_TICK.value] + max_dmas_in_a_tick = provenance_data[ + self.EXTRA_PROVENANCE_DATA_ENTRIES. + MAX_DMAS_IN_A_TICK.value] + max_pipeline_restarts = provenance_data[ + self.EXTRA_PROVENANCE_DATA_ENTRIES. + MAX_PIPELINE_RESTARTS.value] + timer_callback_completed = provenance_data[ + self.EXTRA_PROVENANCE_DATA_ENTRIES. + TIMER_CALLBACK_COMPLETED.value] + spike_pipeline_deactivated = provenance_data[ + self.EXTRA_PROVENANCE_DATA_ENTRIES. + SPIKES_PIPELINE_ACTIVATED.value] label, x, y, p, names = self._get_placement_details(placement) @@ -151,6 +171,36 @@ def get_provenance_data_from_machine(self, transceiver, placement): "spikes_per_second and / or ring_buffer_sigma values located " "within the .spynnaker.cfg file.".format( label, x, y, p, n_plastic_saturations)))) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "MAX_SPIKES_IN_A_TICK"), + max_spikes_in_a_tick, + report=max_spikes_in_a_tick > 20, + message=( + "Max number of spikes for {} on {}, {}, {} " + "was {}. Empirically, we can deal with ~20 for real time " + "performance using a 0.1 ms timestep.".format( + label, x, y, p, max_spikes_in_a_tick)))) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "MAX_DMAS_IN_A_TICK"), + max_dmas_in_a_tick)) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "MAX_PIPELINE_RESTARTS"), + max_pipeline_restarts)) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "MAX_PIPELINE_RESTARTS"), + max_pipeline_restarts)) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "TIMER_CALLBACK_COMPLETED"), + timer_callback_completed)) + provenance_items.append(ProvenanceDataItem( + self._add_name(names, + "SPIKES_PIPELINE_ACTIVATED"), + spike_pipeline_deactivated)) return provenance_items From 76313834c9d251a26c4f0b518bfd165ee8c42558 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Thu, 28 Nov 2019 13:28:51 +0000 Subject: [PATCH 08/66] [PROVENANCE] forgot to add spike profiling utility --- neural_modelling/src/neuron/spike_profiling.h | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 neural_modelling/src/neuron/spike_profiling.h diff --git a/neural_modelling/src/neuron/spike_profiling.h b/neural_modelling/src/neuron/spike_profiling.h new file mode 100644 index 00000000000..7b21687caf7 --- /dev/null +++ b/neural_modelling/src/neuron/spike_profiling.h @@ -0,0 +1,79 @@ +#include + +typedef struct spike_holder_t { + uint8_t spikes_a; + uint8_t spikes_b; + uint8_t spikes_c; + uint8_t spikes_d; +} spike_holder_t; + +static inline void spike_profiling_cache_and_flush_spike_holder( + struct spike_holder_t* counter_spikes, + struct spike_holder_t* cache_levels) { + + cache_levels->spikes_a = counter_spikes->spikes_a; + cache_levels->spikes_b = counter_spikes->spikes_b; + cache_levels->spikes_c = counter_spikes->spikes_c; + cache_levels->spikes_d = counter_spikes->spikes_d; + + // zero counters + counter_spikes->spikes_a = 0; + counter_spikes->spikes_b = 0; + counter_spikes->spikes_c = 0; + counter_spikes->spikes_d = 0; +} + +static inline void spike_profiling_add_count(uint32_t row_length, + struct spike_holder_t* spike_counter) { + + uint32_t a = 0; + uint32_t b = 1; + uint32_t c = 5; + + if (row_length <= a) { + spike_counter->spikes_a++; + } else if (row_length > a && row_length <= b) { + spike_counter->spikes_b++; + } else if (row_length > b && row_length <= c) { + spike_counter->spikes_c++; + } else if (row_length > c) { + spike_counter->spikes_d++; + } +} + +static inline int32_t spike_profiling_get_spike_holder_as_int( + struct spike_holder_t spikes) { + + union { + int32_t inty; + struct spike_holder_t sh; + } x; + + x.sh = spikes; + + return x.inty; +} + +static inline accum spike_profiling_get_spike_holder_as_accum( + struct spike_holder_t spikes) { + union { + accum acc; + struct spike_holder_t sh; + } x; + x.sh = spikes; + + return x.acc; +} + +static inline void spike_profiling_print_spikes_from_spike_holder( + struct spike_holder_t spikes_orig) { + io_printf(IO_BUF, "Spikes from input: a %u, b %u, c %u, d %u \n", + spikes_orig.spikes_a, spikes_orig.spikes_b, spikes_orig.spikes_c, + spikes_orig.spikes_d); +} + +static inline void spike_profiling_print_spikes_from_int(int32_t output) { + io_printf(IO_BUF, "Spikes from output: a %d, b %d, c %d, d %d \n", + (output & 0xFF), (output >> 8 & 0xFF), (output >> 16 & 0xFF), + (output >> 24 & 0xFF)); +} From db6084f4e57f5f041f78d620e57f27f63b91548a Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Thu, 28 Nov 2019 14:21:17 +0000 Subject: [PATCH 09/66] passing syn_info instead of weights. That used to work simply because I tested it with FromListConnectors --- .../neural_projections/connectors/from_list_connector.py | 3 ++- spynnaker/pyNN/models/neuron/synaptic_manager.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py index ed8a88f65f6..8dbe2caf5e4 100644 --- a/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py +++ b/spynnaker/pyNN/models/neural_projections/connectors/from_list_connector.py @@ -196,7 +196,8 @@ def get_weight_mean(self, weights): def get_weight_maximum(self, synapse_info): # pylint: disable=too-many-arguments if self.__weights is None: - return self._get_weight_maximum(self.__weights, len(self.__conn_list)) + return self._get_weight_maximum(synapse_info.weights, + len(self.__conn_list)) else: return numpy.amax(numpy.abs(self.__weights)) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index a3764a00012..11243845011 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -473,7 +473,7 @@ def _get_ring_buffer_to_input_left_shifts( 0.0, delay_variance, n_connections) weight_max = (synapse_dynamics.get_weight_maximum( - connector, synapse_info.weights) * weight_scale) + connector, synapse_info) * weight_scale) min_max_weight[synapse_type] = \ min(min_max_weight[synapse_type], weight_max) From 53cc09b01a01a4823e68e25d112154ad5e60347d Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Mon, 9 Dec 2019 13:47:33 +0000 Subject: [PATCH 10/66] I think this is enough to enable 64 delay slots per neuron --- spynnaker/pyNN/utilities/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index fd7ba6ce664..54a92d655a8 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -56,7 +56,7 @@ SCALE = WEIGHT_FLOAT_TO_FIXED_SCALE * NA_TO_PA_SCALE # natively supported delays for all abstract_models -MAX_SUPPORTED_DELAY_TICS = 16 +MAX_SUPPORTED_DELAY_TICS = 64 MAX_DELAY_BLOCKS = 8 MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 From 00fe5bfca5146cda72cbef9d7f6e1333b38436ed Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Wed, 11 Dec 2019 12:42:04 +0000 Subject: [PATCH 11/66] max delay in matrix generator --- .../matrix_generators/matrix_generator_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neural_modelling/src/synapse_expander/matrix_generators/matrix_generator_common.h b/neural_modelling/src/synapse_expander/matrix_generators/matrix_generator_common.h index bcb1efae73b..bee74729d1b 100644 --- a/neural_modelling/src/synapse_expander/matrix_generators/matrix_generator_common.h +++ b/neural_modelling/src/synapse_expander/matrix_generators/matrix_generator_common.h @@ -28,7 +28,7 @@ /** *! \brief The maximum delay value that can be represented on core */ -#define MAX_DELAY 16 +#define MAX_DELAY 64 /** *! \brief A converted final delay value and delay stage From f194f17c702d1980141970b97a6966e1d4f6575d Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Tue, 28 Jan 2020 10:55:29 +0000 Subject: [PATCH 12/66] viridis based visualiser for a pushbot --- .../push_bot/push_bot_parameters/push_bot_retina_viewer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py b/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py index a1a7b364bed..9f0a1d883f0 100644 --- a/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py +++ b/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py @@ -118,7 +118,7 @@ def run(self): # Create image plot of retina output fig = self.__pyplot.figure() self.__image = self.__pyplot.imshow( - self.__image_data_view, cmap="jet", vmin=0.0, + self.__image_data_view, cmap="viridis", vmin=0.0, vmax=self.__display_max) # Play animation From cc809b0ad7535ec7f617ed18ee2613d70e9ef658 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Fri, 7 Feb 2020 09:31:22 +0200 Subject: [PATCH 13/66] initial implementation of if_cond_alpha. Will probably go unused --- .../makefiles/neuron/IF_cond_alpha/Makefile | 26 ++++++++++++++ neural_modelling/makefiles/neuron/Makefile | 3 +- .../models/neuron/builds/if_cond_alpha.py | 34 +++++++++++++++---- 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile diff --git a/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile b/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile new file mode 100644 index 00000000000..45546379d5f --- /dev/null +++ b/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile @@ -0,0 +1,26 @@ +# Copyright (c) 2017-2019 The University of Manchester +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +APP = $(notdir $(CURDIR)) + +NEURON_MODEL = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.c +NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h +INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_conductance.h +NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h +THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h +SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_alpha_impl.h +SYNAPSE_DYNAMICS = $(NEURON_DIR)/neuron/plasticity/synapse_dynamics_static_impl.c + +include ../neural_build.mk diff --git a/neural_modelling/makefiles/neuron/Makefile b/neural_modelling/makefiles/neuron/Makefile index 21b109c02f7..e1f79678358 100644 --- a/neural_modelling/makefiles/neuron/Makefile +++ b/neural_modelling/makefiles/neuron/Makefile @@ -45,7 +45,8 @@ MODELS = IF_curr_exp \ IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight \ IF_curr_exp_sEMD \ IZK_curr_exp_stdp_mad_pair_additive \ - IZK_cond_exp_stdp_mad_pair_additive + IZK_cond_exp_stdp_mad_pair_additive \ + IF_cond_alpha all: for d in $(MODELS); do $(MAKE) -C $$d || exit $$?; done diff --git a/spynnaker/pyNN/models/neuron/builds/if_cond_alpha.py b/spynnaker/pyNN/models/neuron/builds/if_cond_alpha.py index 535d59ce9ae..de9eb29c1ef 100644 --- a/spynnaker/pyNN/models/neuron/builds/if_cond_alpha.py +++ b/spynnaker/pyNN/models/neuron/builds/if_cond_alpha.py @@ -13,21 +13,43 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from spynnaker.pyNN.exceptions import SpynnakerException +from spynnaker.pyNN.models.neuron import AbstractPyNNNeuronModelStandard from spynnaker.pyNN.models.defaults import defaults, default_initial_values +from spynnaker.pyNN.models.neuron.neuron_models import ( + NeuronModelLeakyIntegrateAndFire) +from spynnaker.pyNN.models.neuron.synapse_types import SynapseTypeAlpha +from spynnaker.pyNN.models.neuron.input_types import InputTypeConductance +from spynnaker.pyNN.models.neuron.threshold_types import ThresholdTypeStatic @defaults -class IFCondAlpha(object): +class IFCondAlpha(AbstractPyNNNeuronModelStandard): """ Leaky integrate and fire neuron with an alpha-shaped current input. """ # noinspection PyPep8Naming - @default_initial_values({"v", "gsyn_exc", "gsyn_inh"}) + @default_initial_values({"v", "exc_response", + "exc_exp_response", "inh_response", + "inh_exp_response"}) def __init__( self, tau_m=20, cm=1.0, e_rev_E=0.0, e_rev_I=-70.0, v_rest=-65.0, v_reset=-65.0, v_thresh=-50.0, tau_syn_E=0.3, tau_syn_I=0.5, - tau_refrac=0.1, i_offset=0, v=-65.0, gsyn_exc=0.0, gsyn_inh=0.0): + tau_refrac=0.1, i_offset=0, v=-65.0, + exc_response=0.0, exc_exp_response=0.0, inh_response=0.0, + inh_exp_response=0.0): # pylint: disable=too-many-arguments, too-many-locals, unused-argument - raise SpynnakerException( - "This neuron model is currently not supported by the tool chain") + neuron_model = NeuronModelLeakyIntegrateAndFire( + v, v_rest, tau_m, cm, i_offset, v_reset, tau_refrac) + + synapse_type = SynapseTypeAlpha( + exc_response=exc_response, exc_exp_response=exc_exp_response, + tau_syn_E=tau_syn_E, inh_response=inh_response, + inh_exp_response=inh_exp_response, tau_syn_I=tau_syn_I) + + input_type = InputTypeConductance(e_rev_E, e_rev_I) + threshold_type = ThresholdTypeStatic(v_thresh) + + super(IFCondAlpha, self).__init__( + model_name="IF_cond_alpha", binary="IF_cond_alpha.aplx", + neuron_model=neuron_model, input_type=input_type, + synapse_type=synapse_type, threshold_type=threshold_type) From afecd18ae2eefd528dd63d61a6e284508f2a1d13 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Thu, 27 Feb 2020 15:58:01 +0000 Subject: [PATCH 14/66] correct reporting of max possible delays --- spynnaker/pyNN/abstract_spinnaker_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spynnaker/pyNN/abstract_spinnaker_common.py b/spynnaker/pyNN/abstract_spinnaker_common.py index bc6ed2c10db..b3a02a86b1b 100644 --- a/spynnaker/pyNN/abstract_spinnaker_common.py +++ b/spynnaker/pyNN/abstract_spinnaker_common.py @@ -196,7 +196,7 @@ def _set_up_timings( raise ConfigurationException( "Pacman does not support max delays above {} ms with the " "current machine time step".format( - 0.144 * machine_time_step)) + max_delay_tics_supported * machine_time_step / 1000.0)) if max_delay is not None: self.__max_delay = max_delay else: From e9467bb753689eb87ae108e43347cd32904d0e44 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Thu, 27 Feb 2020 16:33:40 +0000 Subject: [PATCH 15/66] setting delay extensions to have more delay slots. NEEDS TESTING --- neural_modelling/src/delay_extension/delay_extension.h | 2 +- spynnaker/pyNN/utilities/constants.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/neural_modelling/src/delay_extension/delay_extension.h b/neural_modelling/src/delay_extension/delay_extension.h index a5d9552ed07..3d201192dc3 100644 --- a/neural_modelling/src/delay_extension/delay_extension.h +++ b/neural_modelling/src/delay_extension/delay_extension.h @@ -21,7 +21,7 @@ #include // Constants -#define DELAY_STAGE_LENGTH 16 +#define DELAY_STAGE_LENGTH 64 //! region identifiers typedef enum region_identifiers { diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index 54a92d655a8..78fe19a909c 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -57,8 +57,8 @@ # natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 -MAX_DELAY_BLOCKS = 8 -MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 +MAX_DELAY_BLOCKS = 16 +MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 64 # the minimum supported delay slot between two neurons MIN_SUPPORTED_DELAY = 1 From 888f659520a5c3f7e244828e7ac3b098832bf19d Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Fri, 28 Feb 2020 16:09:39 +0000 Subject: [PATCH 16/66] tested and fixed delay extension with more delay slots. --- neural_modelling/src/delay_extension/delay_extension.c | 1 + spynnaker/pyNN/utilities/constants.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/neural_modelling/src/delay_extension/delay_extension.c b/neural_modelling/src/delay_extension/delay_extension.c index 8c2fd35608d..827d3c4989a 100644 --- a/neural_modelling/src/delay_extension/delay_extension.c +++ b/neural_modelling/src/delay_extension/delay_extension.c @@ -371,6 +371,7 @@ void c_main(void) { // Initialise the incoming spike buffer if (!in_spikes_initialize_spike_buffer(256)) { + log_error("Error in initialisation of spike buffer!"); rt_error(RTE_SWERR); } diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index 78fe19a909c..18361022186 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -57,8 +57,8 @@ # natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 -MAX_DELAY_BLOCKS = 16 -MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 64 +MAX_DELAY_BLOCKS = 64 +MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 # the minimum supported delay slot between two neurons MIN_SUPPORTED_DELAY = 1 From 7cc3a28d97a1fe9c8206bc0afcdf28f2558f46b9 Mon Sep 17 00:00:00 2001 From: Petrut Antoniu Bogdan Date: Fri, 6 Mar 2020 14:50:44 +0000 Subject: [PATCH 17/66] added support for setting RB left shift values --- .../pyNN/models/neuron/synaptic_manager.py | 19 ++++++++++++------- .../pyNN/models/pynn_population_common.py | 8 ++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index 11243845011..03ef9aa89b6 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -545,10 +545,6 @@ def _get_ring_buffer_to_input_left_shifts( if weights_signed: max_weight_powers = (m + 1 for m in max_weight_powers) rb_ls = list(max_weight_powers) - print("=" * 60) - print("RB left shifts for {:20}".format(application_vertex.label), - "=", rb_ls) - print("-" * 60) return rb_ls @staticmethod @@ -975,9 +971,18 @@ def write_data_spec( all_syn_block_sz, graph_mapper, application_graph, application_vertex) - ring_buffer_shifts = self._get_ring_buffer_shifts( - application_vertex, application_graph, machine_time_step, - weight_scale) + print("=" * 80) + if hasattr(application_vertex, "rb_left_shifts"): + print("Using given values for RB left shifts.") + ring_buffer_shifts = application_vertex.rb_left_shifts + else: + print("Computing values for RB left shifts...") + ring_buffer_shifts = self._get_ring_buffer_shifts( + application_vertex, application_graph, machine_time_step, + weight_scale) + print("RB left shifts for {:20}".format(application_vertex.label), + "=", ring_buffer_shifts) + print("-" * 80) weight_scales = self._write_synapse_parameters( spec, ring_buffer_shifts, weight_scale) diff --git a/spynnaker/pyNN/models/pynn_population_common.py b/spynnaker/pyNN/models/pynn_population_common.py index c9cdd7c63c5..539388becf6 100644 --- a/spynnaker/pyNN/models/pynn_population_common.py +++ b/spynnaker/pyNN/models/pynn_population_common.py @@ -74,10 +74,18 @@ def __init__( raise ConfigurationException( "A population cannot have a negative or zero size.") population_parameters = dict(model.default_population_parameters) + + if "rb_left_shifts" in additional_parameters.keys(): + rb_left_shifts = additional_parameters['rb_left_shifts'] + del additional_parameters['rb_left_shifts'] + else: + rb_left_shifts = None if additional_parameters is not None: population_parameters.update(additional_parameters) self.__vertex = model.create_vertex( size, label, constraints, **population_parameters) + if rb_left_shifts: + self.__vertex.rb_left_shifts = rb_left_shifts # Use a provided application vertex directly elif isinstance(model, ApplicationVertex): From 70541be6ae180b8b491968027c4520613d174177 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Fri, 6 Mar 2020 15:38:07 +0000 Subject: [PATCH 18/66] much better handling of rb values --- .../pyNN/models/neuron/synaptic_manager.py | 27 ++++++++++--------- .../pyNN/models/pynn_population_common.py | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synaptic_manager.py b/spynnaker/pyNN/models/neuron/synaptic_manager.py index 03ef9aa89b6..a3580cbf9a4 100644 --- a/spynnaker/pyNN/models/neuron/synaptic_manager.py +++ b/spynnaker/pyNN/models/neuron/synaptic_manager.py @@ -936,11 +936,23 @@ def _get_ring_buffer_shifts( weight_scale): """ Get the ring buffer shifts for this vertex """ + if (self.__ring_buffer_shifts is None and + hasattr(application_vertex, "rb_left_shifts")): + print("=" * 80) + print("Using given values for RB left shifts.") + self.__ring_buffer_shifts = application_vertex.rb_left_shifts + print("RB left shifts for {:20}".format(application_vertex.label), + "=", self.__ring_buffer_shifts) + print("-" * 80) if self.__ring_buffer_shifts is None: + print("=" * 80) + print("Computing values for RB left shifts...") self.__ring_buffer_shifts = \ self._get_ring_buffer_to_input_left_shifts( application_vertex, application_graph, machine_timestep, weight_scale) + print("RB left shifts for {:20}".format(application_vertex.label), + "=", self.__ring_buffer_shifts) return self.__ring_buffer_shifts def write_data_spec( @@ -971,18 +983,9 @@ def write_data_spec( all_syn_block_sz, graph_mapper, application_graph, application_vertex) - print("=" * 80) - if hasattr(application_vertex, "rb_left_shifts"): - print("Using given values for RB left shifts.") - ring_buffer_shifts = application_vertex.rb_left_shifts - else: - print("Computing values for RB left shifts...") - ring_buffer_shifts = self._get_ring_buffer_shifts( - application_vertex, application_graph, machine_time_step, - weight_scale) - print("RB left shifts for {:20}".format(application_vertex.label), - "=", ring_buffer_shifts) - print("-" * 80) + ring_buffer_shifts = self._get_ring_buffer_shifts( + application_vertex, application_graph, machine_time_step, + weight_scale) weight_scales = self._write_synapse_parameters( spec, ring_buffer_shifts, weight_scale) diff --git a/spynnaker/pyNN/models/pynn_population_common.py b/spynnaker/pyNN/models/pynn_population_common.py index 539388becf6..b43ecaae708 100644 --- a/spynnaker/pyNN/models/pynn_population_common.py +++ b/spynnaker/pyNN/models/pynn_population_common.py @@ -84,7 +84,7 @@ def __init__( population_parameters.update(additional_parameters) self.__vertex = model.create_vertex( size, label, constraints, **population_parameters) - if rb_left_shifts: + if rb_left_shifts is not None: self.__vertex.rb_left_shifts = rb_left_shifts # Use a provided application vertex directly From c7c70b35d47e00c75bd47edca29d36c59b06cb94 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Mon, 9 Mar 2020 16:32:08 +0000 Subject: [PATCH 19/66] added check for additional_params being none --- spynnaker/pyNN/models/pynn_population_common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/pynn_population_common.py b/spynnaker/pyNN/models/pynn_population_common.py index b43ecaae708..6fbc0545113 100644 --- a/spynnaker/pyNN/models/pynn_population_common.py +++ b/spynnaker/pyNN/models/pynn_population_common.py @@ -75,7 +75,8 @@ def __init__( "A population cannot have a negative or zero size.") population_parameters = dict(model.default_population_parameters) - if "rb_left_shifts" in additional_parameters.keys(): + if (additional_parameters is not None and + "rb_left_shifts" in additional_parameters.keys()): rb_left_shifts = additional_parameters['rb_left_shifts'] del additional_parameters['rb_left_shifts'] else: From 897bb87f84c520476924d2ff828f9c516010e4c3 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Fri, 13 Mar 2020 15:56:16 +0000 Subject: [PATCH 20/66] delays now work correctly --- neural_modelling/src/neuron/synapse_row.h | 2 +- .../neuron/synapse_dynamics/synapse_dynamics_static.py | 5 +++-- spynnaker/pyNN/utilities/constants.py | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/neural_modelling/src/neuron/synapse_row.h b/neural_modelling/src/neuron/synapse_row.h index 3f7ac4c103d..40b80bbb512 100644 --- a/neural_modelling/src/neuron/synapse_row.h +++ b/neural_modelling/src/neuron/synapse_row.h @@ -51,7 +51,7 @@ //! how many bits the synapse delay will take #ifndef SYNAPSE_DELAY_BITS -#define SYNAPSE_DELAY_BITS 4 +#define SYNAPSE_DELAY_BITS 6 #endif // Create some masks based on the number of bits diff --git a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py index 3a49768d24c..398d49f0fb7 100644 --- a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py +++ b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py @@ -22,6 +22,7 @@ AbstractGenerateOnMachine, MatrixGeneratorID) from spynnaker.pyNN.exceptions import InvalidParameterType from spynnaker.pyNN.utilities.utility_calls import get_n_bits +from spynnaker.pyNN.utilities.constants import DELAY_MASK class SynapseDynamicsStatic( @@ -91,7 +92,7 @@ def get_static_synaptic_data( fixed_fixed = ( ((numpy.rint(numpy.abs(connections["weight"])).astype("uint32") & 0xFFFF) << 16) | - ((connections["delay"].astype("uint32") & 0xF) << + ((connections["delay"].astype("uint32") & DELAY_MASK) << (n_neuron_id_bits + n_synapse_type_bits)) | (connections["synapse_type"].astype( "uint32") << n_neuron_id_bits) | @@ -148,7 +149,7 @@ def read_static_synaptic_data( (data & neuron_id_mask) + post_vertex_slice.lo_atom) connections["weight"] = (data >> 16) & 0xFFFF connections["delay"] = (data >> (n_neuron_id_bits + - n_synapse_type_bits)) & 0xF + n_synapse_type_bits)) & DELAY_MASK connections["delay"][connections["delay"] == 0] = 16 return connections diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index 18361022186..70166a79ec2 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -14,6 +14,7 @@ # along with this program. If not, see . from enum import Enum +import math from spinn_front_end_common.utilities.constants import ( BYTES_PER_WORD, BYTES_PER_KB) @@ -58,6 +59,7 @@ # natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 MAX_DELAY_BLOCKS = 64 +DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) -1 MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 # the minimum supported delay slot between two neurons From 648a941397c99edb52157647993a6f1001b12d8e Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Thu, 23 Apr 2020 15:28:37 +0100 Subject: [PATCH 21/66] Bring in changes to make the models work with multiple steps per ts --- .../implementations/neuron_impl_standard.h | 166 ++++++++++-------- .../external_device_lif_control.py | 4 +- ...threshold_type_multicast_device_control.py | 2 +- .../abstract_pynn_neuron_model_standard.py | 17 ++ .../additional_input_ca2_adaptive.py | 4 +- .../abstract_standard_neuron_component.py | 2 +- .../implementations/neuron_impl_standard.py | 37 +++- .../input_types/input_type_conductance.py | 2 +- .../neuron/input_types/input_type_current.py | 2 +- .../input_types/input_type_current_semd.py | 2 +- .../neuron_models/abstract_neuron_model.py | 8 +- .../neuron/neuron_models/neuron_model_izh.py | 12 +- .../neuron_model_leaky_integrate_and_fire.py | 4 +- .../synapse_types/synapse_type_alpha.py | 4 +- .../synapse_types/synapse_type_delta.py | 2 +- .../synapse_type_dual_exponential.py | 4 +- .../synapse_types/synapse_type_exponential.py | 4 +- .../neuron/synapse_types/synapse_type_semd.py | 4 +- .../threshold_type_maass_stochastic.py | 4 +- .../threshold_types/threshold_type_static.py | 2 +- unittests/test_populations/test_vertex.py | 4 +- 21 files changed, 166 insertions(+), 124 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index 90662fcbe34..c225005566b 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -39,13 +39,13 @@ #ifndef NUM_EXCITATORY_RECEPTORS #define NUM_EXCITATORY_RECEPTORS 1 #error NUM_EXCITATORY_RECEPTORS was undefined. It should be defined by a synapse\ - shaping include + shaping include #endif #ifndef NUM_INHIBITORY_RECEPTORS #define NUM_INHIBITORY_RECEPTORS 1 #error NUM_INHIBITORY_RECEPTORS was undefined. It should be defined by a synapse\ - shaping include + shaping include #endif //! Array of neuron states @@ -66,6 +66,9 @@ static global_neuron_params_pointer_t global_parameters; // The synapse shaping parameters static synapse_param_t *neuron_synapse_shaping_params; +// The number of steps to run per timestep +static uint n_steps_per_timestep; + static bool neuron_impl_initialise(uint32_t n_neurons) { // allocate DTCM for the global parameter details if (sizeof(global_neuron_params_t)) { @@ -149,6 +152,11 @@ static void neuron_impl_load_neuron_parameters( log_debug("reading parameters, next is %u, n_neurons is %u ", next, n_neurons); + // Read the number of steps per timestep + n_steps_per_timestep = address[next]; + log_info("Looping over %u steps each timestep", n_steps_per_timestep); + next += 1; + if (sizeof(global_neuron_params_t)) { log_debug("writing neuron global parameters"); spin1_memcpy(global_parameters, &address[next], @@ -222,61 +230,71 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, state_t voltage = neuron_model_get_membrane_voltage(neuron); recorded_variable_values[V_RECORDING_INDEX] = voltage; - // Get the exc and inh values from the synapses - input_t* exc_value = synapse_types_get_excitatory_input(synapse_type); - input_t* inh_value = synapse_types_get_inhibitory_input(synapse_type); + // Store whether the neuron has spiked + bool spike = false; - // Call functions to obtain exc_input and inh_input - input_t* exc_input_values = input_type_get_input_value( - exc_value, input_type, NUM_EXCITATORY_RECEPTORS); - input_t* inh_input_values = input_type_get_input_value( - inh_value, input_type, NUM_INHIBITORY_RECEPTORS); + // Loop however many times requested + for (uint32_t i = n_steps_per_timestep; i > 0; i--) { - // Sum g_syn contributions from all receptors for recording - REAL total_exc = 0; - REAL total_inh = 0; + // Get the exc and inh values from the synapses + input_t* exc_value = synapse_types_get_excitatory_input(synapse_type); + input_t* inh_value = synapse_types_get_inhibitory_input(synapse_type); - for (int i = 0; i < NUM_EXCITATORY_RECEPTORS; i++) { - total_exc += exc_input_values[i]; - } - for (int i = 0; i < NUM_INHIBITORY_RECEPTORS; i++) { - total_inh += inh_input_values[i]; - } + // Call functions to obtain exc_input and inh_input + input_t* exc_input_values = input_type_get_input_value( + exc_value, input_type, NUM_EXCITATORY_RECEPTORS); + input_t* inh_input_values = input_type_get_input_value( + inh_value, input_type, NUM_INHIBITORY_RECEPTORS); + + // Sum g_syn contributions from all receptors for recording + REAL total_exc = 0; + REAL total_inh = 0; - // Call functions to get the input values to be recorded - recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; - recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; + for (int i = 0; i < NUM_EXCITATORY_RECEPTORS; i++) { + total_exc += exc_input_values[i]; + } + for (int i = 0; i < NUM_INHIBITORY_RECEPTORS; i++) { + total_inh += inh_input_values[i]; + } - // Call functions to convert exc_input and inh_input to current - input_type_convert_excitatory_input_to_current( - exc_input_values, input_type, voltage); - input_type_convert_inhibitory_input_to_current( - inh_input_values, input_type, voltage); + // Call functions to get the input values to be recorded + recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; + recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; - external_bias += additional_input_get_input_value_as_current( - additional_input, voltage); + // Call functions to convert exc_input and inh_input to current + voltage = neuron_model_get_membrane_voltage(neuron); + input_type_convert_excitatory_input_to_current( + exc_input_values, input_type, voltage); + input_type_convert_inhibitory_input_to_current( + inh_input_values, input_type, voltage); - // update neuron parameters - state_t result = neuron_model_state_update( - NUM_EXCITATORY_RECEPTORS, exc_input_values, - NUM_INHIBITORY_RECEPTORS, inh_input_values, - external_bias, neuron); + external_bias += additional_input_get_input_value_as_current( + additional_input, voltage); - // determine if a spike should occur - bool spike = threshold_type_is_above_threshold(result, threshold_type); + // update neuron parameters + state_t result = neuron_model_state_update( + NUM_EXCITATORY_RECEPTORS, exc_input_values, + NUM_INHIBITORY_RECEPTORS, inh_input_values, + external_bias, neuron); - // If spike occurs, communicate to relevant parts of model - if (spike) { - // Call relevant model-based functions - // Tell the neuron model - neuron_model_has_spiked(neuron); + // determine if a spike should occur + bool spike_now = threshold_type_is_above_threshold(result, threshold_type); - // Tell the additional input - additional_input_has_spiked(additional_input); - } + // If spike occurs, communicate to relevant parts of model + if (spike_now) { + spike = true; + + // Call relevant model-based functions + // Tell the neuron model + neuron_model_has_spiked(neuron); + + // Tell the additional input + additional_input_has_spiked(additional_input); + } - // Shape the existing input according to the included rule - synapse_types_shape_input(synapse_type); + // Shape the existing input according to the included rule + synapse_types_shape_input(synapse_type); + } #if LOG_LEVEL >= LOG_DEBUG neuron_model_print_state_variables(neuron); @@ -342,40 +360,40 @@ static void neuron_impl_store_neuron_parameters( #if LOG_LEVEL >= LOG_DEBUG void neuron_impl_print_inputs(uint32_t n_neurons) { - bool empty = true; - for (index_t i = 0; i < n_neurons; i++) { - empty = empty && (0 == bitsk( - synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) - - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]))); - } - - if (!empty) { - log_debug("-------------------------------------\n"); - - for (index_t i = 0; i < n_neurons; i++) { - input_t input = - synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) - - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]); - if (bitsk(input) != 0) { - log_debug("%3u: %12.6k (= ", i, input); - synapse_types_print_input(&neuron_synapse_shaping_params[i]); - log_debug(")\n"); - } - } - log_debug("-------------------------------------\n"); - } + bool empty = true; + for (index_t i = 0; i < n_neurons; i++) { + empty = empty && (0 == bitsk( + synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) + - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]))); + } + + if (!empty) { + log_debug("-------------------------------------\n"); + + for (index_t i = 0; i < n_neurons; i++) { + input_t input = + synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) + - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]); + if (bitsk(input) != 0) { + log_debug("%3u: %12.6k (= ", i, input); + synapse_types_print_input(&neuron_synapse_shaping_params[i]); + log_debug(")\n"); + } + } + log_debug("-------------------------------------\n"); + } } void neuron_impl_print_synapse_parameters(uint32_t n_neurons) { - log_debug("-------------------------------------\n"); - for (index_t n = 0; n < n_neurons; n++) { - synapse_types_print_parameters(&neuron_synapse_shaping_params[n]); - } - log_debug("-------------------------------------\n"); + log_debug("-------------------------------------\n"); + for (index_t n = 0; n < n_neurons; n++) { + synapse_types_print_parameters(&neuron_synapse_shaping_params[n]); + } + log_debug("-------------------------------------\n"); } const char *neuron_impl_get_synapse_type_char(uint32_t synapse_type) { - return synapse_types_get_type_char(synapse_type); + return synapse_types_get_type_char(synapse_type); } #endif // LOG_LEVEL >= LOG_DEBUG diff --git a/spynnaker/pyNN/external_devices_models/external_device_lif_control.py b/spynnaker/pyNN/external_devices_models/external_device_lif_control.py index 21ed3f43dad..e5c89815e47 100644 --- a/spynnaker/pyNN/external_devices_models/external_device_lif_control.py +++ b/spynnaker/pyNN/external_devices_models/external_device_lif_control.py @@ -87,11 +87,13 @@ def __init__( @overrides(AbstractPyNNNeuronModelStandard.create_vertex) def create_vertex( self, n_neurons, label, constraints, spikes_per_second, - ring_buffer_sigma, incoming_spike_buffer_size): + ring_buffer_sigma, incoming_spike_buffer_size, + n_steps_per_timestep): if n_neurons != len(self._devices): raise ConfigurationException( "Number of neurons does not match number of devices in {}" .format(label)) + self._model.n_steps_per_timestep = n_steps_per_timestep max_atoms = self.get_max_atoms_per_core() return ExternalDeviceLifControlVertex( self._devices, self._create_edges, max_atoms, self._model, self, diff --git a/spynnaker/pyNN/external_devices_models/threshold_type_multicast_device_control.py b/spynnaker/pyNN/external_devices_models/threshold_type_multicast_device_control.py index bc400ef7d9a..5baba1880df 100644 --- a/spynnaker/pyNN/external_devices_models/threshold_type_multicast_device_control.py +++ b/spynnaker/pyNN/external_devices_models/threshold_type_multicast_device_control.py @@ -64,7 +64,7 @@ def has_variable(self, variable): return variable in UNITS @overrides(AbstractThresholdType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [parameters[DEVICE].apply_operation( diff --git a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py index 3d422de7867..f238703522c 100644 --- a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py +++ b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py @@ -15,14 +15,31 @@ from .abstract_pynn_neuron_model import AbstractPyNNNeuronModel from spynnaker.pyNN.models.neuron.implementations import NeuronImplStandard +from spinn_utilities.overrides import overrides +_population_parameters = AbstractPyNNNeuronModel.default_population_parameters +_population_parameters["n_steps_per_timestep"] = 1 class AbstractPyNNNeuronModelStandard(AbstractPyNNNeuronModel): __slots__ = [] + default_population_parameters = _population_parameters + def __init__( self, model_name, binary, neuron_model, input_type, synapse_type, threshold_type, additional_input_type=None): AbstractPyNNNeuronModel.__init__(self, NeuronImplStandard( model_name, binary, neuron_model, input_type, synapse_type, threshold_type, additional_input_type)) + + @overrides(AbstractPyNNNeuronModel.create_vertex, + additional_arguments={"n_steps_per_timestep"}) + def create_vertex( + self, n_neurons, label, constraints, spikes_per_second, + ring_buffer_sigma, incoming_spike_buffer_size, + n_steps_per_timestep): + # pylint: disable=arguments-differ + self._model.n_steps_per_timestep = n_steps_per_timestep + return super(AbstractPyNNNeuronModelStandard, self).create_vertex( + n_neurons, label, constraints, spikes_per_second, + ring_buffer_sigma, incoming_spike_buffer_size) diff --git a/spynnaker/pyNN/models/neuron/additional_inputs/additional_input_ca2_adaptive.py b/spynnaker/pyNN/models/neuron/additional_inputs/additional_input_ca2_adaptive.py index bc8b41aa621..05651418a15 100644 --- a/spynnaker/pyNN/models/neuron/additional_inputs/additional_input_ca2_adaptive.py +++ b/spynnaker/pyNN/models/neuron/additional_inputs/additional_input_ca2_adaptive.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_additional_input import AbstractAdditionalInput I_ALPHA = "i_alpha" @@ -67,8 +66,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractAdditionalInput.get_values, additional_arguments={'ts'}) + @overrides(AbstractAdditionalInput.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py b/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py index 623716d8fd5..98bcb0fa6d1 100644 --- a/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py +++ b/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py @@ -90,7 +90,7 @@ def add_state_variables(self, state_variables): """ @abstractmethod - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): """ Get the values to be written to the machine for this model :param parameters: The holder of the parameters diff --git a/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py b/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py index 3c0344ad826..8efd730ef44 100644 --- a/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py +++ b/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py @@ -17,6 +17,13 @@ from spinn_utilities.overrides import overrides from spynnaker.pyNN.models.neuron.input_types import InputTypeConductance from .abstract_neuron_impl import AbstractNeuronImpl +from spinn_front_end_common.utilities import globals_variables + +# The base size of the data +_BASE_SIZE = 4 + +# The default number of steps per timestep +_DEFAULT_N_STEPS_PER_TIMESTEP = 1 class NeuronImplStandard(AbstractNeuronImpl): @@ -31,7 +38,8 @@ class NeuronImplStandard(AbstractNeuronImpl): "__synapse_type", "__threshold_type", "__additional_input_type", - "__components" + "__components", + "__n_steps_per_timestep" ] _RECORDABLES = ["v", "gsyn_exc", "gsyn_inh"] @@ -52,6 +60,7 @@ def __init__( self.__synapse_type = synapse_type self.__threshold_type = threshold_type self.__additional_input_type = additional_input_type + self.__n_steps_per_timestep = _DEFAULT_N_STEPS_PER_TIMESTEP self.__components = [ self.__neuron_model, self.__input_type, self.__threshold_type, @@ -59,6 +68,14 @@ def __init__( if self.__additional_input_type is not None: self.__components.append(self.__additional_input_type) + @property + def n_steps_per_timestep(self): + return self.__n_steps_per_timestep + + @n_steps_per_timestep.setter + def n_steps_per_timestep(self, n_steps_per_timestep): + self.__n_steps_per_timestep = n_steps_per_timestep + @property @overrides(AbstractNeuronImpl.model_name) def model_name(self): @@ -81,7 +98,8 @@ def get_n_cpu_cycles(self, n_neurons): @overrides(AbstractNeuronImpl.get_dtcm_usage_in_bytes) def get_dtcm_usage_in_bytes(self, n_neurons): - total = self.__neuron_model.get_dtcm_usage_in_bytes(n_neurons) + total = _BASE_SIZE + total += self.__neuron_model.get_dtcm_usage_in_bytes(n_neurons) total += self.__synapse_type.get_dtcm_usage_in_bytes(n_neurons) total += self.__input_type.get_dtcm_usage_in_bytes(n_neurons) total += self.__threshold_type.get_dtcm_usage_in_bytes(n_neurons) @@ -92,7 +110,8 @@ def get_dtcm_usage_in_bytes(self, n_neurons): @overrides(AbstractNeuronImpl.get_sdram_usage_in_bytes) def get_sdram_usage_in_bytes(self, n_neurons): - total = self.__neuron_model.get_sdram_usage_in_bytes(n_neurons) + total = _BASE_SIZE + total += self.__neuron_model.get_sdram_usage_in_bytes(n_neurons) total += self.__synapse_type.get_sdram_usage_in_bytes(n_neurons) total += self.__input_type.get_sdram_usage_in_bytes(n_neurons) total += self.__threshold_type.get_sdram_usage_in_bytes(n_neurons) @@ -145,10 +164,14 @@ def add_state_variables(self, state_variables): @overrides(AbstractNeuronImpl.get_data) def get_data(self, parameters, state_variables, vertex_slice): - return numpy.concatenate([ - component.get_data(parameters, state_variables, vertex_slice) - for component in self.__components - ]) + # Work out the time step per step + ts = globals_variables.get_simulator().machine_time_step + ts /= self.__n_steps_per_timestep + items = [numpy.array([self.__n_steps_per_timestep], dtype="uint32")] + items.extend( + component.get_data(parameters, state_variables, vertex_slice, ts) + for component in self.__components) + return numpy.concatenate(items) @overrides(AbstractNeuronImpl.read_data) def read_data( diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py index 4b1723028b9..d2d0827b3ef 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py @@ -63,7 +63,7 @@ def has_variable(self, variable): return variable in UNITS @overrides(AbstractInputType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [parameters[E_REV_E], parameters[E_REV_I]] diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_current.py b/spynnaker/pyNN/models/neuron/input_types/input_type_current.py index 354c5f7d1ad..a18ef9abef1 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_current.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_current.py @@ -38,7 +38,7 @@ def add_state_variables(self, state_variables): pass @overrides(AbstractInputType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): return [] @overrides(AbstractInputType.update_values) diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_current_semd.py b/spynnaker/pyNN/models/neuron/input_types/input_type_current_semd.py index 00f14bb97b7..76a4e7b1ea9 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_current_semd.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_current_semd.py @@ -62,7 +62,7 @@ def has_variable(self, variable): return variable in UNITS @overrides(AbstractInputType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [parameters[MULTIPLICATOR], state_variables[INH_INPUT_PREVIOUS]] diff --git a/spynnaker/pyNN/models/neuron/neuron_models/abstract_neuron_model.py b/spynnaker/pyNN/models/neuron/neuron_models/abstract_neuron_model.py index aae4f85dcd5..72f24c79cfd 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/abstract_neuron_model.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/abstract_neuron_model.py @@ -60,7 +60,7 @@ def get_sdram_usage_in_bytes(self, n_neurons): return usage + (self.__global_struct.get_size_in_whole_words() * BYTES_PER_WORD) - def get_global_values(self): + def get_global_values(self, ts): """ Get the global values to be written to the machine for this model :return: A list with the same length as self.global_struct.field_types @@ -69,10 +69,10 @@ def get_global_values(self): return numpy.zeros(0, dtype="uint32") @overrides(AbstractStandardNeuronComponent.get_data) - def get_data(self, parameters, state_variables, vertex_slice): + def get_data(self, parameters, state_variables, vertex_slice, ts): super_data = super(AbstractNeuronModel, self).get_data( - parameters, state_variables, vertex_slice) - values = self.get_global_values() + parameters, state_variables, vertex_slice, ts) + values = self.get_global_values(ts) global_data = self.__global_struct.get_data(values) return numpy.concatenate([global_data, super_data]) diff --git a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_izh.py b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_izh.py index e715e3661bb..64a2189727a 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_izh.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_izh.py @@ -15,7 +15,6 @@ from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_neuron_model import AbstractNeuronModel A = 'a' @@ -87,15 +86,12 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"machine_time_step": "MachineTimeStep"}) - @overrides(AbstractNeuronModel.get_global_values, - additional_arguments={'machine_time_step'}) - def get_global_values(self, machine_time_step): + @overrides(AbstractNeuronModel.get_global_values) + def get_global_values(self, ts): # pylint: disable=arguments-differ - return [float(machine_time_step)/1000.0] + return [float(ts) / 1000.0] - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractNeuronModel.get_values, additional_arguments={'ts'}) + @overrides(AbstractNeuronModel.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py index b17f0c1ca32..851f5c1c9c4 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_neuron_model import AbstractNeuronModel V = "v" @@ -98,8 +97,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractNeuronModel.get_values, additional_arguments={'ts'}) + @overrides(AbstractNeuronModel.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_alpha.py b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_alpha.py index 798fa6b59d7..cd717366eb3 100644 --- a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_alpha.py +++ b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_alpha.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_synapse_type import AbstractSynapseType EXC_RESPONSE = "exc_response" @@ -99,8 +98,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractSynapseType.get_values, additional_arguments={'ts'}) + @overrides(AbstractSynapseType.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_delta.py b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_delta.py index 619c456e671..5ee0da7587a 100644 --- a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_delta.py +++ b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_delta.py @@ -62,7 +62,7 @@ def has_variable(self, variable): return variable in UNITS @overrides(AbstractSynapseType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [state_variables[ISYN_EXC], state_variables[ISYN_INH]] diff --git a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_dual_exponential.py b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_dual_exponential.py index 5f2f1635744..983f139ad26 100644 --- a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_dual_exponential.py +++ b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_dual_exponential.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_synapse_type import AbstractSynapseType TAU_SYN_E = 'tau_syn_E' @@ -89,8 +88,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractSynapseType.get_values, additional_arguments={'ts'}) + @overrides(AbstractSynapseType.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_exponential.py b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_exponential.py index e5064936182..f2512bf6715 100644 --- a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_exponential.py +++ b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_exponential.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_synapse_type import AbstractSynapseType TAU_SYN_E = 'tau_syn_E' @@ -74,8 +73,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractSynapseType.get_values, additional_arguments={'ts'}) + @overrides(AbstractSynapseType.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_semd.py b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_semd.py index 2660cb4b24c..28c2cb12a58 100644 --- a/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_semd.py +++ b/spynnaker/pyNN/models/neuron/synapse_types/synapse_type_semd.py @@ -16,7 +16,6 @@ import numpy from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_synapse_type import AbstractSynapseType TAU_SYN_E = 'tau_syn_E' @@ -101,8 +100,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractSynapseType.get_values, additional_arguments={'ts'}) + @overrides(AbstractSynapseType.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): tsfloat = float(ts) / 1000.0 diff --git a/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_maass_stochastic.py b/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_maass_stochastic.py index 777a55cb0d4..5dd4128b366 100644 --- a/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_maass_stochastic.py +++ b/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_maass_stochastic.py @@ -15,7 +15,6 @@ from spinn_utilities.overrides import overrides from data_specification.enums import DataType -from pacman.executor.injection_decorator import inject_items from .abstract_threshold_type import AbstractThresholdType DU_TH = "du_th" @@ -69,8 +68,7 @@ def get_units(self, variable): def has_variable(self, variable): return variable in UNITS - @inject_items({"ts": "MachineTimeStep"}) - @overrides(AbstractThresholdType.get_values, additional_arguments={'ts'}) + @overrides(AbstractThresholdType.get_values) def get_values(self, parameters, state_variables, vertex_slice, ts): # pylint: disable=arguments-differ diff --git a/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_static.py b/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_static.py index 2c754a4f341..bb81d11a84a 100644 --- a/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_static.py +++ b/spynnaker/pyNN/models/neuron/threshold_types/threshold_type_static.py @@ -54,7 +54,7 @@ def has_variable(self, variable): return variable in UNITS @overrides(AbstractThresholdType.get_values) - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [parameters[V_THRESH]] diff --git a/unittests/test_populations/test_vertex.py b/unittests/test_populations/test_vertex.py index e976502741c..f2334f8555f 100644 --- a/unittests/test_populations/test_vertex.py +++ b/unittests/test_populations/test_vertex.py @@ -39,7 +39,7 @@ def add_parameters(self, parameters): def add_state_variables(self, state_variables): pass - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): return numpy.zeros(dtype="uint32") def update_values(self, values, parameters, state_variables): @@ -81,7 +81,7 @@ def add_state_variables(self, state_variables): state_variables["foo"] = self._foo state_variables["bar"] = self._bar - def get_values(self, parameters, state_variables, vertex_slice): + def get_values(self, parameters, state_variables, vertex_slice, ts): return numpy.zeros(dtype="uint32") def update_values(self, values, parameters, state_variables): From 6eecc8bddf4710019cec81918db45d3e305421b5 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Thu, 23 Apr 2020 15:51:06 +0100 Subject: [PATCH 22/66] Missed bits --- .../implementations/abstract_standard_neuron_component.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py b/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py index 98bcb0fa6d1..4f26a205529 100644 --- a/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py +++ b/spynnaker/pyNN/models/neuron/implementations/abstract_standard_neuron_component.py @@ -104,8 +104,8 @@ def get_values(self, parameters, state_variables, vertex_slice, ts): :rtype: A list of (single value or list of values or RangedList) """ - def get_data(self, parameters, state_variables, vertex_slice): - """ Get the data to be written to the machine for this model + def get_data(self, parameters, state_variables, vertex_slice, ts): + """ Get the data *to be written to the machine* for this model. :param parameters: The holder of the parameters :type parameters:\ @@ -116,7 +116,7 @@ def get_data(self, parameters, state_variables, vertex_slice): :param vertex_slice: The slice of the vertex to generate parameters for :rtype: numpy array of uint32 """ - values = self.get_values(parameters, state_variables, vertex_slice) + values = self.get_values(parameters, state_variables, vertex_slice, ts) return self.struct.get_data( values, vertex_slice.lo_atom, vertex_slice.n_atoms) From 70fe2854c1eb8e03317945a0e8303b3798bb60aa Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Mon, 11 May 2020 10:07:44 +0100 Subject: [PATCH 23/66] Fix things that have been fixed in main branch --- .../implementations/neuron_impl_standard.h | 18 +++++++++++------- .../implementations/neuron_impl_standard.py | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index c225005566b..583d61a8a67 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -226,16 +226,15 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, synapse_param_pointer_t synapse_type = &neuron_synapse_shaping_params[neuron_index]; - // Get the voltage - state_t voltage = neuron_model_get_membrane_voltage(neuron); - recorded_variable_values[V_RECORDING_INDEX] = voltage; - // Store whether the neuron has spiked bool spike = false; // Loop however many times requested for (uint32_t i = n_steps_per_timestep; i > 0; i--) { + // Get the voltage + state_t voltage = neuron_model_get_membrane_voltage(neuron); + // Get the exc and inh values from the synapses input_t* exc_value = synapse_types_get_excitatory_input(synapse_type); input_t* inh_value = synapse_types_get_inhibitory_input(synapse_type); @@ -258,11 +257,13 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, } // Call functions to get the input values to be recorded - recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; - recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; + if (i == n_steps_per_timestep) { + recorded_variable_values[V_RECORDING_INDEX] = voltage; + recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; + recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; + } // Call functions to convert exc_input and inh_input to current - voltage = neuron_model_get_membrane_voltage(neuron); input_type_convert_excitatory_input_to_current( exc_input_values, input_type, voltage); input_type_convert_inhibitory_input_to_current( @@ -315,6 +316,9 @@ static void neuron_impl_store_neuron_parameters( // return; //} + // Skip over the steps per timestep + next += 1; + if (sizeof(global_neuron_params_t)) { log_debug("writing neuron global parameters"); spin1_memcpy(&address[next], global_parameters, diff --git a/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py b/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py index 8efd730ef44..5315cd0b6bb 100644 --- a/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py +++ b/spynnaker/pyNN/models/neuron/implementations/neuron_impl_standard.py @@ -176,6 +176,7 @@ def get_data(self, parameters, state_variables, vertex_slice): @overrides(AbstractNeuronImpl.read_data) def read_data( self, data, offset, vertex_slice, parameters, state_variables): + offset += _BASE_SIZE for component in self.__components: offset = component.read_data( data, offset, vertex_slice, parameters, state_variables) From bf6b7b5f0ea35568053b02a86561f87eb5b9d808 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Mon, 11 May 2020 10:10:10 +0100 Subject: [PATCH 24/66] Another fix --- .../pyNN/models/neuron/abstract_pynn_neuron_model_standard.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py index f238703522c..50698422f7b 100644 --- a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py +++ b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py @@ -17,7 +17,8 @@ from spynnaker.pyNN.models.neuron.implementations import NeuronImplStandard from spinn_utilities.overrides import overrides -_population_parameters = AbstractPyNNNeuronModel.default_population_parameters +_population_parameters = dict( + AbstractPyNNNeuronModel.default_population_parameters) _population_parameters["n_steps_per_timestep"] = 1 class AbstractPyNNNeuronModelStandard(AbstractPyNNNeuronModel): From 3802b285e475b58ba7b17a68ac41a281b75b3155 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Mon, 3 Aug 2020 10:57:51 +0100 Subject: [PATCH 25/66] tagged IMPLICIT WEIGHT SCALING with a comment --- .../src/neuron/input_types/input_type_conductance.h | 2 +- .../pyNN/models/neuron/input_types/input_type_conductance.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/neural_modelling/src/neuron/input_types/input_type_conductance.h b/neural_modelling/src/neuron/input_types/input_type_conductance.h index 59f9d16afb8..b81ab5aa9ea 100644 --- a/neural_modelling/src/neuron/input_types/input_type_conductance.h +++ b/neural_modelling/src/neuron/input_types/input_type_conductance.h @@ -44,7 +44,7 @@ static inline input_t* input_type_get_input_value( input_t* value, input_type_pointer_t input_type, uint16_t num_receptors) { use(input_type); for (int i = 0; i < num_receptors; i++) { - value[i] = value[i] >> 5; + value[i] = value[i] >> 5; // IMPLICIT WEIGHT SCALING -- the default in main branch is >> 10 (2**10) } return &value[0]; } diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py index d2d0827b3ef..c3205056094 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py @@ -76,7 +76,7 @@ def update_values(self, values, parameters, state_variables): @overrides(AbstractInputType.get_global_weight_scale) def get_global_weight_scale(self): - return float(2**5) + return float(2**5) # IMPLICIT WEIGHT SCALING -- the default in main branch is 2**10 @property def e_rev_E(self): From 7f11fbfdae12f849f8efd50114216e3092925c5c Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Wed, 12 Aug 2020 15:37:07 +0100 Subject: [PATCH 26/66] round to nearest wherever I can --- .../input_types/input_type_conductance.h | 19 ++++++++++++++----- .../src/neuron/models/neuron_model_lif_impl.c | 11 +++++++++-- .../synapse_types_exponential_impl.h | 13 +++++++++++-- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/neural_modelling/src/neuron/input_types/input_type_conductance.h b/neural_modelling/src/neuron/input_types/input_type_conductance.h index b81ab5aa9ea..5bf1873aabc 100644 --- a/neural_modelling/src/neuron/input_types/input_type_conductance.h +++ b/neural_modelling/src/neuron/input_types/input_type_conductance.h @@ -31,6 +31,7 @@ #endif #include "input_type.h" +#include "round.h" typedef struct input_type_t { // reversal voltage - Excitatory [mV] @@ -44,7 +45,7 @@ static inline input_t* input_type_get_input_value( input_t* value, input_type_pointer_t input_type, uint16_t num_receptors) { use(input_type); for (int i = 0; i < num_receptors; i++) { - value[i] = value[i] >> 5; // IMPLICIT WEIGHT SCALING -- the default in main branch is >> 10 (2**10) + value[i] = value[i] >> 5; } return &value[0]; } @@ -53,8 +54,12 @@ static inline void input_type_convert_excitatory_input_to_current( input_t* exc_input, input_type_pointer_t input_type, state_t membrane_voltage) { for (int i=0; i < NUM_EXCITATORY_RECEPTORS; i++) { - exc_input[i] = exc_input[i] * - (input_type->V_rev_E - membrane_voltage); + // accum = accum * (accum - accum) +// exc_input[i] = exc_input[i] * +// (input_type->V_rev_E - membrane_voltage); + // RTN accum + exc_input[i] = MULT_ROUND_NEAREST_ACCUM(exc_input[i], + (input_type->V_rev_E - membrane_voltage)); } } @@ -62,8 +67,12 @@ static inline void input_type_convert_inhibitory_input_to_current( input_t* inh_input, input_type_pointer_t input_type, state_t membrane_voltage) { for (int i=0; i < NUM_INHIBITORY_RECEPTORS; i++) { - inh_input[i] = -inh_input[i] * - (input_type->V_rev_I - membrane_voltage); + // accum = accum * (accum - accum) +// inh_input[i] = -inh_input[i] * +// (input_type->V_rev_I - membrane_voltage); + // RTN accum + inh_input[i] = MULT_ROUND_NEAREST_ACCUM(-inh_input[i], + (input_type->V_rev_I - membrane_voltage)); } } diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c index 3bac73de40d..45051b9c49a 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c @@ -16,16 +16,23 @@ */ #include "neuron_model_lif_impl.h" +#include "round.h" #include // simple Leaky I&F ODE static inline void lif_neuron_closed_form( neuron_pointer_t neuron, REAL V_prev, input_t input_this_timestep) { - REAL alpha = input_this_timestep * neuron->R_membrane + neuron->V_rest; + // accum = accum * accum + accum +// REAL alpha = input_this_timestep * neuron->R_membrane + neuron->V_rest; + REAL alpha = MULT_ROUND_NEAREST_ACCUM ( + input_this_timestep, neuron->R_membrane) + neuron->V_rest; // update membrane voltage - neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); + // accum - (accum * (accum - accum)) +// neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); + neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( + neuron->exp_TC, (alpha - V_prev)); } void neuron_model_set_global_neuron_params( diff --git a/neural_modelling/src/neuron/synapse_types/synapse_types_exponential_impl.h b/neural_modelling/src/neuron/synapse_types/synapse_types_exponential_impl.h index 37ac9b01469..5ee7dbe6c10 100644 --- a/neural_modelling/src/neuron/synapse_types/synapse_types_exponential_impl.h +++ b/neural_modelling/src/neuron/synapse_types/synapse_types_exponential_impl.h @@ -41,6 +41,7 @@ #include #include #include "synapse_types.h" +#include "round.h" //--------------------------------------- @@ -77,9 +78,14 @@ typedef enum input_buffer_regions { //! \param[in] parameter: the pointer to the parameters to use //! \return nothing static inline void exp_shaping(exp_params_t* exp_params) { + // RTN // decay value according to decay constant +// exp_params->synaptic_input_value = +// decay_s1615(exp_params->synaptic_input_value, +// exp_params->decay); + exp_params->synaptic_input_value = - decay_s1615(exp_params->synaptic_input_value, + MULT_ROUND_NEAREST_ACCUM(exp_params->synaptic_input_value, exp_params->decay); } @@ -95,8 +101,11 @@ static inline void synapse_types_shape_input( //! \param[in] input the inputs to add. //! \return None static inline void add_input_exp(exp_params_t* exp_params, input_t input) { + // RTN +// exp_params->synaptic_input_value = exp_params->synaptic_input_value + +// decay_s1615(input, exp_params->init); exp_params->synaptic_input_value = exp_params->synaptic_input_value + - decay_s1615(input, exp_params->init); + MULT_ROUND_NEAREST_ACCUM(input, exp_params->init); } //! \brief adds the inputs for a give timer period to a given neuron that is From c06ecdddc5ce4c3deed1b05c83534e19826a7a80 Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Wed, 12 Aug 2020 16:02:43 +0100 Subject: [PATCH 27/66] exponential time constant is now an unsigned long fract --- neural_modelling/src/neuron/models/neuron_model_lif_impl.c | 2 +- neural_modelling/src/neuron/models/neuron_model_lif_impl.h | 2 +- .../neuron_models/neuron_model_leaky_integrate_and_fire.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c index 45051b9c49a..ff050889e0b 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c @@ -29,7 +29,7 @@ static inline void lif_neuron_closed_form( input_this_timestep, neuron->R_membrane) + neuron->V_rest; // update membrane voltage - // accum - (accum * (accum - accum)) + // accum - (ufract * (accum - accum)) // neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( neuron->exp_TC, (alpha - V_prev)); diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index 73c122a8a96..3c07c282dff 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -35,7 +35,7 @@ typedef struct neuron_t { // 'fixed' computation parameter - time constant multiplier for // closed-form solution // exp(-(machine time step in ms)/(R * C)) [.] - REAL exp_TC; + UFRACT exp_TC; // offset current [nA] REAL I_offset; diff --git a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py index 851f5c1c9c4..3c5d18e0697 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/neuron_model_leaky_integrate_and_fire.py @@ -54,7 +54,7 @@ def __init__( [DataType.S1615, # v DataType.S1615, # v_rest DataType.S1615, # r_membrane (= tau_m / cm) - DataType.S1615, # exp_tc (= e^(-ts / tau_m)) + DataType.U032, # exp_tc (= e^(-ts / tau_m)) DataType.S1615, # i_offset DataType.INT32, # count_refrac DataType.S1615, # v_reset From 2aa4f945aa46e0f2a12e0c5d93db2ffc6058904e Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Fri, 14 Aug 2020 09:51:06 +0100 Subject: [PATCH 28/66] potentially fixed v recording --- .../src/neuron/implementations/neuron_impl_standard.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index 583d61a8a67..d043828b077 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -225,6 +225,10 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, &additional_input_array[neuron_index]; synapse_param_pointer_t synapse_type = &neuron_synapse_shaping_params[neuron_index]; + // Get the voltage + state_t voltage = neuron_model_get_membrane_voltage(neuron); + // Record the voltage + recorded_variable_values[V_RECORDING_INDEX] = voltage; // Store whether the neuron has spiked bool spike = false; @@ -232,8 +236,6 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, // Loop however many times requested for (uint32_t i = n_steps_per_timestep; i > 0; i--) { - // Get the voltage - state_t voltage = neuron_model_get_membrane_voltage(neuron); // Get the exc and inh values from the synapses input_t* exc_value = synapse_types_get_excitatory_input(synapse_type); @@ -258,7 +260,6 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, // Call functions to get the input values to be recorded if (i == n_steps_per_timestep) { - recorded_variable_values[V_RECORDING_INDEX] = voltage; recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; } From 129a45ebc2a3454e2376b1202630828b179d8a4b Mon Sep 17 00:00:00 2001 From: Petrut Bogdan Date: Mon, 17 Aug 2020 11:43:38 +0100 Subject: [PATCH 29/66] correct recording of v --- .../src/neuron/implementations/neuron_impl_standard.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index d043828b077..97ae54a6ad8 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -225,17 +225,14 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, &additional_input_array[neuron_index]; synapse_param_pointer_t synapse_type = &neuron_synapse_shaping_params[neuron_index]; - // Get the voltage - state_t voltage = neuron_model_get_membrane_voltage(neuron); - // Record the voltage - recorded_variable_values[V_RECORDING_INDEX] = voltage; // Store whether the neuron has spiked bool spike = false; // Loop however many times requested for (uint32_t i = n_steps_per_timestep; i > 0; i--) { - + // Get the voltage + state_t voltage = neuron_model_get_membrane_voltage(neuron); // Get the exc and inh values from the synapses input_t* exc_value = synapse_types_get_excitatory_input(synapse_type); @@ -262,6 +259,8 @@ static bool neuron_impl_do_timestep_update(index_t neuron_index, if (i == n_steps_per_timestep) { recorded_variable_values[GSYN_EXCITATORY_RECORDING_INDEX] = total_exc; recorded_variable_values[GSYN_INHIBITORY_RECORDING_INDEX] = total_inh; + // Record the voltage + recorded_variable_values[V_RECORDING_INDEX] = voltage; } // Call functions to convert exc_input and inh_input to current From 9d64eb24208c4a4a381a0f6de1f0d2e69934a387 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 13:36:53 +0000 Subject: [PATCH 30/66] moved function to header but not the associated header... --- neural_modelling/src/neuron/models/neuron_model_lif_impl.c | 1 - neural_modelling/src/neuron/models/neuron_model_lif_impl.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c index 535336ac1cc..cc048303c86 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.c +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.c @@ -18,7 +18,6 @@ //! \file //! \brief Leaky Integrate and Fire neuron implementation #include "neuron_model_lif_impl.h" -#include "round.h" #include diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index 793bd2f2d2a..9ca47867eea 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -21,6 +21,7 @@ #define _NEURON_MODEL_LIF_CURR_IMPL_H_ #include "neuron_model.h" +#include "round.h" ///////////////////////////////////////////////////////////// //! definition for LIF neuron parameters From f2aac78789360e9a4e1728c56ac32a1e2b9cd34a Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 13:44:46 +0000 Subject: [PATCH 31/66] Move IF_cond_alpha from spynnaker8 repo --- spynnaker8/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spynnaker8/__init__.py b/spynnaker8/__init__.py index ac082264d52..3d1345f2c90 100644 --- a/spynnaker8/__init__.py +++ b/spynnaker8/__init__.py @@ -85,6 +85,9 @@ from spynnaker.pyNN.models.neuron.builds.if_curr_alpha import ( IFCurrAlpha as IF_curr_alpha) # noinspection PyUnresolvedReferences +from spynnaker.pyNN.models.neuron.builds.if_cond_alpha import \ + IFCondAlpha as IF_cond_alpha +# noinspection PyUnresolvedReferences from spynnaker.pyNN.models.neuron.builds.if_curr_delta import ( IFCurrDelta as IF_curr_delta) # noinspection PyUnresolvedReferences @@ -139,8 +142,8 @@ 'LastNeuronSelection', 'RandomSelection', 'DistanceDependentFormation', 'RandomByWeightElimination', # neuron stuff - 'IF_cond_exp', 'IF_curr_exp', "IF_curr_alpha", "IF_curr_delta", - 'Izhikevich', 'SpikeSourceArray', 'SpikeSourcePoisson', + 'IF_cond_exp', 'IF_curr_exp', "IF_curr_alpha", "IF_cond_alpha", + "IF_curr_delta", 'Izhikevich', 'SpikeSourceArray', 'SpikeSourcePoisson', # pops 'Assembly', 'Population', 'PopulationView', # projection From bcc4809150a537272049a45bed690830b68feb29 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 14:50:58 +0000 Subject: [PATCH 32/66] spinncer single cell experiment running --- spynnaker/pyNN/abstract_spinnaker_common.py | 40 +++++++++---------- .../external_device_lif_control.py | 4 +- .../neuron/abstract_population_vertex.py | 1 + .../neuron/abstract_pynn_neuron_model.py | 2 +- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/spynnaker/pyNN/abstract_spinnaker_common.py b/spynnaker/pyNN/abstract_spinnaker_common.py index ed575a8004a..fc4b05c875a 100644 --- a/spynnaker/pyNN/abstract_spinnaker_common.py +++ b/spynnaker/pyNN/abstract_spinnaker_common.py @@ -165,26 +165,26 @@ def _set_up_timings(self, timestep, min_delay, time_scale_factor): else: self.__min_delay = self.machine_time_step_ms - # Sort out the maximum delay - natively_supported_delay_for_models = \ - constants.MAX_SUPPORTED_DELAY_TICS - delay_extension_max_supported_delay = ( - constants.MAX_DELAY_BLOCKS * - constants.MAX_TIMER_TICS_SUPPORTED_PER_BLOCK) - max_delay_tics_supported = \ - natively_supported_delay_for_models + \ - delay_extension_max_supported_delay - if (max_delay is not None and max_delay * 1000.0 > - max_delay_tics_supported * machine_time_step): - raise ConfigurationException( - "Pacman does not support max delays above {} ms with the " - "current machine time step".format( - max_delay_tics_supported * self.machine_time_step_ms)) - if max_delay is not None: - self.__max_delay = max_delay - else: - self.__max_delay = ( - max_delay_tics_supported * self.machine_time_step_ms) + # # Sort out the maximum delay + # natively_supported_delay_for_models = \ + # constants.MAX_SUPPORTED_DELAY_TICS + # delay_extension_max_supported_delay = ( + # constants.MAX_DELAY_BLOCKS * + # constants.MAX_TIMER_TICS_SUPPORTED_PER_BLOCK) + # max_delay_tics_supported = \ + # natively_supported_delay_for_models + \ + # delay_extension_max_supported_delay + # if (max_delay is not None and max_delay * 1000.0 > + # max_delay_tics_supported * machine_time_step): + # raise ConfigurationException( + # "Pacman does not support max delays above {} ms with the " + # "current machine time step".format( + # max_delay_tics_supported * self.machine_time_step_ms)) + # if max_delay is not None: + # self.__max_delay = max_delay + # else: + # self.__max_delay = ( + # max_delay_tics_supported * self.machine_time_step_ms) # Sort out the time scale factor if not user specified # (including config) diff --git a/spynnaker/pyNN/external_devices_models/external_device_lif_control.py b/spynnaker/pyNN/external_devices_models/external_device_lif_control.py index ecc1c4aa400..59a170a87ef 100644 --- a/spynnaker/pyNN/external_devices_models/external_device_lif_control.py +++ b/spynnaker/pyNN/external_devices_models/external_device_lif_control.py @@ -97,7 +97,7 @@ def __init__( def create_vertex( self, n_neurons, label, constraints, spikes_per_second, ring_buffer_sigma, incoming_spike_buffer_size, - n_steps_per_timestep, drop_late_spikes, splitter): + n_steps_per_timestep, drop_late_spikes, splitter, rb_left_shifts): if n_neurons != len(self._devices): raise ConfigurationException( "Number of neurons does not match number of devices in {}" @@ -108,4 +108,4 @@ def create_vertex( self._devices, self._create_edges, max_atoms, self._model, self, self._translator, spikes_per_second, label, ring_buffer_sigma, incoming_spike_buffer_size, constraints, - drop_late_spikes, splitter) + drop_late_spikes, splitter, rb_left_shifts) diff --git a/spynnaker/pyNN/models/neuron/abstract_population_vertex.py b/spynnaker/pyNN/models/neuron/abstract_population_vertex.py index f19f525fb40..9fb08d4809a 100644 --- a/spynnaker/pyNN/models/neuron/abstract_population_vertex.py +++ b/spynnaker/pyNN/models/neuron/abstract_population_vertex.py @@ -860,6 +860,7 @@ def get_ring_buffer_shifts(self, incoming_projections): weights_signed = False rate_stats = [RunningStats() for _ in range(n_synapse_types)] steps_per_second = MICRO_TO_SECOND_CONVERSION / machine_time_step() + min_max_weight = numpy.ones(n_synapse_types) * 2 ** 32 for proj in incoming_projections: synapse_info = proj._synapse_information diff --git a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model.py b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model.py index 9ae3506ba20..970842ce24c 100644 --- a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model.py +++ b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model.py @@ -25,7 +25,7 @@ _population_parameters = { "spikes_per_second": None, "ring_buffer_sigma": None, "incoming_spike_buffer_size": None, "drop_late_spikes": None, - "splitter": None + "splitter": None, "rb_left_shifts": None } From db29ff890a88879dfeae4252aa614ea13bdb774f Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 15:11:03 +0000 Subject: [PATCH 33/66] add rb_left_shifts to tests --- .../model_tests/neuron/test_synaptic_manager.py | 12 ++++++++---- unittests/test_populations/test_vertex.py | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/unittests/model_tests/neuron/test_synaptic_manager.py b/unittests/model_tests/neuron/test_synaptic_manager.py index c4a5942a9f3..c951b90a0b1 100644 --- a/unittests/model_tests/neuron/test_synaptic_manager.py +++ b/unittests/model_tests/neuron/test_synaptic_manager.py @@ -216,7 +216,8 @@ def test_set_synapse_dynamics(): post_app_vertex = post_app_model.create_vertex( n_neurons=10, label="post", constraints=None, spikes_per_second=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, - n_steps_per_timestep=1, drop_late_spikes=True, splitter=None) + n_steps_per_timestep=1, drop_late_spikes=True, splitter=None, + rb_left_shifts=None) static = SynapseDynamicsStatic() stdp = SynapseDynamicsSTDP( @@ -326,7 +327,8 @@ def test_set_synapse_dynamics(): post_app_vertex = post_app_model.create_vertex( n_neurons=10, label="post", constraints=None, spikes_per_second=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, - n_steps_per_timestep=1, drop_late_spikes=True, splitter=None) + n_steps_per_timestep=1, drop_late_spikes=True, splitter=None, + rb_left_shifts=None) # STDP followed by structural STDP should result in Structural STDP post_app_vertex.synapse_dynamics = stdp @@ -348,7 +350,8 @@ def test_set_synapse_dynamics(): post_app_vertex = post_app_model.create_vertex( n_neurons=10, label="post", constraints=None, spikes_per_second=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, - n_steps_per_timestep=1, drop_late_spikes=True, splitter=None) + n_steps_per_timestep=1, drop_late_spikes=True, splitter=None, + rb_left_shifts=None) # Static followed by static structural should result in static # structural @@ -385,7 +388,8 @@ def test_set_synapse_dynamics(): post_app_vertex = post_app_model.create_vertex( n_neurons=10, label="post", constraints=None, spikes_per_second=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, - n_steps_per_timestep=1, drop_late_spikes=True, splitter=None) + n_steps_per_timestep=1, drop_late_spikes=True, splitter=None, + rb_left_shifts=None) post_app_vertex.synapse_dynamics = static_struct post_app_vertex.synapse_dynamics = stdp_struct diff --git a/unittests/test_populations/test_vertex.py b/unittests/test_populations/test_vertex.py index d16aa4e1531..9bc553cb681 100644 --- a/unittests/test_populations/test_vertex.py +++ b/unittests/test_populations/test_vertex.py @@ -112,7 +112,7 @@ def __init__(self): max_atoms_per_core=None, spikes_per_second=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, neuron_impl=foo_bar.model, pynn_model=foo_bar, - drop_late_spikes=True, splitter=None) + drop_late_spikes=True, splitter=None, rb_left_shifts=None) def test_initializable(): From 44d569ed275b5f680478bdef28f5242e7f0cceef Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 16:25:19 +0000 Subject: [PATCH 34/66] Can't take logs of something that could be zero --- spynnaker/pyNN/models/neuron/abstract_population_vertex.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/neuron/abstract_population_vertex.py b/spynnaker/pyNN/models/neuron/abstract_population_vertex.py index 9fb08d4809a..3efb4ac357b 100644 --- a/spynnaker/pyNN/models/neuron/abstract_population_vertex.py +++ b/spynnaker/pyNN/models/neuron/abstract_population_vertex.py @@ -928,7 +928,12 @@ def get_ring_buffer_shifts(self, incoming_projections): max_weights[synapse_type] = max( max_weights[synapse_type], biggest_weight[synapse_type]) # This is to deal with very small weights that are floored to 0 - mmw = 2**math.floor(math.log(min_max_weight[synapse_type], 2)) + if min_max_weight[synapse_type] != 0: + mmw = 2**math.floor(math.log(min_max_weight[synapse_type], 2)) + else: + # if it is zero then can't take logs... + small = 1.0 / 65536.0 + mmw = 2**math.floor(math.log(small, 2)) max_weights[synapse_type] = min(mmw * 2 ** 15, max_weights[synapse_type]) From bb735e66748776da0aba00b8e9867c145eca2605 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 18:22:48 +0000 Subject: [PATCH 35/66] fix to pass tests for now, but this constant was 64 earlier on branch... --- .../splitter_components/abstract_spynnaker_splitter_delay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py index 121de78f0ee..bf5e7ca3692 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py @@ -28,7 +28,7 @@ class AbstractSpynnakerSplitterDelay(object, metaclass=AbstractBase): __slots__ = [] # max delays supported by a slice split machine vertex - MAX_SUPPORTED_DELAY_TICS = 64 + MAX_SUPPORTED_DELAY_TICS = 16 # should this be 64? def max_support_delay(self): """ From 2a7083047e6076f837c1fffde0c80c5a15de0b0e Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 18:28:21 +0000 Subject: [PATCH 36/66] flake8 --- .../pyNN/models/neuron/abstract_pynn_neuron_model_standard.py | 1 + .../pyNN/models/neuron/input_types/input_type_conductance.py | 3 ++- spynnaker/pyNN/utilities/constants.py | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py index 48cbf09e18a..9878389b0d1 100644 --- a/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py +++ b/spynnaker/pyNN/models/neuron/abstract_pynn_neuron_model_standard.py @@ -21,6 +21,7 @@ AbstractPyNNNeuronModel.default_population_parameters) _population_parameters["n_steps_per_timestep"] = 1 + class AbstractPyNNNeuronModelStandard(AbstractPyNNNeuronModel): """ A neuron model that follows the sPyNNaker standard composed model \ pattern for point neurons. diff --git a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py index ae64e2a551c..73ebb8f48cc 100644 --- a/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py +++ b/spynnaker/pyNN/models/neuron/input_types/input_type_conductance.py @@ -86,7 +86,8 @@ def update_values(self, values, parameters, state_variables): @overrides(AbstractInputType.get_global_weight_scale) def get_global_weight_scale(self): - return float(2**5) # IMPLICIT WEIGHT SCALING -- the default in main branch is 2**10 + # IMPLICIT WEIGHT SCALING -- the default in main branch is 2**10 + return float(2**5) @property def e_rev_E(self): diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index 5740014c8d9..b92ae89dc1f 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -14,7 +14,6 @@ # along with this program. If not, see . -from enum import Enum import math from spinn_front_end_common.utilities.constants import ( BYTES_PER_WORD, BYTES_PER_KB) @@ -60,7 +59,7 @@ #: natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 MAX_DELAY_BLOCKS = 64 -DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) -1 +DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) - 1 MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 #: the minimum supported delay slot between two neurons From 8318cb9c52adbd1c1636513a402a560c3eaa9ed6 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 18:36:16 +0000 Subject: [PATCH 37/66] pylint caught a missed argument --- .../external_device_lif_control_vertex.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py b/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py index 778adcc78fc..f04b38fcf1e 100644 --- a/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py +++ b/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py @@ -49,7 +49,8 @@ def __init__( self, devices, create_edges, max_atoms_per_core, neuron_impl, pynn_model, translator=None, spikes_per_second=None, label=None, ring_buffer_sigma=None, incoming_spike_buffer_size=None, - drop_late_spikes=None, constraints=None, splitter=None): + drop_late_spikes=None, constraints=None, splitter=None, + rb_left_shifts=None): """ :param list(AbstractMulticastControllableDevice) devices: The AbstractMulticastControllableDevice instances to be controlled From 7b1789ff5cc5a97bd2ff967e9cb3c396bc7778f6 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 18:52:01 +0000 Subject: [PATCH 38/66] pylint, again I somehow missed this argument --- .../external_device_lif_control_vertex.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py b/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py index f04b38fcf1e..ab5c2847a80 100644 --- a/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py +++ b/spynnaker/pyNN/external_devices_models/external_device_lif_control_vertex.py @@ -106,7 +106,8 @@ def __init__( super().__init__( len(devices), label, constraints, max_atoms_per_core, spikes_per_second, ring_buffer_sigma, incoming_spike_buffer_size, - neuron_impl, pynn_model, drop_late_spikes, splitter) + neuron_impl, pynn_model, drop_late_spikes, splitter, + rb_left_shifts) def routing_key_partition_atom_mapping(self, routing_info, partition): # pylint: disable=arguments-differ From 51196ab4162a7ccc302a0d2e0fd936ff9c8a6052 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Dec 2021 19:00:35 +0000 Subject: [PATCH 39/66] Add copyright to spike_profiling.h --- neural_modelling/src/neuron/spike_profiling.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/neural_modelling/src/neuron/spike_profiling.h b/neural_modelling/src/neuron/spike_profiling.h index 7b21687caf7..e8f2752ca30 100644 --- a/neural_modelling/src/neuron/spike_profiling.h +++ b/neural_modelling/src/neuron/spike_profiling.h @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2017-2021 The University of Manchester + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include typedef struct spike_holder_t { From 3d1f36c83c397f92fba581881497e0c606d69aa5 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 7 Dec 2021 12:30:44 +0000 Subject: [PATCH 40/66] Allow up to 64 time slots for delays, update test accordingly --- .../abstract_spynnaker_splitter_delay.py | 2 +- .../model_tests/neuron/test_synaptic_manager.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py index bf5e7ca3692..07b5aff2e23 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py @@ -28,7 +28,7 @@ class AbstractSpynnakerSplitterDelay(object, metaclass=AbstractBase): __slots__ = [] # max delays supported by a slice split machine vertex - MAX_SUPPORTED_DELAY_TICS = 16 # should this be 64? + MAX_SUPPORTED_DELAY_TICS = 64 # should this be 64? def max_support_delay(self): """ diff --git a/unittests/model_tests/neuron/test_synaptic_manager.py b/unittests/model_tests/neuron/test_synaptic_manager.py index c951b90a0b1..c9207062cce 100644 --- a/unittests/model_tests/neuron/test_synaptic_manager.py +++ b/unittests/model_tests/neuron/test_synaptic_manager.py @@ -399,26 +399,26 @@ def test_set_synapse_dynamics(): "neurons_per_core,expect_app_keys,max_delay", [ # Only undelayed, all edges exist (range(10), [], 1000, 100, True, None), - # Only delayed, all edges exist - ([], range(10), 1000, 100, True, 20), + # Only delayed, all edges exist (note max_delay=20 on master) + ([], range(10), 1000, 100, True, 100), # All undelayed and delayed edges exist - (range(10), range(10), 1000, 100, True, 20), + (range(10), range(10), 1000, 100, True, 100), # Only undelayed, some edges are filtered (app keys shouldn't work) ([0, 1, 2, 3, 4], [], 1000, 100, False, None), # Only delayed, some edges are filtered (app keys shouldn't work) - ([], [5, 6, 7, 8, 9], 1000, 100, False, 20), + ([], [5, 6, 7, 8, 9], 1000, 100, False, 100), # Both delayed and undelayed, some undelayed edges don't exist # (app keys work because undelayed aren't filtered) - ([3, 4, 5, 6, 7], range(10), 1000, 100, True, 20), + ([3, 4, 5, 6, 7], range(10), 1000, 100, True, 100), # Both delayed and undelayed, some delayed edges don't exist # (app keys work because all undelayed exist) - (range(10), [4, 5, 6, 7], 1000, 100, True, 20), + (range(10), [4, 5, 6, 7], 1000, 100, True, 100), # Should work but number of neurons don't work out (range(5), [], 10000, 2048, False, None), # Should work but number of cores doesn't work out (range(2000), [], 10000, 5, False, None), # Should work but number of neurons with delays don't work out - ([], range(4), 1024, 256, False, 144) + ([], range(4), 1024, 256, False, 576) # 144 on master ]) def test_pop_based_master_pop_table_standard( undelayed_indices_connected, delayed_indices_connected, From f7de591756dfc3a8cd2a29ca3e97fe7ef6f43f41 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 8 Dec 2021 15:08:26 +0000 Subject: [PATCH 41/66] move send_spike out of sub-cycle; fix peak for n_atoms=1 --- .../implementations/neuron_impl_standard.h | 42 +++++++++---------- .../neuron/population_machine_neurons.py | 6 ++- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index 30e1ceb604a..a14337dfb23 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -266,6 +266,9 @@ static void neuron_impl_do_timestep_update( &additional_input_array[neuron_index]; synapse_param_t *the_synapse_type = &neuron_synapse_shaping_params[neuron_index]; + + bool spike = false; + // Loop however many times requested; do this in reverse for efficiency, // and because the index doesn't actually matter for (uint32_t i_step = n_steps_per_timestep; i_step > 0; i_step--) { @@ -328,6 +331,8 @@ static void neuron_impl_do_timestep_update( // If spike occurs, communicate to relevant parts of model if (spike_now) { + spike = true; + // Call relevant model-based functions // Tell the neuron model neuron_model_has_spiked(this_neuron); @@ -335,11 +340,11 @@ static void neuron_impl_do_timestep_update( // Tell the additional input additional_input_has_spiked(additional_inputs); - // Record the spike - neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); - - // Send the spike - send_spike(timer_count, time, neuron_index); +// // Record the spike +// neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); +// +// // Send the spike +// send_spike(timer_count, time, neuron_index); } // Shape the existing input according to the included rule @@ -349,6 +354,14 @@ static void neuron_impl_do_timestep_update( #if LOG_LEVEL >= LOG_DEBUG neuron_model_print_state_variables(this_neuron); #endif // LOG_LEVEL >= LOG_DEBUG + + if (spike) { + // Record the spike + neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); + + // Send the spike + send_spike(timer_count, time, neuron_index); + } } } @@ -364,8 +377,8 @@ static void neuron_impl_store_neuron_parameters( // Skip over the steps per timestep next += 1; - // Skip over the steps per timestep - next += 1; +// // Skip over the steps per timestep +// next += 1; if (sizeof(global_neuron_params_t)) { log_debug("writing neuron global parameters"); @@ -416,37 +429,22 @@ static void neuron_impl_store_neuron_parameters( void neuron_impl_print_inputs(uint32_t n_neurons) { bool empty = true; for (index_t i = 0; i < n_neurons; i++) { -<<<<<<< HEAD - empty = empty && (0 == bitsk( - synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) - - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]))); -======= synapse_param_t *params = &neuron_synapse_shaping_params[i]; empty = empty && (0 == bitsk( synapse_types_get_excitatory_input(params) - synapse_types_get_inhibitory_input(params))); ->>>>>>> refs/remotes/origin/master } if (!empty) { log_debug("-------------------------------------\n"); for (index_t i = 0; i < n_neurons; i++) { -<<<<<<< HEAD - input_t input = - synapse_types_get_excitatory_input(&neuron_synapse_shaping_params[i]) - - synapse_types_get_inhibitory_input(&neuron_synapse_shaping_params[i]); - if (bitsk(input) != 0) { - log_debug("%3u: %12.6k (= ", i, input); - synapse_types_print_input(&neuron_synapse_shaping_params[i]); -======= synapse_param_t *params = &neuron_synapse_shaping_params[i]; input_t input = synapse_types_get_excitatory_input(params) - synapse_types_get_inhibitory_input(params); if (bitsk(input) != 0) { log_debug("%3u: %12.6k (= ", i, input); synapse_types_print_input(params); ->>>>>>> refs/remotes/origin/master log_debug(")\n"); } } diff --git a/spynnaker/pyNN/models/neuron/population_machine_neurons.py b/spynnaker/pyNN/models/neuron/population_machine_neurons.py index b7edf1dfb85..3811a7bab17 100644 --- a/spynnaker/pyNN/models/neuron/population_machine_neurons.py +++ b/spynnaker/pyNN/models/neuron/population_machine_neurons.py @@ -195,7 +195,11 @@ def _write_neuron_parameters(self, spec, ring_buffer_shifts): # Write the number of neurons in the block: spec.write_value(data=n_atoms) - spec.write_value(data=2**get_n_bits(n_atoms)) + # Write the peak neurons (closest above power of 2 of n_atoms) + if (n_atoms == 1): + spec.write_value(data=n_atoms) + else: + spec.write_value(data=2**get_n_bits(n_atoms)) # Write the ring buffer data # This is only the synapse types that need a ring buffer i.e. not From 9714ba404c703b4d6fb433589522e8f2fedc5cb4 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 16 Dec 2021 11:35:34 +0000 Subject: [PATCH 42/66] Add structured provenance filename reference --- spynnaker8/spinnaker.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spynnaker8/spinnaker.py b/spynnaker8/spinnaker.py index 8920adcc000..90f08343e45 100644 --- a/spynnaker8/spinnaker.py +++ b/spynnaker8/spinnaker.py @@ -52,6 +52,9 @@ def __init__( self.__segment_counter = 0 self.__recorders = set([]) + # Structured provenance_items + self.structured_provenance_filename = None + # main pynn interface inheritance pynn_control.BaseState.__init__(self) From 16422d957dfa469927b94abe1e8db4daae82bf2f Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 19 Jul 2022 14:11:13 +0100 Subject: [PATCH 43/66] Missed these prints --- .../splitter_abstract_pop_vertex_fixed.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py index c3db84718a6..db5d6fe4bba 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py @@ -89,15 +89,14 @@ def create_machine_vertices(self, chip_counter): print("Using given values for RB left shifts.") ring_buffer_shifts = app_vertex.rb_left_shifts print("RB left shifts for {:20}".format(app_vertex.label), - "=", self.__ring_buffer_shifts) + "=", ring_buffer_shifts) print("-" * 80) else: print("=" * 80) print("Computing RB left shifts for", app_vertex.label) - ring_buffer_shifts = app_vertex.get_ring_buffer_shifts( - app_vertex.incoming_projections) + ring_buffer_shifts = app_vertex.get_ring_buffer_shifts(projections) print("RB left shifts for {:20}".format(app_vertex.label), - "=", self.__ring_buffer_shifts) + "=", ring_buffer_shifts) # ring_buffer_shifts = app_vertex.get_ring_buffer_shifts(projections) weight_scales = app_vertex.get_weight_scales(ring_buffer_shifts) From caf6b489ed0e47ae4b424bfc10e0caa0f0764608 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 19 Jul 2022 14:20:04 +0100 Subject: [PATCH 44/66] Move print functions under log debug --- neural_modelling/src/neuron/spike_profiling.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/neural_modelling/src/neuron/spike_profiling.h b/neural_modelling/src/neuron/spike_profiling.h index e8f2752ca30..958dfd858b5 100644 --- a/neural_modelling/src/neuron/spike_profiling.h +++ b/neural_modelling/src/neuron/spike_profiling.h @@ -82,6 +82,7 @@ static inline accum spike_profiling_get_spike_holder_as_accum( return x.acc; } +#if LOG_LEVEL >= LOG_DEBUG static inline void spike_profiling_print_spikes_from_spike_holder( struct spike_holder_t spikes_orig) { io_printf(IO_BUF, "Spikes from input: a %u, b %u, c %u, d %u \n", @@ -94,3 +95,4 @@ static inline void spike_profiling_print_spikes_from_int(int32_t output) { (output & 0xFF), (output >> 8 & 0xFF), (output >> 16 & 0xFF), (output >> 24 & 0xFF)); } +#endif From 2c95c1f03fab12b39bfa1728872db63ca4377204 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 19 Jul 2022 14:26:39 +0100 Subject: [PATCH 45/66] Not sure how this file came back again... --- .../push_bot_retina_viewer.py | 128 ------------------ 1 file changed, 128 deletions(-) delete mode 100644 spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py diff --git a/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py b/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py deleted file mode 100644 index 9f0a1d883f0..00000000000 --- a/spynnaker/pyNN/external_devices_models/push_bot/push_bot_parameters/push_bot_retina_viewer.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2017-2019 The University of Manchester -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import math -import socket -from threading import Thread -import numpy - -# Value of brightest pixel to show -_DISPLAY_MAX = 33.0 -# How regularity to display frames -_FRAME_TIME_MS = 10 -# Time constant of pixel decay -_DECAY_TIME_CONSTANT_MS = 100 -_BUFFER_SIZE = 512 - - -class PushBotRetinaViewer(Thread): - def __init__( - self, resolution, port=0, display_max=_DISPLAY_MAX, - frame_time_ms=_FRAME_TIME_MS, - decay_time_constant_ms=_DECAY_TIME_CONSTANT_MS): - # pylint: disable=too-many-arguments - try: - from matplotlib import pyplot # NOQA - from matplotlib import animation # NOQA - self.__pyplot = pyplot - self.__animation = animation - except ImportError: - raise Exception("matplotlib must be installed to use this viewer") - - super(PushBotRetinaViewer, self).__init__(name="PushBotRetinaViewer") - self.__display_max = display_max - self.__frame_time_ms = frame_time_ms - self.__image = None - self.__ani = None - - # Open socket to receive UDP - self._init_socket(port) - - # Determine mask for coordinates - self.__coordinate_mask = \ - (1 << (2 * resolution.bits_per_coordinate)) - 1 - - # Set up the image - self.__image_data = numpy.zeros(resolution.pixels * resolution.pixels) - self.__image_data_view = self.__image_data.view() - self.__image_data_view.shape = (resolution.pixels, resolution.pixels) - - # Calculate decay proportion each frame - self.__decay_proportion = math.exp( - -float(self.__frame_time_ms) / float(decay_time_constant_ms)) - - def _init_socket(self, port): - """ Open socket to receive UDP. - """ - self.__spike_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.__spike_socket.bind(("0.0.0.0", port)) - self.__spike_socket.setblocking(False) - - self.__local_host, self.__local_port = \ - self.__spike_socket.getsockname() - - @property - def local_host(self): - return self.__local_host - - @property - def local_port(self): - return self.__local_port - - def __recv_data(self, size=_BUFFER_SIZE): - return self.__spike_socket.recv(size) - - def _close(self): - self.__spike_socket.close() - - def _parse_raw_data(self, raw_data): - # Slice off EIEIO header and timestamp, and convert to numpy - # array of uint32 - payload = numpy.fromstring(raw_data[6:], dtype="uint32") - - # Mask out x, y coordinates - payload &= self.__coordinate_mask - - # Increment these pixels - self.__image_data[payload] += 1.0 - - def _updatefig(self): - # Read all UDP messages received during last frame - while True: - try: - self._parse_raw_data(self.__recv_data()) - except socket.error: - # Stop reading - break - - # Decay image data - self.__image_data *= self.__decay_proportion - - # Set image data - self.__image.set_array(self.__image_data_view) - return [self.__image] - - def run(self): - # Create image plot of retina output - fig = self.__pyplot.figure() - self.__image = self.__pyplot.imshow( - self.__image_data_view, cmap="viridis", vmin=0.0, - vmax=self.__display_max) - - # Play animation - self.__ani = self.__animation.FuncAnimation( - fig, (lambda _frame: self._updatefig()), - interval=self.__frame_time_ms, blit=True) - self.__pyplot.show() From f8ec96656c6dd7c3b5374f419b1a0f8136386400 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 19 Jul 2022 14:53:50 +0100 Subject: [PATCH 46/66] Turn off largest binaries for now --- neural_modelling/makefiles/neuron/Makefile | 10 +++++----- .../src/neuron/current_sources/current_source.h | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/neural_modelling/makefiles/neuron/Makefile b/neural_modelling/makefiles/neuron/Makefile index 9d5ffdbce29..e5c1f063074 100644 --- a/neural_modelling/makefiles/neuron/Makefile +++ b/neural_modelling/makefiles/neuron/Makefile @@ -50,11 +50,11 @@ MODELS = IF_curr_exp \ IZK_cond_exp_stdp_izhikevich_neuromodulation_pair_additive \ IZK_cond_exp_stdp_izhikevich_neuromodulation_pair_multiplicative \ IF_curr_exp_stdp_izhikevich_neuromodulation_vogels_2011_additive \ - IF_curr_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ - IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight \ - IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight \ - IF_cond_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ - IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight + IF_curr_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight +# IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight \ +# IF_cond_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ +# IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight +# IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight \ all: for d in $(MODELS); do $(MAKE) -C $$d || exit $$?; done diff --git a/neural_modelling/src/neuron/current_sources/current_source.h b/neural_modelling/src/neuron/current_sources/current_source.h index 43af1250469..d58ab0872d1 100644 --- a/neural_modelling/src/neuron/current_sources/current_source.h +++ b/neural_modelling/src/neuron/current_sources/current_source.h @@ -60,7 +60,6 @@ static bool current_source_initialise(address_t cs_address, uint32_t n_neurons) // Avoid the loops if no current sources #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) - io_printf(IO_BUF, "no current sources defined \n"); return true; #else @@ -155,7 +154,6 @@ static bool current_source_load_parameters(address_t cs_address) { // Avoid the loops if no current sources #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) - io_printf(IO_BUF, "no current sources defined \n"); return true; #else From e51cfedde75c0f8001da4327083d46d731faa872 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 20 Jul 2022 09:32:42 +0100 Subject: [PATCH 47/66] Implement no current source; update Makefiles for large binaries --- .../Makefile | 2 +- .../Makefile | 2 +- .../Makefile | 2 +- neural_modelling/makefiles/neuron/Makefile | 10 ++++---- .../neuron/current_sources/current_source.h | 6 ++--- .../current_sources/current_source_none.h | 25 +++++++++++++++++++ .../current_source_none_impl.h | 25 +++++++++++++++++++ 7 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 neural_modelling/src/neuron/current_sources/current_source_none.h create mode 100644 neural_modelling/src/neuron/current_sources/current_source_none_impl.h diff --git a/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight/Makefile b/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight/Makefile index a6556cca292..83da67c914f 100644 --- a/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight/Makefile +++ b/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight/Makefile @@ -17,7 +17,7 @@ APP = $(notdir $(CURDIR)) NEURON_MODEL = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.c NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_conductance.h -CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_stepnoisy_impl.h +CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_dc_only_impl.h NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_exponential_impl.h diff --git a/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile b/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile index d86d1de57c3..70595029ae3 100644 --- a/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile +++ b/neural_modelling/makefiles/neuron/IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile @@ -17,7 +17,7 @@ APP = $(notdir $(CURDIR)) NEURON_MODEL = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.c NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_conductance.h -CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_dc_only_impl.h +CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_none_impl.h NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_exponential_impl.h diff --git a/neural_modelling/makefiles/neuron/IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile b/neural_modelling/makefiles/neuron/IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile index 832dda59a84..fc9ace5af26 100644 --- a/neural_modelling/makefiles/neuron/IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile +++ b/neural_modelling/makefiles/neuron/IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight/Makefile @@ -17,7 +17,7 @@ APP = $(notdir $(CURDIR)) NEURON_MODEL = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.c NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_current.h -CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_noisy_only_impl.h +CURRENT_SOURCE_H = $(NEURON_DIR)/neuron/current_sources/current_source_dc_only_impl.h NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_exponential_impl.h diff --git a/neural_modelling/makefiles/neuron/Makefile b/neural_modelling/makefiles/neuron/Makefile index e5c1f063074..9d5ffdbce29 100644 --- a/neural_modelling/makefiles/neuron/Makefile +++ b/neural_modelling/makefiles/neuron/Makefile @@ -50,11 +50,11 @@ MODELS = IF_curr_exp \ IZK_cond_exp_stdp_izhikevich_neuromodulation_pair_additive \ IZK_cond_exp_stdp_izhikevich_neuromodulation_pair_multiplicative \ IF_curr_exp_stdp_izhikevich_neuromodulation_vogels_2011_additive \ - IF_curr_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight -# IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight \ -# IF_cond_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ -# IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight -# IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight \ + IF_curr_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ + IF_curr_exp_stdp_mad_pair_additive_structural_random_distance_weight \ + IF_cond_exp_stdp_mad_nearest_pair_additive_structural_last_neuron_distance_weight \ + IF_cond_exp_stdp_mad_pair_additive_structural_last_neuron_distance_weight \ + IF_cond_exp_stdp_mad_pair_additive_structural_random_distance_weight all: for d in $(MODELS); do $(MAKE) -C $$d || exit $$?; done diff --git a/neural_modelling/src/neuron/current_sources/current_source.h b/neural_modelling/src/neuron/current_sources/current_source.h index d58ab0872d1..a18c35fa831 100644 --- a/neural_modelling/src/neuron/current_sources/current_source.h +++ b/neural_modelling/src/neuron/current_sources/current_source.h @@ -58,8 +58,7 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static bool current_source_initialise(address_t cs_address, uint32_t n_neurons) { // Avoid the loops if no current sources - #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ - !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) + #if defined(_CURRENT_SOURCE_NONE_H_) return true; #else @@ -152,8 +151,7 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static bool current_source_load_parameters(address_t cs_address) { // Avoid the loops if no current sources - #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ - !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) + #if defined(_CURRENT_SOURCE_NONE_H_) return true; #else diff --git a/neural_modelling/src/neuron/current_sources/current_source_none.h b/neural_modelling/src/neuron/current_sources/current_source_none.h new file mode 100644 index 00000000000..53a951aa8ce --- /dev/null +++ b/neural_modelling/src/neuron/current_sources/current_source_none.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2019 The University of Manchester + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//! \dir +//! \brief None current source functions +//! \file +//! \brief Functions called for no current source +#ifndef _CURRENT_SOURCE_NONE_H_ +#define _CURRENT_SOURCE_NONE_H_ + +#endif // _CURRENT_SOURCE_NONE_H_ diff --git a/neural_modelling/src/neuron/current_sources/current_source_none_impl.h b/neural_modelling/src/neuron/current_sources/current_source_none_impl.h new file mode 100644 index 00000000000..bdea7a9b927 --- /dev/null +++ b/neural_modelling/src/neuron/current_sources/current_source_none_impl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2019 The University of Manchester + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//! \dir +//! \brief Current source implementations +//! \file +//! \brief General API of a current source implementation +#ifndef _CURRENT_SOURCE_NONE_IMPL_H_ +#define _CURRENT_SOURCE_NONE_IMPL_H_ + +#endif // _CURRENT_SOURCE_NONE_IMPL_H_ From b11c3162adbcd824d43ca192fe9cc92c54e38c89 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 31 Aug 2022 15:01:28 +0100 Subject: [PATCH 48/66] Delay slots constant has been moved to the splitter --- .../splitter_components/abstract_spynnaker_splitter_delay.py | 2 +- spynnaker/pyNN/utilities/constants.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py index 07b5aff2e23..2dbd2fc8727 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py @@ -28,7 +28,7 @@ class AbstractSpynnakerSplitterDelay(object, metaclass=AbstractBase): __slots__ = [] # max delays supported by a slice split machine vertex - MAX_SUPPORTED_DELAY_TICS = 64 # should this be 64? + MAX_SUPPORTED_DELAY_TICS = 16 # 64 # should this be 64? def max_support_delay(self): """ diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index b92ae89dc1f..a9c09d4a9c7 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -57,8 +57,8 @@ SCALE = WEIGHT_FLOAT_TO_FIXED_SCALE * NA_TO_PA_SCALE #: natively supported delays for all abstract_models -MAX_SUPPORTED_DELAY_TICS = 64 -MAX_DELAY_BLOCKS = 64 +MAX_SUPPORTED_DELAY_TICS = 16 # 64 +MAX_DELAY_BLOCKS = 16 # 64 DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) - 1 MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 From 125005e808ecac496950be71e71415b102c4c8fe Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 22 Sep 2022 15:01:14 +0100 Subject: [PATCH 49/66] Fit debug builds into ITCM --- .../implementations/neuron_impl_standard.h | 3 --- .../population_table_binary_search_impl.c | 24 +++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index 676b54b4815..fa0548fed13 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -177,9 +177,6 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \param[in] n_neurons: number of neurons static void neuron_impl_load_neuron_parameters( address_t address, uint32_t next, uint32_t n_neurons) { - log_debug("reading parameters, next is %u, n_neurons is %u ", - next, n_neurons); - // Read the number of steps per timestep n_steps_per_timestep = address[next++]; if (n_steps_per_timestep > 1) { diff --git a/neural_modelling/src/neuron/population_table/population_table_binary_search_impl.c b/neural_modelling/src/neuron/population_table/population_table_binary_search_impl.c index e7415674a80..0f27318c179 100644 --- a/neural_modelling/src/neuron/population_table/population_table_binary_search_impl.c +++ b/neural_modelling/src/neuron/population_table/population_table_binary_search_impl.c @@ -320,15 +320,15 @@ bool population_table_load_bitfields(filter_region_t *filter_region) { log_debug("Master pop key: 0x%08x, mask: 0x%08x", master_population_table[mp_i].key, master_population_table[mp_i].mask); -#ifdef LOG_DEBUG - // Sanity checking code; not needed in normal operation, and costs ITCM - // With both things being in key order, this should never happen... - if (bf_i < n_filters && - filters[bf_i].key < master_population_table[mp_i].key) { - log_error("Skipping bitfield %d for key 0x%08x", bf_i, filters[bf_i].key); - rt_error(RTE_SWERR); - } -#endif +//#ifdef LOG_DEBUG +// // Sanity checking code; not needed in normal operation, and costs ITCM +// // With both things being in key order, this should never happen... +// if (bf_i < n_filters && +// filters[bf_i].key < master_population_table[mp_i].key) { +// log_error("Skipping bitfield %d for key 0x%08x", bf_i, filters[bf_i].key); +// rt_error(RTE_SWERR); +// } +//#endif // While there is a match, keep track of the start and end; note this // may recheck the first entry, but there might not be a first entry if @@ -336,7 +336,7 @@ bool population_table_load_bitfields(filter_region_t *filter_region) { uint32_t start = bf_i; uint32_t n_words_total = 0; uint32_t useful = 0; - log_debug("Starting with bit field %d with key 0x%08x", bf_i, filters[bf_i].key); +// log_debug("Starting with bit field %d with key 0x%08x", bf_i, filters[bf_i].key); while (bf_i < n_filters && matches(mp_i, filters[bf_i].key)) { log_debug("Using bit field %d with key 0x%08x, merged %d, redundant %d", bf_i, filters[bf_i].key, filters[bf_i].merged, filters[bf_i].all_ones); @@ -513,12 +513,12 @@ bool population_table_get_first_address( // neuron here. If not return false and avoid the DMA check. if (!bit_field_test( connectivity_bit_field[position], last_neuron_id)) { - log_debug("Tested and was not set"); +// log_debug("Tested and was not set"); bit_field_filtered_packets += 1; items_to_go = 0; return false; } - log_debug("Was set, carrying on"); +// log_debug("Was set, carrying on"); } else { log_debug("Bit field was not set up. " "either its due to a lack of DTCM, or because the " From 08f377e9c7653cfc561f9b0b76a0926437caadc4 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 22 Sep 2022 16:48:22 +0100 Subject: [PATCH 50/66] Delete test no longer in master, go back to spinncer delay tics values --- .../splitter_components/abstract_spynnaker_splitter_delay.py | 2 +- spynnaker/pyNN/utilities/constants.py | 4 ++-- unittests/model_tests/neuron/test_synaptic_manager.py | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py index 2dbd2fc8727..2a78e4b82bc 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py @@ -28,7 +28,7 @@ class AbstractSpynnakerSplitterDelay(object, metaclass=AbstractBase): __slots__ = [] # max delays supported by a slice split machine vertex - MAX_SUPPORTED_DELAY_TICS = 16 # 64 # should this be 64? + MAX_SUPPORTED_DELAY_TICS = 64 # can this be 16? def max_support_delay(self): """ diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index a9c09d4a9c7..b92ae89dc1f 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -57,8 +57,8 @@ SCALE = WEIGHT_FLOAT_TO_FIXED_SCALE * NA_TO_PA_SCALE #: natively supported delays for all abstract_models -MAX_SUPPORTED_DELAY_TICS = 16 # 64 -MAX_DELAY_BLOCKS = 16 # 64 +MAX_SUPPORTED_DELAY_TICS = 64 +MAX_DELAY_BLOCKS = 64 DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) - 1 MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 diff --git a/unittests/model_tests/neuron/test_synaptic_manager.py b/unittests/model_tests/neuron/test_synaptic_manager.py index 75c6c9ec539..554bd24ed71 100644 --- a/unittests/model_tests/neuron/test_synaptic_manager.py +++ b/unittests/model_tests/neuron/test_synaptic_manager.py @@ -411,8 +411,6 @@ def test_set_synapse_dynamics(): # Both delayed and undelayed, some delayed edges don't exist # (app keys work because all undelayed exist) (range(10), [4, 5, 6, 7], 1000, 100, True, 100), - # Should work but number of neurons don't work out - (range(5), [], 10000, 2048, False, None), # Should work but number of cores doesn't work out (range(2000), [], 10000, 5, False, None), # Should work but number of neurons with delays don't work out From 0418d8ae16f2b1f3f99652b277b2dc9e325111ac Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 3 Oct 2022 12:48:29 +0100 Subject: [PATCH 51/66] Attempt to catch possible issues with ring buffer DTCM for longer delays --- .../splitter_abstract_pop_vertex_fixed.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py index 00f23aa98cf..d20f23a7fe9 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py @@ -20,6 +20,7 @@ AbstractSplitterCommon) from pacman.utilities.algorithm_utilities\ .partition_algorithm_utilities import get_multidimensional_slices +from pacman.utilities.utility_calls import get_n_bits_for_fields from spynnaker.pyNN.models.neuron import ( AbstractPopulationVertex, PopulationMachineVertex, PopulationMachineLocalOnlyCombinedVertex, LocalOnlyProvenance) @@ -38,6 +39,12 @@ from spynnaker.pyNN.models.neuron.local_only import AbstractLocalOnly from collections import defaultdict from spynnaker.pyNN.models.utility_models.delays import DelayExtensionVertex +from spynnaker.pyNN.utilities.utility_calls import get_n_bits +from spynnaker.pyNN.exceptions import SynapticConfigurationException + +# The maximum number of bits for the ring buffer index that are likely to +# fit in DTCM (14-bits = 16,384 16-bit ring buffer entries = 32Kb DTCM +MAX_RING_BUFFER_BITS = 14 class SplitterAbstractPopulationVertexFixed( @@ -97,6 +104,23 @@ def set_governed_app_vertex(self, app_vertex): @overrides(AbstractSplitterCommon.create_machine_vertices) def create_machine_vertices(self, chip_counter): app_vertex = self._governed_app_vertex + + # Do some checks to make sure everything is likely to fit + field_sizes = [ + min(max_atoms, n) for max_atoms, n in zip( + app_vertex.get_max_atoms_per_dimension_per_core(), + app_vertex.atoms_shape)] + n_atom_bits = get_n_bits_for_fields(field_sizes) + n_synapse_types = app_vertex.neuron_impl.get_n_synapse_types() + if (n_atom_bits + get_n_bits(n_synapse_types) + + get_n_bits(self.max_support_delay())) > MAX_RING_BUFFER_BITS: + raise SynapticConfigurationException( + "The combination of the number of neurons per core ({}), " + "the number of synapse types ({}), and the maximum delay per " + "core ({}) will require too much DTCM. Please reduce one or " + "more of these values.".format( + field_sizes, n_synapse_types, self.max_support_delay())) + app_vertex.synapse_recorder.add_region_offset( len(app_vertex.neuron_recorder.get_recordable_variables())) From 10d430c40fa6c451623fdad77ce9db70bbeb3763 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 4 Oct 2022 16:40:19 +0100 Subject: [PATCH 52/66] Adjust DELAY_MASK calculations --- .../models/neuron/synapse_dynamics/synapse_dynamics_static.py | 4 ++-- spynnaker/pyNN/utilities/constants.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py index 85666a05cae..7dc657f9d81 100644 --- a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py +++ b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py @@ -170,8 +170,8 @@ def read_static_synaptic_data( connections["target"] = ( (data & neuron_id_mask) + post_vertex_slice.lo_atom) connections["weight"] = (data >> 16) & 0xFFFF - connections["delay"] = (data >> (n_neuron_id_bits + - n_synapse_type_bits)) & DELAY_MASK + connections["delay"] = ((data & OxFFF) >> ( + n_neuron_id_bits + n_synapse_type_bits)) & DELAY_MASK connections["delay"][connections["delay"] == 0] = 16 return connections diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index b92ae89dc1f..43cf81753ee 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -58,9 +58,9 @@ #: natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 -MAX_DELAY_BLOCKS = 64 +# MAX_DELAY_BLOCKS = 64 DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) - 1 -MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 +# MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 #: the minimum supported delay slot between two neurons MIN_SUPPORTED_DELAY = 1 From 91ea67d0a18f46e1d75c9b5b4f00098775320a01 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 4 Oct 2022 16:57:24 +0100 Subject: [PATCH 53/66] Revert "Adjust DELAY_MASK calculations" This reverts commit 10d430c40fa6c451623fdad77ce9db70bbeb3763. --- .../models/neuron/synapse_dynamics/synapse_dynamics_static.py | 4 ++-- spynnaker/pyNN/utilities/constants.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py index 7dc657f9d81..85666a05cae 100644 --- a/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py +++ b/spynnaker/pyNN/models/neuron/synapse_dynamics/synapse_dynamics_static.py @@ -170,8 +170,8 @@ def read_static_synaptic_data( connections["target"] = ( (data & neuron_id_mask) + post_vertex_slice.lo_atom) connections["weight"] = (data >> 16) & 0xFFFF - connections["delay"] = ((data & OxFFF) >> ( - n_neuron_id_bits + n_synapse_type_bits)) & DELAY_MASK + connections["delay"] = (data >> (n_neuron_id_bits + + n_synapse_type_bits)) & DELAY_MASK connections["delay"][connections["delay"] == 0] = 16 return connections diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index 43cf81753ee..b92ae89dc1f 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -58,9 +58,9 @@ #: natively supported delays for all abstract_models MAX_SUPPORTED_DELAY_TICS = 64 -# MAX_DELAY_BLOCKS = 64 +MAX_DELAY_BLOCKS = 64 DELAY_MASK = (1 << int(math.log2(MAX_SUPPORTED_DELAY_TICS))) - 1 -# MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 +MAX_TIMER_TICS_SUPPORTED_PER_BLOCK = 16 #: the minimum supported delay slot between two neurons MIN_SUPPORTED_DELAY = 1 From f7fc478eadb08f0c5fa564dc973e5654557cf5af Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 30 Nov 2022 11:55:38 +0000 Subject: [PATCH 54/66] Update to stop compiler warnings --- neural_modelling/src/neuron/current_sources/current_source.h | 3 +-- neural_modelling/src/neuron/models/neuron_model_lif_impl.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/neural_modelling/src/neuron/current_sources/current_source.h b/neural_modelling/src/neuron/current_sources/current_source.h index a18c35fa831..aba55bd5efe 100644 --- a/neural_modelling/src/neuron/current_sources/current_source.h +++ b/neural_modelling/src/neuron/current_sources/current_source.h @@ -207,8 +207,7 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static inline REAL current_source_get_offset(uint32_t time, uint32_t neuron_index) { // Avoid the loops if no current sources defined - #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ - !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) + #if defined(_CURRENT_SOURCE_NONE_H_) return ZERO; #else diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index 2ba573249bf..d0073af2a88 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -65,7 +65,7 @@ static inline void lif_neuron_closed_form( neuron_t *neuron, REAL V_prev, input_t input_this_timestep) { // accum = accum * accum + accum // REAL alpha = input_this_timestep * neuron->R_membrane + neuron->V_rest; - REAL alpha = MULT_ROUND_NEAREST_ACCUM ( + REAL alpha = MULT_ROUND_NEAREST_ACCUM( input_this_timestep, neuron->R_membrane) + neuron->V_rest; // update membrane voltage From d7bf5dedb32b3c2d87468edf9e0c09a178e9091a Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 30 Nov 2022 16:43:42 +0000 Subject: [PATCH 55/66] missed in merge --- spynnaker/pyNN/models/populations/population.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index eb3591552bb..78de5b158eb 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -828,14 +828,6 @@ def __create_vertex( if rb_left_shifts is not None: self.__vertex.set_rb_left_shifts(rb_left_shifts) - # Introspect properties of the vertex - self.__vertex_population_settable = \ - isinstance(self.__vertex, AbstractPopulationSettable) - self.__vertex_population_initializable = \ - isinstance(self.__vertex, AbstractPopulationInitializable) - self.__vertex_contains_units = \ - isinstance(self.__vertex, AbstractContainsUnits) - @staticmethod def create(cellclass, cellparams=None, n=1): """ Pass through method to the constructor defined by PyNN.\ From 5905d56f5a9695ef8508fbafe14751ac6692917f Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 1 Dec 2022 17:26:32 +0000 Subject: [PATCH 56/66] Still trying to work out ITCM problems on this branch --- neural_modelling/src/neuron/c_main.c | 30 ++-- neural_modelling/src/neuron/c_main_synapses.c | 22 +++ .../neuron/current_sources/current_source.h | 9 +- .../current_sources/current_source_none.h | 25 ---- .../current_source_none_impl.h | 25 ---- .../input_types/input_type_conductance.h | 18 +-- .../src/neuron/models/neuron_model_lif_impl.h | 18 +-- .../src/neuron/spike_processing.c | 104 +++++++------- .../src/neuron/spike_processing.h | 58 ++++---- .../src/neuron/spike_processing_fast.c | 56 ++++++++ .../src/neuron/spike_processing_fast.h | 43 ++++++ .../neuron/synapse_types/exp_synapse_utils.h | 19 +-- .../splitter_abstract_pop_vertex_fixed.py | 31 ++-- .../neuron/population_machine_vertex.py | 134 +++++++++--------- ...pulation_synapses_machine_vertex_common.py | 70 ++++++++- 15 files changed, 402 insertions(+), 260 deletions(-) delete mode 100644 neural_modelling/src/neuron/current_sources/current_source_none.h delete mode 100644 neural_modelling/src/neuron/current_sources/current_source_none_impl.h diff --git a/neural_modelling/src/neuron/c_main.c b/neural_modelling/src/neuron/c_main.c index 6ac13699bdd..b11909a47be 100644 --- a/neural_modelling/src/neuron/c_main.c +++ b/neural_modelling/src/neuron/c_main.c @@ -38,13 +38,13 @@ #include "c_main_common.h" #include "regions.h" #include "profile_tags.h" -#include "spike_profiling.h" +//#include "spike_profiling.h" #include "spike_processing.h" -struct spike_holder_t spike_counter; -struct spike_holder_t spike_cache; -struct spike_holder_t spike_counter_inh; -struct spike_holder_t spike_cache_inh; +//struct spike_holder_t spike_counter; +//struct spike_holder_t spike_cache; +//struct spike_holder_t spike_counter_inh; +//struct spike_holder_t spike_cache_inh; //! The combined provenance from synapses and neurons struct combined_provenance { @@ -188,16 +188,16 @@ void background_callback(uint timer_count, uint local_time) { //! \param[in] unused: unused parameter kept for API consistency void timer_callback(uint timer_count, UNUSED uint unused) { - // Get number of spikes in last tick, and reset spike counter - spike_processing_get_and_reset_spikes_this_tick(); - spike_processing_get_and_reset_dmas_this_tick(); - spike_processing_get_and_reset_pipeline_restarts_this_tick(); - - // cache and flush spike counters - spike_profiling_cache_and_flush_spike_holder(&spike_counter, - &spike_cache); - spike_profiling_cache_and_flush_spike_holder(&spike_counter_inh, - &spike_cache_inh); +// // Get number of spikes in last tick, and reset spike counter +// spike_processing_get_and_reset_spikes_this_tick(); +// spike_processing_get_and_reset_dmas_this_tick(); +// spike_processing_get_and_reset_pipeline_restarts_this_tick(); +// +// // cache and flush spike counters +// spike_profiling_cache_and_flush_spike_holder(&spike_counter, +// &spike_cache); +// spike_profiling_cache_and_flush_spike_holder(&spike_counter_inh, +// &spike_cache_inh); // Disable interrupts to stop DMAs and MC getting in the way of this bit uint32_t state = spin1_int_disable(); diff --git a/neural_modelling/src/neuron/c_main_synapses.c b/neural_modelling/src/neuron/c_main_synapses.c index 811e2976f45..e99b5903c71 100644 --- a/neural_modelling/src/neuron/c_main_synapses.c +++ b/neural_modelling/src/neuron/c_main_synapses.c @@ -36,9 +36,20 @@ #include "c_main_synapse_common.h" #include "c_main_common.h" #include "spike_processing_fast.h" +#include "spike_profiling.h" #include "structural_plasticity/synaptogenesis_dynamics.h" #include +//! spike profiling +struct spike_holder_t spike_counter; +struct spike_holder_t spike_cache; +struct spike_holder_t spike_counter_inh; +struct spike_holder_t spike_cache_inh; + +//// FLUSH SPIKES ?? +//bool timer_callback_active = false; +//extern volatile bool dma_busy; + //! values for the priority for each callback typedef enum callback_priorities { MC = -1, DMA = -2, TIMER = 0, SDP = 0 @@ -130,6 +141,17 @@ void resume_callback(void) { //! \param[in] unused0: unused //! \param[in] unused1: unused void timer_callback(UNUSED uint unused0, UNUSED uint unused1) { + // Get number of spikes in last tick, and reset spike counter + spike_processing_get_and_reset_spikes_this_tick(); + spike_processing_get_and_reset_dmas_this_tick(); + spike_processing_get_and_reset_pipeline_restarts_this_tick(); + + // cache and flush spike counters + spike_profiling_cache_and_flush_spike_holder(&spike_counter, + &spike_cache); + spike_profiling_cache_and_flush_spike_holder(&spike_counter_inh, + &spike_cache_inh); + time++; if (simulation_is_finished()) { // Enter pause and resume state to avoid another tick diff --git a/neural_modelling/src/neuron/current_sources/current_source.h b/neural_modelling/src/neuron/current_sources/current_source.h index bf021c00662..c4a2ef8e30a 100644 --- a/neural_modelling/src/neuron/current_sources/current_source.h +++ b/neural_modelling/src/neuron/current_sources/current_source.h @@ -58,7 +58,8 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static bool current_source_initialise(address_t cs_address, uint32_t n_neurons) { // Avoid the loops if no current sources - #if defined(_CURRENT_SOURCE_NONE_H_) + #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ + !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) return true; #else @@ -148,7 +149,8 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static bool current_source_load_parameters(address_t cs_address) { // Avoid the loops if no current sources - #if defined(_CURRENT_SOURCE_NONE_H_) + #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ + !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) return true; #else @@ -204,7 +206,8 @@ SOMETIMES_UNUSED // Marked unused as only used sometimes //! \return True if successful static inline REAL current_source_get_offset(uint32_t time, uint32_t neuron_index) { // Avoid the loops if no current sources defined - #if defined(_CURRENT_SOURCE_NONE_H_) + #if !defined(_CURRENT_SOURCE_DC_H_) && !defined(_CURRENT_SOURCE_AC_H) && \ + !defined(_CURRENT_SOURCE_STEP_H_) && !defined(_CURRENT_SOURCE_NOISY_H_) return ZERO; #else diff --git a/neural_modelling/src/neuron/current_sources/current_source_none.h b/neural_modelling/src/neuron/current_sources/current_source_none.h deleted file mode 100644 index 53a951aa8ce..00000000000 --- a/neural_modelling/src/neuron/current_sources/current_source_none.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2017-2019 The University of Manchester - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -//! \dir -//! \brief None current source functions -//! \file -//! \brief Functions called for no current source -#ifndef _CURRENT_SOURCE_NONE_H_ -#define _CURRENT_SOURCE_NONE_H_ - -#endif // _CURRENT_SOURCE_NONE_H_ diff --git a/neural_modelling/src/neuron/current_sources/current_source_none_impl.h b/neural_modelling/src/neuron/current_sources/current_source_none_impl.h deleted file mode 100644 index bdea7a9b927..00000000000 --- a/neural_modelling/src/neuron/current_sources/current_source_none_impl.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2017-2019 The University of Manchester - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -//! \dir -//! \brief Current source implementations -//! \file -//! \brief General API of a current source implementation -#ifndef _CURRENT_SOURCE_NONE_IMPL_H_ -#define _CURRENT_SOURCE_NONE_IMPL_H_ - -#endif // _CURRENT_SOURCE_NONE_IMPL_H_ diff --git a/neural_modelling/src/neuron/input_types/input_type_conductance.h b/neural_modelling/src/neuron/input_types/input_type_conductance.h index c3fad7e3853..5c78eb2b3f5 100644 --- a/neural_modelling/src/neuron/input_types/input_type_conductance.h +++ b/neural_modelling/src/neuron/input_types/input_type_conductance.h @@ -21,7 +21,7 @@ #define _INPUT_TYPE_CONDUCTANCE_H_ #include "input_type.h" -#include "round.h" +//#include "round.h" //! Conductance input parameters struct input_type_params_t { @@ -77,11 +77,11 @@ static inline void input_type_convert_excitatory_input_to_current( state_t membrane_voltage) { for (int i=0; i < NUM_EXCITATORY_RECEPTORS; i++) { // accum = accum * (accum - accum) -// exc_input[i] = exc_input[i] * -// (input_type->V_rev_E - membrane_voltage); + exc_input[i] = exc_input[i] * + (input_type->V_rev_E - membrane_voltage); // RTN accum - exc_input[i] = MULT_ROUND_NEAREST_ACCUM(exc_input[i], - (input_type->V_rev_E - membrane_voltage)); +// exc_input[i] = MULT_ROUND_NEAREST_ACCUM(exc_input[i], +// (input_type->V_rev_E - membrane_voltage)); } } @@ -96,11 +96,11 @@ static inline void input_type_convert_inhibitory_input_to_current( state_t membrane_voltage) { for (int i=0; i < NUM_INHIBITORY_RECEPTORS; i++) { // accum = accum * (accum - accum) -// inh_input[i] = -inh_input[i] * -// (input_type->V_rev_I - membrane_voltage); + inh_input[i] = -inh_input[i] * + (input_type->V_rev_I - membrane_voltage); // RTN accum - inh_input[i] = MULT_ROUND_NEAREST_ACCUM(-inh_input[i], - (input_type->V_rev_I - membrane_voltage)); +// inh_input[i] = MULT_ROUND_NEAREST_ACCUM(-inh_input[i], +// (input_type->V_rev_I - membrane_voltage)); } } diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index b8fd0bc0f46..a024f9838aa 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -21,7 +21,7 @@ #define _NEURON_MODEL_LIF_CURR_IMPL_H_ #include "neuron_model.h" -#include "round.h" +//#include "round.h" //! definition for LIF neuron parameters struct neuron_params_t { @@ -121,15 +121,15 @@ static inline void neuron_model_save_state(neuron_t *state, neuron_params_t *par static inline void lif_neuron_closed_form( neuron_t *neuron, REAL V_prev, input_t input_this_timestep) { // accum = accum * accum + accum -// REAL alpha = input_this_timestep * neuron->R_membrane + neuron->V_rest; - REAL alpha = MULT_ROUND_NEAREST_ACCUM( - input_this_timestep, neuron->R_membrane) + neuron->V_rest; + REAL alpha = (input_this_timestep * neuron->R_membrane) + neuron->V_rest; +// REAL alpha = MULT_ROUND_NEAREST_ACCUM( +// input_this_timestep, neuron->R_membrane) + neuron->V_rest; // update membrane voltage // accum - (ufract * (accum - accum)) -// neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); - neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( - neuron->exp_TC, (alpha - V_prev)); + neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); +// neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( +// neuron->exp_TC, (alpha - V_prev)); } //! \brief primary function called in timer loop after synaptic updates @@ -154,8 +154,8 @@ static inline state_t neuron_model_state_update( // If outside of the refractory period if (neuron->refract_timer <= 0) { - REAL total_exc = 0; - REAL total_inh = 0; + REAL total_exc = ZERO; + REAL total_inh = ZERO; for (int i=0; i < num_excitatory_inputs; i++) { total_exc += exc_input[i]; diff --git a/neural_modelling/src/neuron/spike_processing.c b/neural_modelling/src/neuron/spike_processing.c index 5179c608d8f..18ce336e4c5 100644 --- a/neural_modelling/src/neuron/spike_processing.c +++ b/neural_modelling/src/neuron/spike_processing.c @@ -109,18 +109,18 @@ static uint32_t biggest_fill_size_of_input_buffer; //! end of a timer tick. static bool clear_input_buffers_of_late_packets; -static uint32_t max_spikes_in_a_tick; -static uint32_t max_dmas_in_a_tick; -static uint32_t dma_complete_count; -static uint32_t max_pipeline_restarts; -static uint32_t spike_pipeline_deactivation_time = 0; -static uint32_t timer_callback_completed = 0; -static uint32_t spikes_this_time_step = 0; // needed because packets gets reset? -static uint32_t dmas_this_time_step = 0; -static uint32_t pipeline_restarts = 0; - -static uint32_t max_flushed_spikes = 0; -static uint32_t total_flushed_spikes = 0; +//static uint32_t max_spikes_in_a_tick; +//static uint32_t max_dmas_in_a_tick; +//static uint32_t dma_complete_count; +//static uint32_t max_pipeline_restarts; +//static uint32_t spike_pipeline_deactivation_time = 0; +//static uint32_t timer_callback_completed = 0; +//static uint32_t spikes_this_time_step = 0; // needed because packets gets reset? +//static uint32_t dmas_this_time_step = 0; +//static uint32_t pipeline_restarts = 0; +// +//static uint32_t max_flushed_spikes = 0; +//static uint32_t total_flushed_spikes = 0; //! the number of packets received this time step static struct { @@ -315,8 +315,8 @@ static inline void start_dma_loop(void) { static void multicast_packet_received_callback(uint key, UNUSED uint unused) { p_per_ts_struct.packets_this_time_step += 1; // Increment the count of number of spikes received this tick by this core - spikes_this_time_step++; - log_debug("Received spike %x at %d, DMA Busy = %d", key, time, dma_busy); +// spikes_this_time_step++; +// log_debug("Received spike %x at %d, DMA Busy = %d", key, time, dma_busy); if (in_spikes_add_spike(key)) { start_dma_loop(); } @@ -328,9 +328,9 @@ static void multicast_packet_received_callback(uint key, UNUSED uint unused) { static void multicast_packet_pl_received_callback(uint key, uint payload) { p_per_ts_struct.packets_this_time_step += 1; // Increment the count of number of spikes received this tick by this core - spikes_this_time_step++; - log_debug("Received spike %x with payload %d at %d, DMA Busy = %d", - key, payload, time, dma_busy); +// spikes_this_time_step++; +// log_debug("Received spike %x with payload %d at %d, DMA Busy = %d", +// key, payload, time, dma_busy); // cycle through the packet insertion bool added = false; @@ -350,11 +350,11 @@ static void dma_complete_callback(UNUSED uint unused, UNUSED uint tag) { // increment the dma complete count for provenance generation dma_complete_count++; - log_debug("DMA transfer complete at time %u with tag %u", time, tag); - - // Increment the counter tracking the number of DMAs completed this - // timestep on a particular core - dmas_this_time_step++; +// log_debug("DMA transfer complete at time %u with tag %u", time, tag); +// +// // Increment the counter tracking the number of DMAs completed this +// // timestep on a particular core +// dmas_this_time_step++; // Get pointer to current buffer uint32_t current_buffer_index = buffer_being_read; @@ -426,7 +426,7 @@ void user_event_callback(UNUSED uint unused0, UNUSED uint unused1) { dma_n_spikes = 0; // Increment counter for spike processing pipeline restarts - pipeline_restarts++; +// pipeline_restarts++; if (buffer_being_read < N_DMA_BUFFERS) { // If the DMA buffer is full of valid data, attempt to reuse it on the @@ -500,13 +500,13 @@ void spike_processing_store_provenance(struct spike_processing_provenance *prov) prov->n_rewires = n_successful_rewires; prov->n_packets_dropped_from_lateness = count_input_buffer_packets_late; prov->max_filled_input_buffer_size = biggest_fill_size_of_input_buffer; - prov->max_spikes_in_a_tick = max_spikes_in_a_tick; - prov->max_dmas_in_a_tick = max_dmas_in_a_tick; - prov->max_pipeline_restarts = max_pipeline_restarts; - prov->timer_callback_completed = timer_callback_completed; - prov->spike_pipeline_deactivated = spike_pipeline_deactivation_time; - prov->max_flushed_spikes = max_flushed_spikes; - prov->total_flushed_spikes = total_flushed_spikes; +// prov->max_spikes_in_a_tick = max_spikes_in_a_tick; +// prov->max_dmas_in_a_tick = max_dmas_in_a_tick; +// prov->max_pipeline_restarts = max_pipeline_restarts; +// prov->timer_callback_completed = timer_callback_completed; +// prov->spike_pipeline_deactivated = spike_pipeline_deactivation_time; +// prov->max_flushed_spikes = max_flushed_spikes; +// prov->total_flushed_spikes = total_flushed_spikes; } bool spike_processing_do_rewiring(int number_of_rewires) { @@ -519,28 +519,28 @@ bool spike_processing_do_rewiring(int number_of_rewires) { return true; } -// Custom provenance from SpiNNCer -void spike_processing_get_and_reset_spikes_this_tick(void ) { - if (spikes_this_time_step > max_spikes_in_a_tick) { - max_spikes_in_a_tick = spikes_this_time_step; - } - spikes_this_time_step = 0; -} - -void spike_processing_get_and_reset_dmas_this_tick(void) { - if (dmas_this_time_step > max_dmas_in_a_tick){ - max_dmas_in_a_tick = dmas_this_time_step; - } - dmas_this_time_step = 0; -} - -void spike_processing_get_and_reset_pipeline_restarts_this_tick(void) { - if (pipeline_restarts > max_pipeline_restarts) { - max_pipeline_restarts = pipeline_restarts; - } - pipeline_restarts = 0; -} - +//// Custom provenance from SpiNNCer +//void spike_processing_get_and_reset_spikes_this_tick(void ) { +// if (spikes_this_time_step > max_spikes_in_a_tick) { +// max_spikes_in_a_tick = spikes_this_time_step; +// } +// spikes_this_time_step = 0; +//} +// +//void spike_processing_get_and_reset_dmas_this_tick(void) { +// if (dmas_this_time_step > max_dmas_in_a_tick){ +// max_dmas_in_a_tick = dmas_this_time_step; +// } +// dmas_this_time_step = 0; +//} +// +//void spike_processing_get_and_reset_pipeline_restarts_this_tick(void) { +// if (pipeline_restarts > max_pipeline_restarts) { +// max_pipeline_restarts = pipeline_restarts; +// } +// pipeline_restarts = 0; +//} +// //uint32_t spike_processing_get_pipeline_deactivation_time(){ // return spike_pipeline_deactivation_time; //} diff --git a/neural_modelling/src/neuron/spike_processing.h b/neural_modelling/src/neuron/spike_processing.h index 38d9f3cc22d..3a48a5bcb94 100644 --- a/neural_modelling/src/neuron/spike_processing.h +++ b/neural_modelling/src/neuron/spike_processing.h @@ -38,21 +38,21 @@ struct spike_processing_provenance { uint32_t n_packets_dropped_from_lateness; //! The maximum size of the input buffer uint32_t max_filled_input_buffer_size; - //! SpiNNCer-related provenance - //! The maximum number of spikes in a tick - uint32_t max_spikes_in_a_tick; - //! The maximum number of DMAs in a tick - uint32_t max_dmas_in_a_tick; - //! The maximum number of pipeline restarts - uint32_t max_pipeline_restarts; - //! Was the timer callback completed? - uint32_t timer_callback_completed; - //! Was the spike pipeline deactivated? - uint32_t spike_pipeline_deactivated; - //! The maximum number of flushed spikes in one step - uint32_t max_flushed_spikes; - //! Thet total number of flushed spikes - uint32_t total_flushed_spikes; +// //! SpiNNCer-related provenance +// //! The maximum number of spikes in a tick +// uint32_t max_spikes_in_a_tick; +// //! The maximum number of DMAs in a tick +// uint32_t max_dmas_in_a_tick; +// //! The maximum number of pipeline restarts +// uint32_t max_pipeline_restarts; +// //! Was the timer callback completed? +// uint32_t timer_callback_completed; +// //! Was the spike pipeline deactivated? +// uint32_t spike_pipeline_deactivated; +// //! The maximum number of flushed spikes in one step +// uint32_t max_flushed_spikes; +// //! Thet total number of flushed spikes +// uint32_t total_flushed_spikes; }; //! \brief Initialise the spike processing system @@ -86,20 +86,20 @@ bool spike_processing_do_rewiring(int number_of_rewires); void spike_processing_clear_input_buffer(timer_t time); -// Custom provenance from SpiNNCer - -//! \brief get number of spikes received since last timer event -//! \return uint32_t number of spikes -void spike_processing_get_and_reset_spikes_this_tick(void); - -//! \brief get number of dmas completed since last timer event -//! \return uint32_t number of DMAs -void spike_processing_get_and_reset_dmas_this_tick(void); - -//! \brief get number of time pipeline was restarted since last timer event -//! \return uint32_t number of pipeline restarts -void spike_processing_get_and_reset_pipeline_restarts_this_tick(void); - +//// Custom provenance from SpiNNCer +// +////! \brief get number of spikes received since last timer event +////! \return uint32_t number of spikes +//void spike_processing_get_and_reset_spikes_this_tick(void); +// +////! \brief get number of dmas completed since last timer event +////! \return uint32_t number of DMAs +//void spike_processing_get_and_reset_dmas_this_tick(void); +// +////! \brief get number of time pipeline was restarted since last timer event +////! \return uint32_t number of pipeline restarts +//void spike_processing_get_and_reset_pipeline_restarts_this_tick(void); +// ////! \brief get time from T1 clock at which spike pipeline completed ////! \return uint32_t pipeline deactivation time //uint32_t spike_processing_get_pipeline_deactivation_time(); diff --git a/neural_modelling/src/neuron/spike_processing_fast.c b/neural_modelling/src/neuron/spike_processing_fast.c index a668ae23bc6..2c698e609c4 100644 --- a/neural_modelling/src/neuron/spike_processing_fast.c +++ b/neural_modelling/src/neuron/spike_processing_fast.c @@ -115,6 +115,19 @@ static uint32_t earliest_spike_received_time = 0; //! The maximum number of spikes left at the end of a time step static uint32_t max_spikes_overflow = 0; +static uint32_t max_spikes_in_a_tick; +static uint32_t max_dmas_in_a_tick; +static uint32_t dma_complete_count; +static uint32_t max_pipeline_restarts; +static uint32_t spike_pipeline_deactivation_time = 0; +static uint32_t timer_callback_completed = 0; +static uint32_t spikes_this_time_step = 0; // needed because packets gets reset? +static uint32_t dmas_this_time_step = 0; +static uint32_t pipeline_restarts = 0; + +static uint32_t max_flushed_spikes = 0; +static uint32_t total_flushed_spikes = 0; + //! The number of packets received this time step for recording static struct { uint32_t time; @@ -657,4 +670,47 @@ void spike_processing_fast_store_provenance( prov->earliest_receive = earliest_spike_received_time; prov->latest_receive = latest_spike_received_time; prov->max_spikes_overflow = max_spikes_overflow; + prov->max_spikes_in_a_tick = max_spikes_in_a_tick; + prov->max_dmas_in_a_tick = max_dmas_in_a_tick; + prov->max_pipeline_restarts = max_pipeline_restarts; + prov->timer_callback_completed = timer_callback_completed; + prov->spike_pipeline_deactivated = spike_pipeline_deactivation_time; + prov->max_flushed_spikes = max_flushed_spikes; + prov->total_flushed_spikes = total_flushed_spikes; } + +// Custom provenance from SpiNNCer +void spike_processing_get_and_reset_spikes_this_tick(void ) { + if (spikes_this_time_step > max_spikes_in_a_tick) { + max_spikes_in_a_tick = spikes_this_time_step; + } + spikes_this_time_step = 0; +} + +void spike_processing_get_and_reset_dmas_this_tick(void) { + if (dmas_this_time_step > max_dmas_in_a_tick){ + max_dmas_in_a_tick = dmas_this_time_step; + } + dmas_this_time_step = 0; +} + +void spike_processing_get_and_reset_pipeline_restarts_this_tick(void) { + if (pipeline_restarts > max_pipeline_restarts) { + max_pipeline_restarts = pipeline_restarts; + } + pipeline_restarts = 0; +} + +uint32_t spike_processing_get_pipeline_deactivation_time(){ + return spike_pipeline_deactivation_time; +} + +// FLUSH SPIKES +uint32_t spike_processing_get_total_flushed_spikes(){ + return total_flushed_spikes; +} + +uint32_t spike_processing_get_max_flushed_spikes(){ + return max_flushed_spikes; +} + diff --git a/neural_modelling/src/neuron/spike_processing_fast.h b/neural_modelling/src/neuron/spike_processing_fast.h index 3ee096cd9a6..20c79ff9c5b 100644 --- a/neural_modelling/src/neuron/spike_processing_fast.h +++ b/neural_modelling/src/neuron/spike_processing_fast.h @@ -80,6 +80,21 @@ struct spike_processing_fast_provenance { uint32_t latest_receive; //! The most spikes left at the end of any time step uint32_t max_spikes_overflow; + //! SpiNNCer-related provenance + //! The maximum number of spikes in a tick + uint32_t max_spikes_in_a_tick; + //! The maximum number of DMAs in a tick + uint32_t max_dmas_in_a_tick; + //! The maximum number of pipeline restarts + uint32_t max_pipeline_restarts; + //! Was the timer callback completed? + uint32_t timer_callback_completed; + //! Was the spike pipeline deactivated? + uint32_t spike_pipeline_deactivated; + //! The maximum number of flushed spikes in one step + uint32_t max_flushed_spikes; + //! Thet total number of flushed spikes + uint32_t total_flushed_spikes; }; //! \brief Set up spike processing @@ -113,4 +128,32 @@ void spike_processing_fast_time_step_loop(uint32_t time, uint32_t n_rewires); void spike_processing_fast_store_provenance( struct spike_processing_fast_provenance *prov); +// Custom provenance from SpiNNCer + +//! \brief get number of spikes received since last timer event +//! \return uint32_t number of spikes +void spike_processing_get_and_reset_spikes_this_tick(void); + +//! \brief get number of dmas completed since last timer event +//! \return uint32_t number of DMAs +void spike_processing_get_and_reset_dmas_this_tick(void); + +//! \brief get number of time pipeline was restarted since last timer event +//! \return uint32_t number of pipeline restarts +void spike_processing_get_and_reset_pipeline_restarts_this_tick(void); + +//! \brief get time from T1 clock at which spike pipeline completed +//! \return uint32_t pipeline deactivation time +uint32_t spike_processing_get_pipeline_deactivation_time(); + +// FLUSH SPIKES +//! \brief returns the total unprocessed spikes from a simulation +//! \return total unprocessed spikes +uint32_t spike_processing_get_total_flushed_spikes(); + +//! \brief returns the maximum unprocessed spikes from a single +//! simulation timestep. +//! \return maximum unprocessed spikes from a single timestep. +uint32_t spike_processing_get_max_flushed_spikes(); + #endif // _SPIKE_PROCESSING_FAST_H_ diff --git a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h index 12eab582bbe..731d9c4c105 100644 --- a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h +++ b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h @@ -22,7 +22,7 @@ #include #include -#include "round.h" +//#include "round.h" //! The type of exponential decay parameters typedef struct exp_params_t { @@ -61,20 +61,21 @@ static inline void decay_and_init(exp_state_t *state, exp_params_t *params, //! \param[in,out] exp_param: The parameter to shape static inline void exp_shaping(exp_state_t *exp_param) { // decay value according to decay constant -// exp_param->synaptic_input_value = -// decay_s1615(exp_param->synaptic_input_value, exp_param->decay); - exp_param->synaptic_input_value = - MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, - exp_param->decay);} + exp_param->synaptic_input_value = + decay_s1615(exp_param->synaptic_input_value, exp_param->decay); +// exp_param->synaptic_input_value = +// MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, +// exp_param->decay); +} //! \brief helper function to add input for a given timer period to a given //! neuron //! \param[in,out] parameter: the parameter to update //! \param[in] input: the input to add. static inline void add_input_exp(exp_state_t *parameter, input_t input) { -// parameter->synaptic_input_value = parameter->synaptic_input_value + -// decay_s1615(input, parameter->init); parameter->synaptic_input_value = parameter->synaptic_input_value + - MULT_ROUND_NEAREST_ACCUM(input, parameter->init); + decay_s1615(input, parameter->init); +// parameter->synaptic_input_value = parameter->synaptic_input_value + +// MULT_ROUND_NEAREST_ACCUM(input, parameter->init); } diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py index 666fd5384f9..6043747a568 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/splitter_abstract_pop_vertex_fixed.py @@ -104,22 +104,21 @@ def create_machine_vertices(self, chip_counter): app_vertex.get_max_atoms_per_core(), app_vertex.n_atoms) ring_buffer_shifts = None - if self.__ring_buffer_shifts is None: - app_vertex = self._governed_app_vertex - if (hasattr(app_vertex, "rb_left_shifts") and - app_vertex.rb_left_shifts is not None): - print("=" * 80) - print("Using given values for RB left shifts.") - ring_buffer_shifts = app_vertex.rb_left_shifts - print("RB left shifts for {:20}".format(app_vertex.label), - "=", ring_buffer_shifts) - print("-" * 80) - else: - print("=" * 80) - print("Computing RB left shifts for", app_vertex.label) - ring_buffer_shifts = app_vertex.get_ring_buffer_shifts() - print("RB left shifts for {:20}".format(app_vertex.label), - "=", ring_buffer_shifts) + app_vertex = self._governed_app_vertex + if (hasattr(app_vertex, "rb_left_shifts") and + app_vertex.rb_left_shifts is not None): + print("=" * 80) + print("Using given values for RB left shifts.") + ring_buffer_shifts = app_vertex.rb_left_shifts + print("RB left shifts for {:20}".format(app_vertex.label), + "=", ring_buffer_shifts) + print("-" * 80) + else: + print("=" * 80) + print("Computing RB left shifts for", app_vertex.label) + ring_buffer_shifts = app_vertex.get_ring_buffer_shifts() + print("RB left shifts for {:20}".format(app_vertex.label), + "=", ring_buffer_shifts) weight_scales = app_vertex.get_weight_scales(ring_buffer_shifts) all_syn_block_sz = app_vertex.get_synapses_size( diff --git a/spynnaker/pyNN/models/neuron/population_machine_vertex.py b/spynnaker/pyNN/models/neuron/population_machine_vertex.py index b25a6414007..b8cff871079 100644 --- a/spynnaker/pyNN/models/neuron/population_machine_vertex.py +++ b/spynnaker/pyNN/models/neuron/population_machine_vertex.py @@ -42,21 +42,21 @@ class SpikeProcessingProvenance(ctypes.LittleEndianStructure): # The number of packets that were dropped due to being late ("n_late_packets", ctypes.c_uint32), # The maximum size of the spike input buffer during simulation - ("max_size_input_buffer", ctypes.c_uint32), - # Custom provenance from SpiNNCer - max spikes in a tick - ("max_spikes_in_a_tick", ctypes.c_uint32), - # max dmas in a tick - ("max_dmas_in_a_tick", ctypes.c_uint32), - # max pipeline restarts - ("max_pipeline_restarts", ctypes.c_uint32), - # timer callback completed? - ("timer_callback_completed", ctypes.c_uint32), - # spikes pipeline activated? - ("spikes_pipeline_activated", ctypes.c_uint32), - # Max flushed spikes in a timestep - ("max_flushed_spikes", ctypes.c_uint32), - # Total flushed spikes - ("total_flushed_spikes", ctypes.c_uint32) + ("max_size_input_buffer", ctypes.c_uint32) + # # Custom provenance from SpiNNCer - max spikes in a tick + # ("max_spikes_in_a_tick", ctypes.c_uint32), + # # max dmas in a tick + # ("max_dmas_in_a_tick", ctypes.c_uint32), + # # max pipeline restarts + # ("max_pipeline_restarts", ctypes.c_uint32), + # # timer callback completed? + # ("timer_callback_completed", ctypes.c_uint32), + # # spikes pipeline activated? + # ("spikes_pipeline_activated", ctypes.c_uint32), + # # Max flushed spikes in a timestep + # ("max_flushed_spikes", ctypes.c_uint32), + # # Total flushed spikes + # ("total_flushed_spikes", ctypes.c_uint32) ] N_ITEMS = len(_fields_) @@ -104,15 +104,15 @@ class PopulationMachineVertex( MAX_FILLED_SIZE_OF_INPUT_BUFFER_NAME = "Max_filled_size_input_buffer" BACKGROUND_OVERLOADS_NAME = "Times_the_background_queue_overloaded" BACKGROUND_MAX_QUEUED_NAME = "Max_backgrounds_queued" - # Custom provenance from SpiNNCer - MAX_SPIKES_IN_A_TICK = "Maximum number of spikes in a timer tick" - MAX_DMAS_IN_A_TICK = "Maximum number of DMAs in a timer tick" - MAX_PIPELINE_RESTARTS = "Maximum pipeline restarts" - TIMER_CALLBACK_COMPLETED = "Was the timer callback completed?" - SPIKES_PIPELINE_ACTIVATED = "Was the spikes pipeline activated?" - # Flushed spikes - MAX_FLUSHED_SPIKES = "Maximum number of spikes flushed in a timer tick" - TOTAL_FLUSHED_SPIKES = "Total number of spikes flushed" + # # Custom provenance from SpiNNCer + # MAX_SPIKES_IN_A_TICK = "Maximum number of spikes in a timer tick" + # MAX_DMAS_IN_A_TICK = "Maximum number of DMAs in a timer tick" + # MAX_PIPELINE_RESTARTS = "Maximum pipeline restarts" + # TIMER_CALLBACK_COMPLETED = "Was the timer callback completed?" + # SPIKES_PIPELINE_ACTIVATED = "Was the spikes pipeline activated?" + # # Flushed spikes + # MAX_FLUSHED_SPIKES = "Maximum number of spikes flushed in a timer tick" + # TOTAL_FLUSHED_SPIKES = "Total number of spikes flushed" class REGIONS(Enum): """Regions for populations.""" @@ -412,49 +412,49 @@ def _parse_spike_processing_provenance( x, y, p, self.MAX_FILLED_SIZE_OF_INPUT_BUFFER_NAME, prov.max_size_input_buffer) - # SpiNNCer - db.insert_core( - x, y, p, self.MAX_SPIKES_IN_A_TICK, - prov.max_spikes_in_a_tick) - if prov.max_spikes_in_a_tick > 200: - db.insert_report( - f"Max number of spikes for {label} was " - f"{prov.max_spikes_in_a_tick}. Empirically, we " - f"can deal with ~200 for real time performance using a " - f"1.0 ms timestep.") - - db.insert_core( - x, y, p, self.MAX_DMAS_IN_A_TICK, - prov.max_dmas_in_a_tick) - - db.insert_core( - x, y, p, self.MAX_PIPELINE_RESTARTS, - prov.max_pipeline_restarts) - - db.insert_core( - x, y, p, self.TIMER_CALLBACK_COMPLETED, - prov.timer_callback_completed) - - db.insert_core( - x, y, p, self.SPIKES_PIPELINE_ACTIVATED, - prov.spikes_pipeline_activated) - - # FLUSHED SPIKES - db.insert_core( - x, y, p, self.MAX_FLUSHED_SPIKES, - prov.max_flushed_spikes) - if prov.max_flushed_spikes > 0: - db.insert_report( - f"Max number of flushed spikes for {label} was " - f"was {prov.max_flushed_spikes}.") - - db.insert_core( - x, y, p, self.TOTAL_FLUSHED_SPIKES, - prov.total_flushed_spikes) - if prov.total_flushed_spikes > 0: - db.insert_report( - f"Total number of flushed spikes for {label} was " - f"{prov.total_flushed_spikes}.") + # # SpiNNCer + # db.insert_core( + # x, y, p, self.MAX_SPIKES_IN_A_TICK, + # prov.max_spikes_in_a_tick) + # if prov.max_spikes_in_a_tick > 200: + # db.insert_report( + # f"Max number of spikes for {label} was " + # f"{prov.max_spikes_in_a_tick}. Empirically, we " + # f"can deal with ~200 for real time performance using a " + # f"1.0 ms timestep.") + # + # db.insert_core( + # x, y, p, self.MAX_DMAS_IN_A_TICK, + # prov.max_dmas_in_a_tick) + # + # db.insert_core( + # x, y, p, self.MAX_PIPELINE_RESTARTS, + # prov.max_pipeline_restarts) + # + # db.insert_core( + # x, y, p, self.TIMER_CALLBACK_COMPLETED, + # prov.timer_callback_completed) + # + # db.insert_core( + # x, y, p, self.SPIKES_PIPELINE_ACTIVATED, + # prov.spikes_pipeline_activated) + # + # # FLUSHED SPIKES + # db.insert_core( + # x, y, p, self.MAX_FLUSHED_SPIKES, + # prov.max_flushed_spikes) + # if prov.max_flushed_spikes > 0: + # db.insert_report( + # f"Max number of flushed spikes for {label} was " + # f"was {prov.max_flushed_spikes}.") + # + # db.insert_core( + # x, y, p, self.TOTAL_FLUSHED_SPIKES, + # prov.total_flushed_spikes) + # if prov.total_flushed_spikes > 0: + # db.insert_report( + # f"Total number of flushed spikes for {label} was " + # f"{prov.total_flushed_spikes}.") @overrides(PopulationMachineNeurons.set_do_neuron_regeneration) def set_do_neuron_regeneration(self): diff --git a/spynnaker/pyNN/models/neuron/population_synapses_machine_vertex_common.py b/spynnaker/pyNN/models/neuron/population_synapses_machine_vertex_common.py index 6ffef53a08e..3bea68e030a 100644 --- a/spynnaker/pyNN/models/neuron/population_synapses_machine_vertex_common.py +++ b/spynnaker/pyNN/models/neuron/population_synapses_machine_vertex_common.py @@ -68,7 +68,21 @@ class SpikeProcessingFastProvenance(ctypes.LittleEndianStructure): # The latest time a spike was received ("latest_receive", ctypes.c_uint32), # The maximum overflow of spikes in a time step - ("max_spikes_overflow", ctypes.c_uint32) + ("max_spikes_overflow", ctypes.c_uint32), + # Custom provenance from SpiNNCer - max spikes in a tick + ("max_spikes_in_a_tick", ctypes.c_uint32), + # max dmas in a tick + ("max_dmas_in_a_tick", ctypes.c_uint32), + # max pipeline restarts + ("max_pipeline_restarts", ctypes.c_uint32), + # timer callback completed? + ("timer_callback_completed", ctypes.c_uint32), + # spikes pipeline activated? + ("spikes_pipeline_activated", ctypes.c_uint32), + # Max flushed spikes in a timestep + ("max_flushed_spikes", ctypes.c_uint32), + # Total flushed spikes + ("total_flushed_spikes", ctypes.c_uint32) ] N_ITEMS = len(_fields_) @@ -95,6 +109,16 @@ class PopulationSynapsesMachineVertexCommon( LATEST_RECEIVE = "Latest_receive_time" MAX_SPIKE_OVERFLOW = "Max_spike_overflow_in_time_step" + # Custom provenance from SpiNNCer + MAX_SPIKES_IN_A_TICK = "Maximum number of spikes in a timer tick" + MAX_DMAS_IN_A_TICK = "Maximum number of DMAs in a timer tick" + MAX_PIPELINE_RESTARTS = "Maximum pipeline restarts" + TIMER_CALLBACK_COMPLETED = "Was the timer callback completed?" + SPIKES_PIPELINE_ACTIVATED = "Was the spikes pipeline activated?" + # Flushed spikes + MAX_FLUSHED_SPIKES = "Maximum number of spikes flushed in a timer tick" + TOTAL_FLUSHED_SPIKES = "Total number of spikes flushed" + __slots__ = [ "__sdram_partition", "__neuron_vertex", @@ -369,3 +393,47 @@ def _parse_spike_processing_fast_provenance( x, y, p, self.LATEST_RECEIVE, prov.latest_receive) db.insert_core( x, y, p, self.MAX_SPIKE_OVERFLOW, prov.max_spikes_overflow) + + # SpiNNCer + db.insert_core( + x, y, p, self.MAX_SPIKES_IN_A_TICK, + prov.max_spikes_in_a_tick) + if prov.max_spikes_in_a_tick > 200: + db.insert_report( + f"Max number of spikes for {label} was " + f"{prov.max_spikes_in_a_tick}. Empirically, we " + f"can deal with ~200 for real time performance using a " + f"1.0 ms timestep.") + + db.insert_core( + x, y, p, self.MAX_DMAS_IN_A_TICK, + prov.max_dmas_in_a_tick) + + db.insert_core( + x, y, p, self.MAX_PIPELINE_RESTARTS, + prov.max_pipeline_restarts) + + db.insert_core( + x, y, p, self.TIMER_CALLBACK_COMPLETED, + prov.timer_callback_completed) + + db.insert_core( + x, y, p, self.SPIKES_PIPELINE_ACTIVATED, + prov.spikes_pipeline_activated) + + # FLUSHED SPIKES + db.insert_core( + x, y, p, self.MAX_FLUSHED_SPIKES, + prov.max_flushed_spikes) + if prov.max_flushed_spikes > 0: + db.insert_report( + f"Max number of flushed spikes for {label} was " + f"was {prov.max_flushed_spikes}.") + + db.insert_core( + x, y, p, self.TOTAL_FLUSHED_SPIKES, + prov.total_flushed_spikes) + if prov.total_flushed_spikes > 0: + db.insert_report( + f"Total number of flushed spikes for {label} was " + f"{prov.total_flushed_spikes}.") From 1204c5576c9f569fcae5e0cfe9787870ce84caa8 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 1 Dec 2022 17:47:38 +0000 Subject: [PATCH 57/66] Seems like this UFRACT is the culprit --- neural_modelling/src/neuron/models/neuron_model_lif_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index a024f9838aa..d880d88a462 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -68,7 +68,7 @@ struct neuron_t { //! 'fixed' computation parameter - time constant multiplier for //! closed-form solution //! exp(-(machine time step in ms)/(R * C)) [.] - UFRACT exp_TC; + REAL exp_TC; //! offset current [nA] REAL I_offset; From 2feb571e26f77258265eba7458851a21781c8472 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Fri, 2 Dec 2022 13:06:21 +0000 Subject: [PATCH 58/66] Only need to sum g_syn on the first step --- .../implementations/neuron_impl_standard.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index ed11fc37f66..e801423fd91 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -273,19 +273,19 @@ static void neuron_impl_do_timestep_update( input_t *inh_input_values = input_type_get_input_value( inh_syn_values, input_types, NUM_INHIBITORY_RECEPTORS); - // Sum g_syn contributions from all receptors for recording - REAL total_exc = ZERO; - REAL total_inh = ZERO; - - for (int i = 0; i < NUM_EXCITATORY_RECEPTORS; i++) { - total_exc += exc_input_values[i]; - } - for (int i = 0; i < NUM_INHIBITORY_RECEPTORS; i++) { - total_inh += inh_input_values[i]; - } - // Do recording if on the first step if (i_step == n_steps_per_timestep) { + // Sum g_syn contributions from all receptors for recording + REAL total_exc = ZERO; + REAL total_inh = ZERO; + + for (int i = 0; i < NUM_EXCITATORY_RECEPTORS; i++) { + total_exc += exc_input_values[i]; + } + for (int i = 0; i < NUM_INHIBITORY_RECEPTORS; i++) { + total_inh += inh_input_values[i]; + } + neuron_recording_record_accum( V_RECORDING_INDEX, neuron_index, soma_voltage); neuron_recording_record_accum( From 543e8f7755a25da0ae1e77aa29e842ba7ae95ffc Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Fri, 2 Dec 2022 13:09:47 +0000 Subject: [PATCH 59/66] Put the rounding multiplications back in... --- .../src/neuron/models/neuron_model_lif_impl.h | 14 +++++++------- .../neuron/synapse_types/exp_synapse_utils.h | 19 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index d880d88a462..2555a88d8b0 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -21,7 +21,7 @@ #define _NEURON_MODEL_LIF_CURR_IMPL_H_ #include "neuron_model.h" -//#include "round.h" +#include "round.h" //! definition for LIF neuron parameters struct neuron_params_t { @@ -121,15 +121,15 @@ static inline void neuron_model_save_state(neuron_t *state, neuron_params_t *par static inline void lif_neuron_closed_form( neuron_t *neuron, REAL V_prev, input_t input_this_timestep) { // accum = accum * accum + accum - REAL alpha = (input_this_timestep * neuron->R_membrane) + neuron->V_rest; -// REAL alpha = MULT_ROUND_NEAREST_ACCUM( -// input_this_timestep, neuron->R_membrane) + neuron->V_rest; +// REAL alpha = (input_this_timestep * neuron->R_membrane) + neuron->V_rest; + REAL alpha = MULT_ROUND_NEAREST_ACCUM( + input_this_timestep, neuron->R_membrane) + neuron->V_rest; // update membrane voltage // accum - (ufract * (accum - accum)) - neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); -// neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( -// neuron->exp_TC, (alpha - V_prev)); +// neuron->V_membrane = alpha - (neuron->exp_TC * (alpha - V_prev)); + neuron->V_membrane = alpha - MULT_ROUND_NEAREST_ACCUM( + neuron->exp_TC, (alpha - V_prev)); } //! \brief primary function called in timer loop after synaptic updates diff --git a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h index 731d9c4c105..f047004e655 100644 --- a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h +++ b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h @@ -22,7 +22,7 @@ #include #include -//#include "round.h" +#include "round.h" //! The type of exponential decay parameters typedef struct exp_params_t { @@ -61,11 +61,11 @@ static inline void decay_and_init(exp_state_t *state, exp_params_t *params, //! \param[in,out] exp_param: The parameter to shape static inline void exp_shaping(exp_state_t *exp_param) { // decay value according to decay constant - exp_param->synaptic_input_value = - decay_s1615(exp_param->synaptic_input_value, exp_param->decay); -// exp_param->synaptic_input_value = -// MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, -// exp_param->decay); +// exp_param->synaptic_input_value = +// decay_s1615(exp_param->synaptic_input_value, exp_param->decay); + exp_param->synaptic_input_value = + MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, + exp_param->decay); } //! \brief helper function to add input for a given timer period to a given @@ -73,9 +73,8 @@ static inline void exp_shaping(exp_state_t *exp_param) { //! \param[in,out] parameter: the parameter to update //! \param[in] input: the input to add. static inline void add_input_exp(exp_state_t *parameter, input_t input) { - parameter->synaptic_input_value = parameter->synaptic_input_value + - decay_s1615(input, parameter->init); // parameter->synaptic_input_value = parameter->synaptic_input_value + -// MULT_ROUND_NEAREST_ACCUM(input, parameter->init); - +// decay_s1615(input, parameter->init); + parameter->synaptic_input_value = parameter->synaptic_input_value + + MULT_ROUND_NEAREST_ACCUM(input, parameter->init); } From 001e4d93145a86a0a09e8c31fedb7fade732c8d9 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 5 Dec 2022 13:42:19 +0000 Subject: [PATCH 60/66] Save ITCM --- .../additional_input_ca2_adaptive_impl.h | 2 +- neural_modelling/src/neuron/c_main.c | 6 ++-- .../implementations/neuron_impl_standard.h | 28 +++++++++---------- .../src/neuron/models/neuron_model_izh_impl.h | 2 +- .../src/neuron/models/neuron_model_lif_impl.h | 2 +- .../neuron/synapse_types/exp_synapse_utils.h | 18 ++++++------ .../synapse_types/synapse_types_alpha_impl.h | 8 +++--- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/neural_modelling/src/neuron/additional_inputs/additional_input_ca2_adaptive_impl.h b/neural_modelling/src/neuron/additional_inputs/additional_input_ca2_adaptive_impl.h index 24d404a3d70..d622dcf1869 100644 --- a/neural_modelling/src/neuron/additional_inputs/additional_input_ca2_adaptive_impl.h +++ b/neural_modelling/src/neuron/additional_inputs/additional_input_ca2_adaptive_impl.h @@ -77,7 +77,7 @@ static inline input_t additional_input_get_input_value_as_current( additional_input->i_ca2 *= additional_input->exp_tau_ca2; // Return the Ca2 - return -additional_input->i_ca2; + return additional_input->i_ca2; } //! \brief Notifies the additional input type that the neuron has spiked diff --git a/neural_modelling/src/neuron/c_main.c b/neural_modelling/src/neuron/c_main.c index b11909a47be..4bd4c6462dd 100644 --- a/neural_modelling/src/neuron/c_main.c +++ b/neural_modelling/src/neuron/c_main.c @@ -161,9 +161,9 @@ static inline void process_ring_buffers(void) { neuron_transfer(&ring_buffers[first_index]); // Print the neuron inputs. - #if LOG_LEVEL >= LOG_DEBUG - neuron_print_inputs(); - #endif // LOG_LEVEL >= LOG_DEBUG +#if LOG_LEVEL >= LOG_DEBUG + neuron_print_inputs(); +#endif // LOG_LEVEL >= LOG_DEBUG } //! \brief Background activities called from timer diff --git a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h index e801423fd91..95960bb940b 100644 --- a/neural_modelling/src/neuron/implementations/neuron_impl_standard.h +++ b/neural_modelling/src/neuron/implementations/neuron_impl_standard.h @@ -252,7 +252,7 @@ static void neuron_impl_do_timestep_update( additional_input_t *additional_inputs = &additional_input_array[neuron_index]; synapse_types_t *the_synapse_type = &synapse_types_array[neuron_index]; - bool spike = false; +// bool spike = false; // Loop however many times requested; do this in reverse for efficiency, // and because the index doesn't actually matter @@ -320,7 +320,7 @@ static void neuron_impl_do_timestep_update( // If spike occurs, communicate to relevant parts of model if (spike_now) { - spike = true; +// spike = true; // Call relevant model-based functions // Tell the neuron model @@ -329,11 +329,11 @@ static void neuron_impl_do_timestep_update( // Tell the additional input additional_input_has_spiked(additional_inputs); -// // Record the spike -// neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); -// -// // Send the spike -// send_spike(timer_count, time, neuron_index); + // Record the spike + neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); + + // Send the spike + send_spike(timer_count, time, neuron_index); } // Shape the existing input according to the included rule @@ -344,13 +344,13 @@ static void neuron_impl_do_timestep_update( neuron_model_print_state_variables(this_neuron); #endif // LOG_LEVEL >= LOG_DEBUG - if (spike) { - // Record the spike - neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); - - // Send the spike - send_spike(timer_count, time, neuron_index); - } +// if (spike) { +// // Record the spike +// neuron_recording_record_bit(SPIKE_RECORDING_BITFIELD, neuron_index); +// +// // Send the spike +// send_spike(timer_count, time, neuron_index); +// } } } diff --git a/neural_modelling/src/neuron/models/neuron_model_izh_impl.h b/neural_modelling/src/neuron/models/neuron_model_izh_impl.h index a9f6c5d2e04..ac5912d2693 100644 --- a/neural_modelling/src/neuron/models/neuron_model_izh_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_izh_impl.h @@ -179,7 +179,7 @@ static inline state_t neuron_model_state_update( } input_t input_this_timestep = total_exc - total_inh - + external_bias + neuron->I_offset + current_offset; + - external_bias + neuron->I_offset + current_offset; // the best AR update so far rk2_kernel_midpoint(neuron->this_h, neuron, input_this_timestep); diff --git a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h index 2555a88d8b0..35001e4b0c5 100644 --- a/neural_modelling/src/neuron/models/neuron_model_lif_impl.h +++ b/neural_modelling/src/neuron/models/neuron_model_lif_impl.h @@ -165,7 +165,7 @@ static inline state_t neuron_model_state_update( } // Get the input in nA input_t input_this_timestep = - total_exc - total_inh + external_bias + neuron->I_offset + current_offset; + total_exc - total_inh - external_bias + neuron->I_offset + current_offset; lif_neuron_closed_form( neuron, neuron->V_membrane, input_this_timestep); diff --git a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h index f047004e655..cd59c0692e5 100644 --- a/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h +++ b/neural_modelling/src/neuron/synapse_types/exp_synapse_utils.h @@ -22,7 +22,7 @@ #include #include -#include "round.h" +//#include "round.h" //! The type of exponential decay parameters typedef struct exp_params_t { @@ -61,11 +61,11 @@ static inline void decay_and_init(exp_state_t *state, exp_params_t *params, //! \param[in,out] exp_param: The parameter to shape static inline void exp_shaping(exp_state_t *exp_param) { // decay value according to decay constant -// exp_param->synaptic_input_value = -// decay_s1615(exp_param->synaptic_input_value, exp_param->decay); - exp_param->synaptic_input_value = - MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, - exp_param->decay); + exp_param->synaptic_input_value = + decay_s1615(exp_param->synaptic_input_value, exp_param->decay); +// exp_param->synaptic_input_value = +// MULT_ROUND_NEAREST_ACCUM(exp_param->synaptic_input_value, +// exp_param->decay); } //! \brief helper function to add input for a given timer period to a given @@ -73,8 +73,8 @@ static inline void exp_shaping(exp_state_t *exp_param) { //! \param[in,out] parameter: the parameter to update //! \param[in] input: the input to add. static inline void add_input_exp(exp_state_t *parameter, input_t input) { -// parameter->synaptic_input_value = parameter->synaptic_input_value + -// decay_s1615(input, parameter->init); parameter->synaptic_input_value = parameter->synaptic_input_value + - MULT_ROUND_NEAREST_ACCUM(input, parameter->init); + decay_s1615(input, parameter->init); +// parameter->synaptic_input_value = parameter->synaptic_input_value + +// MULT_ROUND_NEAREST_ACCUM(input, parameter->init); } diff --git a/neural_modelling/src/neuron/synapse_types/synapse_types_alpha_impl.h b/neural_modelling/src/neuron/synapse_types/synapse_types_alpha_impl.h index 5c4310e8869..581490207a0 100644 --- a/neural_modelling/src/neuron/synapse_types/synapse_types_alpha_impl.h +++ b/neural_modelling/src/neuron/synapse_types/synapse_types_alpha_impl.h @@ -145,9 +145,9 @@ static inline void add_input_alpha(alpha_state_t *a_params, input_t input) { a_params->exp_buff = decay_s1615(a_params->exp_buff, a_params->decay) + ONE; - a_params->lin_buff = - (a_params->lin_buff + (input * a_params->dt_divided_by_tau_sqr)) - * (ONE - kdivk(ONE, a_params->exp_buff)); + REAL exp_temp = ONE - kdivk(ONE, a_params->exp_buff); + a_params->lin_buff = (a_params->lin_buff + ( + input * a_params->dt_divided_by_tau_sqr)) * exp_temp; } //! \brief adds the inputs for a give timer period to a given neuron that is @@ -222,7 +222,7 @@ static inline const char *synapse_types_get_type_char( //! \param[in] parameters: the pointer to the parameters to print static inline void synapse_types_print_input( synapse_types_t *parameters) { - io_printf(IO_BUF, "%12.6k - %12.6k", + log_debug("%12.6k - %12.6k", parameters->exc.lin_buff * parameters->exc.exp_buff, parameters->inh.lin_buff * parameters->inh.exp_buff); } From c2de26b13aed405792761f9d95288dbd760da580 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 5 Dec 2022 14:02:20 +0000 Subject: [PATCH 61/66] vera remove trailing line --- neural_modelling/src/neuron/spike_processing_fast.c | 1 - 1 file changed, 1 deletion(-) diff --git a/neural_modelling/src/neuron/spike_processing_fast.c b/neural_modelling/src/neuron/spike_processing_fast.c index 2c698e609c4..72c1fb37fd2 100644 --- a/neural_modelling/src/neuron/spike_processing_fast.c +++ b/neural_modelling/src/neuron/spike_processing_fast.c @@ -713,4 +713,3 @@ uint32_t spike_processing_get_total_flushed_spikes(){ uint32_t spike_processing_get_max_flushed_spikes(){ return max_flushed_spikes; } - From 7ea6378b2984d492ee9ac8c08c0c18fd779c4bca Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Tue, 17 Jan 2023 12:14:40 +0000 Subject: [PATCH 62/66] Try 16 delay tics by default --- .../abstract_spynnaker_splitter_delay.py | 2 +- .../model_tests/neuron/test_synaptic_manager.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py index 2a78e4b82bc..29f799e00aa 100644 --- a/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py +++ b/spynnaker/pyNN/extra_algorithms/splitter_components/abstract_spynnaker_splitter_delay.py @@ -28,7 +28,7 @@ class AbstractSpynnakerSplitterDelay(object, metaclass=AbstractBase): __slots__ = [] # max delays supported by a slice split machine vertex - MAX_SUPPORTED_DELAY_TICS = 64 # can this be 16? + MAX_SUPPORTED_DELAY_TICS = 16 def max_support_delay(self): """ diff --git a/unittests/model_tests/neuron/test_synaptic_manager.py b/unittests/model_tests/neuron/test_synaptic_manager.py index 0ed9b3e0f67..8d37b84d653 100644 --- a/unittests/model_tests/neuron/test_synaptic_manager.py +++ b/unittests/model_tests/neuron/test_synaptic_manager.py @@ -407,23 +407,23 @@ def test_set_synapse_dynamics(): # Only undelayed, all edges exist (range(10), [], 1000, 100, None), # Only delayed, all edges exist (note max_delay=20 on master) - ([], range(10), 1000, 100, 100), + ([], range(10), 1000, 100, 20), # All undelayed and delayed edges exist - (range(10), range(10), 1000, 100, 100), + (range(10), range(10), 1000, 100, 20), # Only undelayed, some connections missing but app keys can still work ([0, 1, 2, 3, 4], [], 1000, 100, None), # Only delayed, some connections missing but app keys can still work - ([], [5, 6, 7, 8, 9], 1000, 100, 100), + ([], [5, 6, 7, 8, 9], 1000, 100, 20), # Both delayed and undelayed, some undelayed edges don't exist # (app keys work because undelayed aren't filtered) - ([3, 4, 5, 6, 7], range(10), 1000, 100, 100), + ([3, 4, 5, 6, 7], range(10), 1000, 100, 20), # Both delayed and undelayed, some delayed edges don't exist # (app keys work because all undelayed exist) - (range(10), [4, 5, 6, 7], 1000, 100, 100), + (range(10), [4, 5, 6, 7], 1000, 100, 20), # Should work but number of cores doesn't work out (range(2000), [], 10000, 5, None), # Should work but number of neurons with delays don't work out - ([], range(4), 1024, 256, 576) # 144 on master + ([], range(4), 1024, 256, 144) ]) def test_pop_based_master_pop_table_standard( undelayed_indices_connected, delayed_indices_connected, From ed6aad6dcc2f539c4a551c43b0ac472ed265605e Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 6 Mar 2023 14:22:17 +0000 Subject: [PATCH 63/66] Turn this error off for now --- neural_modelling/src/common/send_mc.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neural_modelling/src/common/send_mc.h b/neural_modelling/src/common/send_mc.h index 871676bce13..5c1f9848aaf 100644 --- a/neural_modelling/src/common/send_mc.h +++ b/neural_modelling/src/common/send_mc.h @@ -32,10 +32,10 @@ static inline void wait_for_cc(void) { spin1_delay_us(1); n_loops++; } - if (!(cc[CC_TCR] & TX_NOT_FULL_MASK)) { - log_error("Couldn't send spike; TCR=0x%08x\n", cc[CC_TCR]); - rt_error(RTE_SWERR); - } +// if (!(cc[CC_TCR] & TX_NOT_FULL_MASK)) { +// log_error("Couldn't send spike; TCR=0x%08x\n", cc[CC_TCR]); +// rt_error(RTE_SWERR); +// } } //! \brief Perform direct spike sending with hardware for speed From c2cbfaa1280e205fe0cb3cf705d549fa83aef2dd Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Fri, 7 Jul 2023 13:58:14 +0100 Subject: [PATCH 64/66] Update license --- neural_modelling/src/neuron/spike_profiling.h | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/neural_modelling/src/neuron/spike_profiling.h b/neural_modelling/src/neuron/spike_profiling.h index 958dfd858b5..225d479c7b2 100644 --- a/neural_modelling/src/neuron/spike_profiling.h +++ b/neural_modelling/src/neuron/spike_profiling.h @@ -1,18 +1,17 @@ /* - * Copyright (c) 2017-2021 The University of Manchester + * Copyright (c) 2021 The University of Manchester * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * https://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include From 220e8668bf4fdb0dee5ad9f2ed97258c4141c904 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Fri, 21 Jul 2023 15:01:17 +0100 Subject: [PATCH 65/66] Missed a license --- .../makefiles/neuron/IF_cond_alpha/Makefile | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile b/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile index 45546379d5f..99f7033f24b 100644 --- a/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile +++ b/neural_modelling/makefiles/neuron/IF_cond_alpha/Makefile @@ -1,17 +1,16 @@ -# Copyright (c) 2017-2019 The University of Manchester +# Copyright (c) 2017 The University of Manchester # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# https://www.apache.org/licenses/LICENSE-2.0 # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. APP = $(notdir $(CURDIR)) From 5a62341b7b99b7542fc6ea7944320755f47d124c Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Wed, 2 Aug 2023 16:11:00 +0100 Subject: [PATCH 66/66] flake8 --- unittests/model_tests/neuron/test_synaptic_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittests/model_tests/neuron/test_synaptic_manager.py b/unittests/model_tests/neuron/test_synaptic_manager.py index 7e313550600..631b617f9cd 100644 --- a/unittests/model_tests/neuron/test_synaptic_manager.py +++ b/unittests/model_tests/neuron/test_synaptic_manager.py @@ -31,8 +31,8 @@ from spinn_front_end_common.interface.interface_functions import ( load_application_data_specs) from spynnaker.pyNN.data.spynnaker_data_writer import SpynnakerDataWriter -from spynnaker.pyNN.models.neuron.synaptic_matrices import SynapticMatrices,\ - SynapseRegions +from spynnaker.pyNN.models.neuron.synaptic_matrices import ( + SynapticMatrices, SynapseRegions) from spynnaker.pyNN.models.neuron.synapse_dynamics import ( SynapseDynamicsStatic, SynapseDynamicsStructuralSTDP, SynapseDynamicsSTDP, SynapseDynamicsStructuralStatic,