def test_get_max_row_bytes(dynamics, size, exception, max_size): io = SynapseIORowBased() population_table = MasterPopTableAsBinarySearch() synapse_information = SynapseInformation(None, dynamics, 0) in_edge = ProjectionApplicationEdge(None, None, synapse_information) if exception is not None: with pytest.raises(exception) as exc_info: io._get_max_row_bytes(size, dynamics, population_table, in_edge, size) assert exc_info.value.max_size == max_size else: actual_size = io._get_max_row_bytes(size, dynamics, population_table, in_edge, size) assert actual_size == max_size
def test_slices(): unittest_setup() app_edge = ProjectionApplicationEdge(None, None, None) mv0_2 = SimpleMachineVertex(None, None, None, None, Slice(0, 1)) mv2_4 = SimpleMachineVertex(None, None, None, None, Slice(2, 3)) mv4_6 = SimpleMachineVertex(None, None, None, None, Slice(4, 5)) app_edge.remember_associated_machine_edge(MachineEdge(mv0_2, mv2_4)) app_edge.remember_associated_machine_edge(MachineEdge(mv4_6, mv0_2)) app_edge.remember_associated_machine_edge(MachineEdge(mv0_2, mv2_4)) assert app_edge.pre_slices == [Slice(0, 1), Slice(4, 5)] post1 = app_edge.post_slices assert post1 == [Slice(0, 1), Slice(2, 3)] app_edge.remember_associated_machine_edge(MachineEdge(mv0_2, mv0_2)) app_edge.remember_associated_machine_edge(MachineEdge(mv2_4, mv2_4)) assert app_edge.pre_slices == [Slice(0, 1), Slice(2, 3), Slice(4, 5)] post2 = app_edge.post_slices assert post1 == post2 assert id(post1) != id(post2)
def test_get_allowed_row_length(dynamics_class, timing, weight, size, exception, max_size): spynnaker8.setup() if timing is not None and weight is not None: dynamics = dynamics_class(timing(), weight()) else: dynamics = dynamics_class() synapse_information = SynapseInformation(None, None, None, False, False, None, None, dynamics, 0, True) in_edge = ProjectionApplicationEdge(None, None, synapse_information) if exception is not None: with pytest.raises(exception) as exc_info: _get_allowed_row_length(size, dynamics, in_edge, size) assert exc_info.value.max_size == max_size else: actual_size = _get_allowed_row_length(size, dynamics, in_edge, size) assert actual_size == max_size
def test_get_max_row_length(dynamics_class, timing, weight, size, exception, max_size): MockSimulator.setup() if timing is not None and weight is not None: dynamics = dynamics_class(timing(), weight()) else: dynamics = dynamics_class() io = SynapseIORowBased() population_table = MasterPopTableAsBinarySearch() synapse_information = SynapseInformation(None, None, None, None, None, None, dynamics, 0) in_edge = ProjectionApplicationEdge(None, None, synapse_information) if exception is not None: with pytest.raises(exception) as exc_info: io._get_max_row_length(size, dynamics, population_table, in_edge, size) assert exc_info.value.max_size == max_size else: actual_size = io._get_max_row_length(size, dynamics, population_table, in_edge, size) assert actual_size == max_size
def __init__(self, spinnaker_control, connector, synapse_dynamics_stdp, target, pre_synaptic_population, post_synaptic_population, rng, machine_time_step, user_max_delay, label, time_scale_factor): # pylint: disable=too-many-arguments, too-many-locals self._spinnaker_control = spinnaker_control self._projection_edge = None self._host_based_synapse_list = None self._has_retrieved_synaptic_list_from_machine = False self._requires_mapping = True self._label = None if not isinstance(post_synaptic_population._get_vertex, AbstractAcceptsIncomingSynapses): raise ConfigurationException( "postsynaptic population is not designed to receive" " synaptic projections") # sort out synapse type synapse_type = post_synaptic_population._get_vertex\ .get_synapse_id_by_target(target) if synapse_type is None: raise ConfigurationException( "Synapse target {} not found in {}".format( target, post_synaptic_population.label)) # set the plasticity dynamics for the post pop (allows plastic stuff # when needed) post_synaptic_population._get_vertex.set_synapse_dynamics( synapse_dynamics_stdp) # Set and store information for future processing self._synapse_information = SynapseInformation(connector, synapse_dynamics_stdp, synapse_type) connector.set_projection_information(pre_synaptic_population, post_synaptic_population, rng, machine_time_step) # handle max delay max_delay = synapse_dynamics_stdp.get_delay_maximum(connector) if max_delay is None: max_delay = user_max_delay # check if all delays requested can fit into the natively supported # delays in the models post_vertex_max_supported_delay_ms = \ post_synaptic_population._get_vertex \ .get_maximum_delay_supported_in_ms(machine_time_step) if max_delay > (post_vertex_max_supported_delay_ms + _delay_extension_max_supported_delay): raise ConfigurationException( "The maximum delay {} for projection is not supported".format( max_delay)) if max_delay > user_max_delay / (machine_time_step / 1000.0): logger.warning("The end user entered a max delay" " for which the projection breaks") # check that the projection edges label is not none, and give an # auto generated label if set to None if label is None: label = "projection edge {}".format( spinnaker_control.none_labelled_edge_count) spinnaker_control.increment_none_labelled_edge_count() # Find out if there is an existing edge between the populations edge_to_merge = self._find_existing_edge( pre_synaptic_population._get_vertex, post_synaptic_population._get_vertex) if edge_to_merge is not None: # If there is an existing edge, add the connector edge_to_merge.add_synapse_information(self._synapse_information) self._projection_edge = edge_to_merge else: # If there isn't an existing edge, create a new one self._projection_edge = ProjectionApplicationEdge( pre_synaptic_population._get_vertex, post_synaptic_population._get_vertex, self._synapse_information, label=label) # add edge to the graph spinnaker_control.add_application_edge( self._projection_edge, constants.SPIKE_PARTITION_ID) # If the delay exceeds the post vertex delay, add a delay extension if max_delay > post_vertex_max_supported_delay_ms: delay_edge = self._add_delay_extension( pre_synaptic_population, post_synaptic_population, max_delay, post_vertex_max_supported_delay_ms, machine_time_step, time_scale_factor) self._projection_edge.delay_edge = delay_edge # add projection to the SpiNNaker control system spinnaker_control.add_projection(self) # If there is a virtual board, we need to hold the data in case the # user asks for it self._virtual_connection_list = None if spinnaker_control.use_virtual_board: self._virtual_connection_list = list() pre_vertex = pre_synaptic_population._get_vertex post_vertex = post_synaptic_population._get_vertex connection_holder = ConnectionHolder(None, False, pre_vertex.n_atoms, post_vertex.n_atoms, self._virtual_connection_list) post_vertex.add_pre_run_connection_holder( connection_holder, self._projection_edge, self._synapse_information)
def test_write_synaptic_matrix_and_master_population_table(self): MockSimulator.setup() default_config_paths = os.path.join( os.path.dirname(abstract_spinnaker_common.__file__), AbstractSpiNNakerCommon.CONFIG_FILE_NAME) config = conf_loader.load_config( AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths) config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40) machine_time_step = 1000.0 pre_app_vertex = SimpleApplicationVertex(10) pre_vertex = SimpleMachineVertex(resources=None) pre_vertex_slice = Slice(0, 9) post_app_vertex = SimpleApplicationVertex(10) post_vertex = SimpleMachineVertex(resources=None) post_vertex_slice = Slice(0, 9) post_slice_index = 0 one_to_one_connector_1 = OneToOneConnector(None) one_to_one_connector_1.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) one_to_one_connector_1.set_weights_and_delays(1.5, 1.0) one_to_one_connector_2 = OneToOneConnector(None) one_to_one_connector_2.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) one_to_one_connector_2.set_weights_and_delays(2.5, 2.0) all_to_all_connector = AllToAllConnector(None) all_to_all_connector.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) all_to_all_connector.set_weights_and_delays(4.5, 4.0) direct_synapse_information_1 = SynapseInformation( one_to_one_connector_1, SynapseDynamicsStatic(), 0) direct_synapse_information_2 = SynapseInformation( one_to_one_connector_2, SynapseDynamicsStatic(), 1) all_to_all_synapse_information = SynapseInformation( all_to_all_connector, SynapseDynamicsStatic(), 0) app_edge = ProjectionApplicationEdge(pre_app_vertex, post_app_vertex, direct_synapse_information_1) app_edge.add_synapse_information(direct_synapse_information_2) app_edge.add_synapse_information(all_to_all_synapse_information) machine_edge = ProjectionMachineEdge(app_edge.synapse_information, pre_vertex, post_vertex) partition_name = "TestPartition" graph = MachineGraph("Test") graph.add_vertex(pre_vertex) graph.add_vertex(post_vertex) graph.add_edge(machine_edge, partition_name) graph_mapper = GraphMapper() graph_mapper.add_vertex_mapping(pre_vertex, pre_vertex_slice, pre_app_vertex) graph_mapper.add_vertex_mapping(post_vertex, post_vertex_slice, post_app_vertex) graph_mapper.add_edge_mapping(machine_edge, app_edge) weight_scales = [4096.0, 4096.0] key = 0 routing_info = RoutingInfo() routing_info.add_partition_info( PartitionRoutingInfo( [BaseKeyAndMask(key, 0xFFFFFFF0)], graph.get_outgoing_edge_partition_starting_at_vertex( pre_vertex, partition_name))) temp_spec = tempfile.mktemp() spec_writer = FileDataWriter(temp_spec) spec = DataSpecificationGenerator(spec_writer, None) master_pop_sz = 1000 master_pop_region = 0 all_syn_block_sz = 2000 synapse_region = 1 spec.reserve_memory_region(master_pop_region, master_pop_sz) spec.reserve_memory_region(synapse_region, all_syn_block_sz) synapse_type = MockSynapseType() synaptic_manager = SynapticManager(synapse_type=synapse_type, ring_buffer_sigma=5.0, spikes_per_second=100.0, config=config) synaptic_manager._write_synaptic_matrix_and_master_population_table( spec, [post_vertex_slice], post_slice_index, post_vertex, post_vertex_slice, all_syn_block_sz, weight_scales, master_pop_region, synapse_region, routing_info, graph_mapper, graph, machine_time_step) spec.end_specification() spec_writer.close() spec_reader = FileDataReader(temp_spec) executor = DataSpecificationExecutor(spec_reader, master_pop_sz + all_syn_block_sz) executor.execute() master_pop_table = executor.get_region(0) synaptic_matrix = executor.get_region(1) all_data = bytearray() all_data.extend( master_pop_table.region_data[:master_pop_table.max_write_pointer]) all_data.extend( synaptic_matrix.region_data[:synaptic_matrix.max_write_pointer]) master_pop_table_address = 0 synaptic_matrix_address = master_pop_table.max_write_pointer direct_synapses_address = struct.unpack_from( "<I", synaptic_matrix.region_data)[0] direct_synapses_address += synaptic_matrix_address + 8 indirect_synapses_address = synaptic_matrix_address + 4 placement = Placement(None, 0, 0, 1) transceiver = MockTransceiverRawData(all_data) # Get the master population table details items = synaptic_manager._poptable_type\ .extract_synaptic_matrix_data_location( key, master_pop_table_address, transceiver, placement.x, placement.y) # The first entry should be direct, but the rest should be indirect; # the second is potentially direct, but has been restricted by the # restriction on the size of the direct matrix assert len(items) == 3 # TODO: This has been changed because direct matrices are disabled! assert not items[0][2] assert not items[1][2] assert not items[2][2] data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=0, using_extra_monitor_cores=False) connections_1 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_1, pre_vertex_slice, post_vertex_slice, row_len_1, 0, 2, weight_scales, data_1, None, app_edge.n_delay_stages, machine_time_step) # The first matrix is a 1-1 matrix, so row length is 1 assert row_len_1 == 1 # Check that all the connections have the right weight and delay assert len(connections_1) == post_vertex_slice.n_atoms assert all([conn["weight"] == 1.5 for conn in connections_1]) assert all([conn["delay"] == 1.0 for conn in connections_1]) data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=1, using_extra_monitor_cores=False) connections_2 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_2, pre_vertex_slice, post_vertex_slice, row_len_2, 0, 2, weight_scales, data_2, None, app_edge.n_delay_stages, machine_time_step) # The second matrix is a 1-1 matrix, so row length is 1 assert row_len_2 == 1 # Check that all the connections have the right weight and delay assert len(connections_2) == post_vertex_slice.n_atoms assert all([conn["weight"] == 2.5 for conn in connections_2]) assert all([conn["delay"] == 2.0 for conn in connections_2]) data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=2, using_extra_monitor_cores=False) connections_3 = synaptic_manager._synapse_io.read_synapses( all_to_all_synapse_information, pre_vertex_slice, post_vertex_slice, row_len_3, 0, 2, weight_scales, data_3, None, app_edge.n_delay_stages, machine_time_step) # The third matrix is an all-to-all matrix, so length is n_atoms assert row_len_3 == post_vertex_slice.n_atoms # Check that all the connections have the right weight and delay assert len(connections_3) == \ post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms assert all([conn["weight"] == 4.5 for conn in connections_3]) assert all([conn["delay"] == 4.0 for conn in connections_3])
def __init__(self, pre_synaptic_population, post_synaptic_population, connector, synapse_type=None, source=None, receptor_type=None, space=None, label=None): """ :param ~spynnaker.pyNN.models.populations.PopulationBase \ pre_synaptic_population: :param ~spynnaker.pyNN.models.populations.PopulationBase \ post_synaptic_population: :param AbstractConnector connector: :param AbstractSynapseDynamics synapse_type: :param None source: Unsupported; must be None :param str receptor_type: :param ~pyNN.space.Space space: :param str label: """ # pylint: disable=too-many-arguments, too-many-locals if source is not None: raise NotImplementedError( "sPyNNaker {} does not yet support multi-compartmental " "cells.".format(__version__)) sim = get_simulator() self.__projection_edge = None self.__host_based_synapse_list = None self.__has_retrieved_synaptic_list_from_machine = False self.__requires_mapping = True self.__label = label pre_is_view = self.__check_population(pre_synaptic_population, connector) post_is_view = self.__check_population(post_synaptic_population, connector) # set default label if label is None: # set the projection's label to a default (maybe non-unique!) self.__label = ("from pre {} to post {} with connector {}".format( pre_synaptic_population.label, post_synaptic_population.label, connector)) # give an auto generated label for the underlying edge label = "projection edge {}".format(sim.none_labelled_edge_count) sim.increment_none_labelled_edge_count() # Handle default synapse type if synapse_type is None: synapse_dynamics = SynapseDynamicsStatic() else: synapse_dynamics = synapse_type # set the space function as required if space is None: space = PyNNSpace() connector.set_space(space) pre_vertex = pre_synaptic_population._vertex post_vertex = post_synaptic_population._vertex if not isinstance(post_vertex, AbstractAcceptsIncomingSynapses): raise ConfigurationException( "postsynaptic population is not designed to receive" " synaptic projections") # sort out synapse type synaptic_type = post_vertex.get_synapse_id_by_target(receptor_type) synapse_type_from_dynamics = False if synaptic_type is None: synaptic_type = synapse_dynamics.get_synapse_id_by_target( receptor_type) synapse_type_from_dynamics = True if synaptic_type is None: raise ConfigurationException( "Synapse target {} not found in {}".format( receptor_type, post_synaptic_population.label)) # as a from-list connector can have plastic parameters, grab those ( # if any) and add them to the synapse dynamics object if isinstance(connector, FromListConnector): connector._apply_parameters_to_synapse_type(synaptic_type) # round the delays to multiples of full timesteps # (otherwise SDRAM estimation calculations can go wrong) if ((not isinstance(synapse_dynamics.delay, RandomDistribution)) and (not isinstance(synapse_dynamics.delay, str))): synapse_dynamics.set_delay( numpy.rint( numpy.array(synapse_dynamics.delay) * machine_time_step_per_ms()) * machine_time_step_ms()) # set the plasticity dynamics for the post pop (allows plastic stuff # when needed) post_vertex.set_synapse_dynamics(synapse_dynamics) # get rng if needed rng = connector.rng if hasattr(connector, "rng") else None # Set and store synapse information for future processing self.__synapse_information = SynapseInformation( connector, pre_synaptic_population, post_synaptic_population, pre_is_view, post_is_view, rng, synapse_dynamics, synaptic_type, receptor_type, sim.use_virtual_board, synapse_type_from_dynamics, synapse_dynamics.weight, synapse_dynamics.delay) # Set projection information in connector connector.set_projection_information(self.__synapse_information) # Find out if there is an existing edge between the populations edge_to_merge = self._find_existing_edge(pre_vertex, post_vertex) if edge_to_merge is not None: # If there is an existing edge, add the connector edge_to_merge.add_synapse_information(self.__synapse_information) self.__projection_edge = edge_to_merge else: # If there isn't an existing edge, create a new one and add it self.__projection_edge = ProjectionApplicationEdge( pre_vertex, post_vertex, self.__synapse_information, label=label) sim.add_application_edge(self.__projection_edge, SPIKE_PARTITION_ID) # add projection to the SpiNNaker control system sim.add_projection(self) # If there is a virtual board, we need to hold the data in case the # user asks for it self.__virtual_connection_list = None if sim.use_virtual_board: self.__virtual_connection_list = list() connection_holder = ConnectionHolder( None, False, pre_vertex.n_atoms, post_vertex.n_atoms, self.__virtual_connection_list) self.__synapse_information.add_pre_run_connection_holder( connection_holder) # If the target is a population, add to the list of incoming # projections if isinstance(post_vertex, AbstractPopulationVertex): post_vertex.add_incoming_projection(self) # If the source is a poisson, add to the list of outgoing projections if isinstance(pre_vertex, SpikeSourcePoissonVertex): pre_vertex.add_outgoing_projection(self)
def test_write_synaptic_matrix_and_master_population_table(self): MockSimulator.setup() # Add an sdram so maxsdram is high enough SDRAM(10000) default_config_paths = os.path.join( os.path.dirname(abstract_spinnaker_common.__file__), AbstractSpiNNakerCommon.CONFIG_FILE_NAME) config = conf_loader.load_config( AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths) config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40) machine_time_step = 1000.0 pre_app_vertex = SimpleApplicationVertex(10) pre_vertex = SimpleMachineVertex(resources=None) pre_vertex_slice = Slice(0, 9) post_app_vertex = SimpleApplicationVertex(10) post_vertex = SimpleMachineVertex(resources=None) post_vertex_slice = Slice(0, 9) post_slice_index = 0 one_to_one_connector_1 = OneToOneConnector(None) one_to_one_connector_1.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) one_to_one_connector_2 = OneToOneConnector(None) one_to_one_connector_2.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) all_to_all_connector = AllToAllConnector(None) all_to_all_connector.set_projection_information( pre_app_vertex, post_app_vertex, None, machine_time_step) direct_synapse_information_1 = SynapseInformation( one_to_one_connector_1, SynapseDynamicsStatic(), 0, 1.5, 1.0) direct_synapse_information_2 = SynapseInformation( one_to_one_connector_2, SynapseDynamicsStatic(), 1, 2.5, 2.0) all_to_all_synapse_information = SynapseInformation( all_to_all_connector, SynapseDynamicsStatic(), 0, 4.5, 4.0) app_edge = ProjectionApplicationEdge( pre_app_vertex, post_app_vertex, direct_synapse_information_1) app_edge.add_synapse_information(direct_synapse_information_2) app_edge.add_synapse_information(all_to_all_synapse_information) machine_edge = ProjectionMachineEdge( app_edge.synapse_information, pre_vertex, post_vertex) partition_name = "TestPartition" graph = MachineGraph("Test") graph.add_vertex(pre_vertex) graph.add_vertex(post_vertex) graph.add_edge(machine_edge, partition_name) graph_mapper = GraphMapper() graph_mapper.add_vertex_mapping( pre_vertex, pre_vertex_slice, pre_app_vertex) graph_mapper.add_vertex_mapping( post_vertex, post_vertex_slice, post_app_vertex) graph_mapper.add_edge_mapping(machine_edge, app_edge) weight_scales = [4096.0, 4096.0] key = 0 routing_info = RoutingInfo() routing_info.add_partition_info(PartitionRoutingInfo( [BaseKeyAndMask(key, 0xFFFFFFF0)], graph.get_outgoing_edge_partition_starting_at_vertex( pre_vertex, partition_name))) temp_spec = tempfile.mktemp() spec_writer = FileDataWriter(temp_spec) spec = DataSpecificationGenerator(spec_writer, None) master_pop_sz = 1000 master_pop_region = 0 all_syn_block_sz = 2000 synapse_region = 1 direct_region = 2 spec.reserve_memory_region(master_pop_region, master_pop_sz) spec.reserve_memory_region(synapse_region, all_syn_block_sz) synaptic_manager = SynapticManager( n_synapse_types=2, ring_buffer_sigma=5.0, spikes_per_second=100.0, config=config) # UGLY but the mock transceiver NEED generate_on_machine be False abstract_generate_connector_on_machine.IS_PYNN_8 = False synaptic_manager._write_synaptic_matrix_and_master_population_table( spec, [post_vertex_slice], post_slice_index, post_vertex, post_vertex_slice, all_syn_block_sz, weight_scales, master_pop_region, synapse_region, direct_region, routing_info, graph_mapper, graph, machine_time_step) spec.end_specification() spec_writer.close() spec_reader = FileDataReader(temp_spec) executor = DataSpecificationExecutor( spec_reader, master_pop_sz + all_syn_block_sz) executor.execute() master_pop_table = executor.get_region(0) synaptic_matrix = executor.get_region(1) direct_matrix = executor.get_region(2) all_data = bytearray() all_data.extend(master_pop_table.region_data[ :master_pop_table.max_write_pointer]) all_data.extend(synaptic_matrix.region_data[ :synaptic_matrix.max_write_pointer]) all_data.extend(direct_matrix.region_data[ :direct_matrix.max_write_pointer]) master_pop_table_address = 0 synaptic_matrix_address = master_pop_table.max_write_pointer direct_synapses_address = ( synaptic_matrix_address + synaptic_matrix.max_write_pointer) direct_synapses_address += 4 indirect_synapses_address = synaptic_matrix_address placement = Placement(None, 0, 0, 1) transceiver = MockTransceiverRawData(all_data) # Get the master population table details items = synaptic_manager._poptable_type\ .extract_synaptic_matrix_data_location( key, master_pop_table_address, transceiver, placement.x, placement.y) # The first entry should be direct, but the rest should be indirect; # the second is potentially direct, but has been restricted by the # restriction on the size of the direct matrix assert len(items) == 3 assert items[0][2] assert not items[1][2] assert not items[2][2] data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=0, using_extra_monitor_cores=False) connections_1 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_1, pre_vertex_slice, post_vertex_slice, row_len_1, 0, 2, weight_scales, data_1, None, app_edge.n_delay_stages, machine_time_step) # The first matrix is a 1-1 matrix, so row length is 1 assert row_len_1 == 1 # Check that all the connections have the right weight and delay assert len(connections_1) == post_vertex_slice.n_atoms assert all([conn["weight"] == 1.5 for conn in connections_1]) assert all([conn["delay"] == 1.0 for conn in connections_1]) data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=1, using_extra_monitor_cores=False) connections_2 = synaptic_manager._synapse_io.read_synapses( direct_synapse_information_2, pre_vertex_slice, post_vertex_slice, row_len_2, 0, 2, weight_scales, data_2, None, app_edge.n_delay_stages, machine_time_step) # The second matrix is a 1-1 matrix, so row length is 1 assert row_len_2 == 1 # Check that all the connections have the right weight and delay assert len(connections_2) == post_vertex_slice.n_atoms assert all([conn["weight"] == 2.5 for conn in connections_2]) assert all([conn["delay"] == 2.0 for conn in connections_2]) data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block( transceiver=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=2, using_extra_monitor_cores=False) connections_3 = synaptic_manager._synapse_io.read_synapses( all_to_all_synapse_information, pre_vertex_slice, post_vertex_slice, row_len_3, 0, 2, weight_scales, data_3, None, app_edge.n_delay_stages, machine_time_step) # The third matrix is an all-to-all matrix, so length is n_atoms assert row_len_3 == post_vertex_slice.n_atoms # Check that all the connections have the right weight and delay assert len(connections_3) == \ post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms assert all([conn["weight"] == 4.5 for conn in connections_3]) assert all([conn["delay"] == 4.0 for conn in connections_3])
def test_write_synaptic_matrix_and_master_population_table(self): MockSimulator.setup() # Add an sdram so max SDRAM is high enough SDRAM(10000) # UGLY but the mock transceiver NEED generate_on_machine to be False AbstractGenerateConnectorOnMachine.generate_on_machine = self.say_false default_config_paths = os.path.join( os.path.dirname(abstract_spinnaker_common.__file__), AbstractSpiNNakerCommon.CONFIG_FILE_NAME) config = conf_loader.load_config( AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths) config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40) machine_time_step = 1000.0 pre_app_vertex = SimpleApplicationVertex(10) pre_vertex_slice = Slice(0, 9) pre_vertex = pre_app_vertex.create_machine_vertex( pre_vertex_slice, None) post_app_vertex = SimpleApplicationVertex(10) post_vertex_slice = Slice(0, 9) post_vertex = post_app_vertex.create_machine_vertex( post_vertex_slice, None) post_slice_index = 0 one_to_one_connector_1 = OneToOneConnector(None) direct_synapse_information_1 = SynapseInformation( one_to_one_connector_1, pre_app_vertex, post_app_vertex, False, False, None, SynapseDynamicsStatic(), 0, 1.5, 1.0) one_to_one_connector_1.set_projection_information( machine_time_step, direct_synapse_information_1) one_to_one_connector_2 = OneToOneConnector(None) direct_synapse_information_2 = SynapseInformation( one_to_one_connector_2, pre_app_vertex, post_app_vertex, False, False, None, SynapseDynamicsStatic(), 1, 2.5, 2.0) one_to_one_connector_2.set_projection_information( machine_time_step, direct_synapse_information_2) all_to_all_connector = AllToAllConnector(None) all_to_all_synapse_information = SynapseInformation( all_to_all_connector, pre_app_vertex, post_app_vertex, False, False, None, SynapseDynamicsStatic(), 0, 4.5, 4.0) all_to_all_connector.set_projection_information( machine_time_step, all_to_all_synapse_information) app_edge = ProjectionApplicationEdge(pre_app_vertex, post_app_vertex, direct_synapse_information_1) app_edge.add_synapse_information(direct_synapse_information_2) app_edge.add_synapse_information(all_to_all_synapse_information) machine_edge = app_edge.create_machine_edge(pre_vertex, post_vertex, label=None) partition_name = "TestPartition" graph = MachineGraph("Test") graph.add_vertex(pre_vertex) graph.add_vertex(post_vertex) graph.add_edge(machine_edge, partition_name) weight_scales = [4096.0, 4096.0] key = 0 routing_info = RoutingInfo() routing_info.add_partition_info( PartitionRoutingInfo( [BaseKeyAndMask(key, 0xFFFFFFF0)], graph.get_outgoing_edge_partition_starting_at_vertex( pre_vertex, partition_name))) temp_spec = tempfile.mktemp() spec_writer = FileDataWriter(temp_spec) spec = DataSpecificationGenerator(spec_writer, None) master_pop_sz = 1000 all_syn_block_sz = 2000 master_pop_region = 0 synapse_region = 1 direct_region = 2 spec.reserve_memory_region(master_pop_region, master_pop_sz) spec.reserve_memory_region(synapse_region, all_syn_block_sz) synaptic_manager = SynapticManager(n_synapse_types=2, ring_buffer_sigma=5.0, spikes_per_second=100.0, config=config) # Poke in our testing region IDs synaptic_manager._pop_table_region = master_pop_region synaptic_manager._synaptic_matrix_region = synapse_region synaptic_manager._direct_matrix_region = direct_region synaptic_manager._write_synaptic_matrix_and_master_population_table( spec, [post_vertex_slice], post_slice_index, post_vertex, post_vertex_slice, all_syn_block_sz, weight_scales, routing_info, graph, machine_time_step) spec.end_specification() spec_writer.close() spec_reader = FileDataReader(temp_spec) executor = DataSpecificationExecutor(spec_reader, master_pop_sz + all_syn_block_sz) executor.execute() master_pop_table = executor.get_region(0) synaptic_matrix = executor.get_region(1) direct_matrix = executor.get_region(2) all_data = bytearray() all_data.extend( master_pop_table.region_data[:master_pop_table.max_write_pointer]) all_data.extend( synaptic_matrix.region_data[:synaptic_matrix.max_write_pointer]) all_data.extend( direct_matrix.region_data[:direct_matrix.max_write_pointer]) master_pop_table_address = 0 synaptic_matrix_address = master_pop_table.max_write_pointer direct_synapses_address = (synaptic_matrix_address + synaptic_matrix.max_write_pointer) direct_synapses_address += 4 indirect_synapses_address = synaptic_matrix_address placement = Placement(None, 0, 0, 1) transceiver = MockTransceiverRawData(all_data) # Get the master population table details items = synaptic_manager._extract_synaptic_matrix_data_location( key, master_pop_table_address, transceiver, placement) # The first entry should be direct, but the rest should be indirect; # the second is potentially direct, but has been restricted by the # restriction on the size of the direct matrix assert len(items) == 3 assert items[0][2] assert not items[1][2] assert not items[2][2] data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block( txrx=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=0, using_monitors=False) connections_1 = synaptic_manager._read_synapses( direct_synapse_information_1, pre_vertex_slice, post_vertex_slice, row_len_1, 0, weight_scales, data_1, None, machine_time_step) # The first matrix is a 1-1 matrix, so row length is 1 assert row_len_1 == 1 # Check that all the connections have the right weight and delay assert len(connections_1) == post_vertex_slice.n_atoms assert all([conn["weight"] == 1.5 for conn in connections_1]) assert all([conn["delay"] == 1.0 for conn in connections_1]) data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block( txrx=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=1, using_monitors=False) connections_2 = synaptic_manager._read_synapses( direct_synapse_information_2, pre_vertex_slice, post_vertex_slice, row_len_2, 0, weight_scales, data_2, None, machine_time_step) # The second matrix is a 1-1 matrix, so row length is 1 assert row_len_2 == 1 # Check that all the connections have the right weight and delay assert len(connections_2) == post_vertex_slice.n_atoms assert all([conn["weight"] == 2.5 for conn in connections_2]) assert all([conn["delay"] == 2.0 for conn in connections_2]) data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block( txrx=transceiver, placement=placement, master_pop_table_address=master_pop_table_address, indirect_synapses_address=indirect_synapses_address, direct_synapses_address=direct_synapses_address, key=key, n_rows=pre_vertex_slice.n_atoms, index=2, using_monitors=False) connections_3 = synaptic_manager._read_synapses( all_to_all_synapse_information, pre_vertex_slice, post_vertex_slice, row_len_3, 0, weight_scales, data_3, None, machine_time_step) # The third matrix is an all-to-all matrix, so length is n_atoms assert row_len_3 == post_vertex_slice.n_atoms # Check that all the connections have the right weight and delay assert len(connections_3) == \ post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms assert all([conn["weight"] == 4.5 for conn in connections_3]) assert all([conn["delay"] == 4.0 for conn in connections_3])