def test_standard(self): """Test that mostly empty specs result in appropriate calls to build the keyspace and that the weight is grabbed from the connection. """ # Create the model with it's default keyspace model = mock.Mock() model.keyspaces = {"nengo": mock.Mock()} exp_ks = model.keyspaces["nengo"].return_value = mock.Mock() model._get_object_and_connection_id.return_value = (1, 3) # Create the connection that we're building pre = mock.Mock("pre") post = mock.Mock("post") post.size_in = 5 connection = mock.Mock(spec_set=nengo.Connection) connection.pre_obj = pre connection.post_obj = post # Create a spec for the source and a spec for the sink source_obj = mock.Mock() source_spec = spec(source_obj) sink_obj = mock.Mock() sink_spec = spec(sink_obj) # Get the Signal signal = _make_signal(model, connection, source_spec, sink_spec) assert signal.source is source_obj assert signal.sinks == [sink_obj] assert signal.keyspace is exp_ks assert signal.weight == post.size_in assert signal.latching is False # Check that the keyspace was called correctly model.keyspaces["nengo"].assert_called_once_with(object=1, connection=3)
def test_keyspace_collision(self): # Create the model with it's default keyspace model = Model() # Create the keyspace keyspace_a = mock.Mock(name="keyspace") keyspace_b = mock.Mock(name="keyspace") # Create the connection that we're building pre = mock.Mock("pre") post = mock.Mock("post") post.size_in = 0 connection = mock.Mock(spec_set=nengo.Connection) connection.pre_obj = pre connection.post_obj = post # Create a spec for the source and a spec for the sink source_obj = mock.Mock() source_spec = spec(source_obj, keyspace=keyspace_a) sink_obj = mock.Mock() sink_spec = spec(sink_obj, keyspace=keyspace_b) with pytest.raises(NotImplementedError) as excinfo: _make_signal(model, connection, source_spec, sink_spec) assert "keyspace" in str(excinfo.value)
def test_latching(self, a_is_latching, b_is_latching, latching): # Construct the specs a_spec = spec(None, latching=a_is_latching) b_spec = spec(None, latching=b_is_latching) # Make the signal parameters, check they are correct sig_pars = _make_signal_parameters(a_spec, b_spec, DummyConnection()) assert sig_pars.latching is latching
def test_keyspace_from_sink(self): """Check that the sink keyspace is used if provided.""" ks = mock.Mock(name="Keyspace") a_spec = spec(None) b_spec = spec(None, keyspace=ks) # Make the signal parameters, check they are correct sig_pars = _make_signal_parameters(a_spec, b_spec, DummyConnection()) assert sig_pars.keyspace is ks
def test_weight(self, source_weight, sink_weight): """Test that the greatest specified weight is used.""" # Construct the specs a_spec = spec(None, weight=source_weight) b_spec = spec(None, weight=sink_weight) # Make the signal parameters, check they are correct sig_pars = _make_signal_parameters(a_spec, b_spec, DummyConnection()) assert sig_pars.weight == max((source_weight, sink_weight))
def test_keyspace_collision(self): """Test that if both the source and spec provide a keyspace an error is raised. """ a_spec = spec(None, keyspace=mock.Mock()) b_spec = spec(None, keyspace=mock.Mock()) # Make the signal parameters, this should raise an error with pytest.raises(NotImplementedError): _make_signal_parameters(a_spec, b_spec, DummyConnection())
def get_node_source(self, model, cn): """Get the source for a connection originating from a Node.""" if cn.pre_obj in self.passthrough_nodes: # If the Node is a passthrough Node then we return a reference # to the Filter operator we created earlier regardless. return spec( ObjectPort(self.passthrough_nodes[cn.pre_obj], OutputPort.standard)) elif cn.pre_obj in self._f_of_t_nodes: # If the Node is a function of time Node then we return a # reference to the value source we created earlier. return spec( ObjectPort(self._f_of_t_nodes[cn.pre_obj], OutputPort.standard)) elif (type(cn.post_obj) is nengo.Node and cn.post_obj not in self.passthrough_nodes): # If this connection goes from a Node to another Node (exactly, not # any subclasses) then we just add both nodes and the connection to # the host model. with self.host_network: self._add_node(cn.pre_obj) self._add_node(cn.post_obj) self._add_connection(cn) # Return None to indicate that the connection should not be # represented by a signal on SpiNNaker. return None else: # Otherwise, we create a new OutputNode for the Node at the # start of the given connection, then add both it and the Node # to the host network, with a joining connection. with self.host_network: # Create the output Node if necessary if cn.pre_obj not in self._output_nodes: self._add_node(cn.pre_obj) self._output_nodes[cn.pre_obj] = \ OutputNode(cn.pre_obj, self) output_node = self._output_nodes[cn.pre_obj] nengo.Connection(cn.pre_obj, output_node, synapse=None) # Return a specification that describes how the signal should # be represented on SpiNNaker. return self.get_spinnaker_source_for_node(model, cn)
def get_node_source(self, model, cn): """Get the source for a connection originating from a Node.""" if cn.pre_obj in self.passthrough_nodes: # If the Node is a passthrough Node then we return a reference # to the Filter operator we created earlier regardless. return spec(ObjectPort(self.passthrough_nodes[cn.pre_obj], OutputPort.standard)) elif cn.pre_obj in self._f_of_t_nodes: # If the Node is a function of time Node then we return a # reference to the value source we created earlier. return spec(ObjectPort(self._f_of_t_nodes[cn.pre_obj], OutputPort.standard)) elif (type(cn.post_obj) is nengo.Node and cn.post_obj not in self.passthrough_nodes): # If this connection goes from a Node to another Node (exactly, not # any subclasses) then we just add both nodes and the connection to # the host model. with self.host_network: self._add_node(cn.pre_obj) self._add_node(cn.post_obj) self._add_connection(cn) # Return None to indicate that the connection should not be # represented by a signal on SpiNNaker. return None else: # Otherwise, we create a new OutputNode for the Node at the # start of the given connection, then add both it and the Node # to the host network, with a joining connection. with self.host_network: # Create the output Node if necessary if cn.pre_obj not in self._output_nodes: self._add_node(cn.pre_obj) self._output_nodes[cn.pre_obj] = \ OutputNode(cn.pre_obj, self) output_node = self._output_nodes[cn.pre_obj] nengo.Connection(cn.pre_obj, output_node, synapse=None) # Return a specification that describes how the signal should # be represented on SpiNNaker. return self.get_spinnaker_source_for_node(model, cn)
def test_spec(): """Test specifying the source or sink of a signal.""" # With minimal arguments s = spec(None) assert s.target is None assert s.keyspace is None assert not s.latching assert s.weight == 0 # With all arguments target = mock.Mock(name="target") keyspace = mock.Mock(name="keyspace") weight = 5 latching = True s = spec(target, keyspace=keyspace, weight=weight, latching=latching) assert s.target is target assert s.keyspace is keyspace assert s.weight == weight assert s.latching is latching
def test_weights(self, source_weight, sink_weight, expected_weight): """Test that weights are taken from the spec. """ # Create the model with it's default keyspace model = Model() # Create the connection that we're building pre = mock.Mock("pre") post = mock.Mock("post") post.size_in = 5 connection = mock.Mock(spec_set=nengo.Connection) connection.pre_obj = pre connection.post_obj = post # Create a spec for the source and a spec for the sink source_obj = mock.Mock() source_spec = spec(source_obj, weight=source_weight) sink_obj = mock.Mock() sink_spec = spec(sink_obj, weight=sink_weight) # Get the Signal signal = _make_signal(model, connection, source_spec, sink_spec) assert signal.weight == expected_weight
def test_keyspace_from_sink(self): # Create the model with it's default keyspace model = Model() # Create the keyspace keyspace = mock.Mock(name="keyspace") # Create the connection that we're building pre = mock.Mock("pre") post = mock.Mock("post") post.size_in = 0 connection = mock.Mock(spec_set=nengo.Connection) connection.pre_obj = pre connection.post_obj = post # Create a spec for the source and a spec for the sink source_obj = mock.Mock() source_spec = spec(source_obj) sink_obj = mock.Mock() sink_spec = spec(sink_obj, keyspace=keyspace) # Get the Signal signal = _make_signal(model, connection, source_spec, sink_spec) assert signal.keyspace is keyspace
def get_node_sink(self, model, cn): """Get the sink for a connection terminating at a Node.""" if cn.post_obj in self.passthrough_nodes: # If the Node is a passthrough Node then we return a reference # to the Filter operator we created earlier regardless. return spec( ObjectPort(self.passthrough_nodes[cn.post_obj], InputPort.standard)) elif (type(cn.pre_obj) is nengo.Node and cn.pre_obj not in self.passthrough_nodes): # If this connection goes from a Node to another Node (exactly, not # any subclasses) then we just add both nodes and the connection to # the host model. with self.host_network: self._add_node(cn.pre_obj) self._add_node(cn.post_obj) self._add_connection(cn) # Return None to indicate that the connection should not be # represented by a signal on SpiNNaker. return None else: # Otherwise we create a new InputNode for the Node at the end # of the given connection, then add both it and the Node to the # host network with a joining connection. with self.host_network: self._add_node(cn.post_obj) # Create the input node AND connection if necessary if cn.post_obj not in self._input_nodes: self._input_nodes[cn.post_obj] = \ InputNode(cn.post_obj, self) input_node = self._input_nodes[cn.post_obj] nengo.Connection(input_node, cn.post_obj, synapse=None) # Return a specification that describes how the signal should # be represented on SpiNNaker. return self.get_spinnaker_sink_for_node(model, cn)
def get_node_sink(self, model, cn): """Get the sink for a connection terminating at a Node.""" if cn.post_obj in self.passthrough_nodes: # If the Node is a passthrough Node then we return a reference # to the Filter operator we created earlier regardless. return spec(ObjectPort(self.passthrough_nodes[cn.post_obj], InputPort.standard)) elif (type(cn.pre_obj) is nengo.Node and cn.pre_obj not in self.passthrough_nodes): # If this connection goes from a Node to another Node (exactly, not # any subclasses) then we just add both nodes and the connection to # the host model. with self.host_network: self._add_node(cn.pre_obj) self._add_node(cn.post_obj) self._add_connection(cn) # Return None to indicate that the connection should not be # represented by a signal on SpiNNaker. return None else: # Otherwise we create a new InputNode for the Node at the end # of the given connection, then add both it and the Node to the # host network with a joining connection. with self.host_network: self._add_node(cn.post_obj) # Create the input node AND connection if necessary if cn.post_obj not in self._input_nodes: self._input_nodes[cn.post_obj] = \ InputNode(cn.post_obj, self) input_node = self._input_nodes[cn.post_obj] nengo.Connection(input_node, cn.post_obj, synapse=None) # Return a specification that describes how the signal should # be represented on SpiNNaker. return self.get_spinnaker_sink_for_node(model, cn)
def source_getter(model, conn): assert model is m assert conn is connection return spec(ObjectPort(source, source_port))
def sink_getter(model, conn): assert model is m assert conn is connection return spec(ObjectPort(sink, sink_port))
def sink_getter_fn(m, c): assert m is model assert c is connection return spec(sink)
def source_getter_fn(m, c): assert m is model assert c is connection return spec(source)