def test_build_node_function_of_time(self, period): """Test that building a function of time Node creates a new operator. """ with nengo.Network() as net: a = nengo.Node(lambda t: [t, t**2], size_in=0) # Mark the Node as a function of time add_spinnaker_params(net.config) net.config[a].function_of_time = True if period is not None: net.config[a].function_of_time_period = period # Create the model model = Model() model.config = net.config # Build the Node nioc = NodeIOController() nioc.build_node(model, a) # Assert that this added a new operator to the model assert model.object_operators[a].function is a.output if period is not None: assert model.object_operators[a].period == period else: assert model.object_operators[a].period is None assert model.extra_operators == list()
def test_build_node_function_of_time_off(self, recwarn): """Test that building a function of time Node is exactly the same as building a regular Node if function of time Nodes are disabled (but that a warning is raised). """ with nengo.Network() as net: a = nengo.Node(lambda t: t, size_in=0, size_out=1, label="Stim") # Mark the Node as a function of time add_spinnaker_params(net.config) net.config[a].function_of_time = True # Create the model model = Model() model.config = net.config # Build the Node nioc = NodeIOController(function_of_time_nodes=False) nioc.build_node(model, a) # Assert that no new operators were created assert model.object_operators == dict() assert model.extra_operators == list() # This should have raised a warning w = recwarn.pop() assert "disabled" in str(w.message) assert "Stim" in str(w.message)
def test_get_node_source_f_of_t(self): """Test that calling the NodeIOController for a f_of_t->xx connection doesn't ask for a SpiNNaker sorce and instead returns the value source that was associated with the Node. """ with nengo.Network() as net: a = nengo.Node(lambda t: t) b = nengo.Ensemble(100, 1) a_b = nengo.Connection(a, b) # Mark the Node as being a function of time add_spinnaker_params(net.config) net.config[a].function_of_time = True # Create a model and build the Node model = Model() model.config = net.config nioc = NodeIOController() nioc.build_node(model, a) # Get the source and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_source_for_node") as gssfn: spec = nioc.get_node_source(model, a_b) assert spec.target.obj is model.object_operators[a] assert spec.target.port is OutputPort.standard # Assert this _didn't_ call `get_spinnaker_source_for_node` assert not gssfn.called # There should be nothing in the host network assert nioc.host_network.all_nodes == list() assert nioc.host_network.all_connections == list()
def create_network_netlist(network, n_steps, fp, dt=0.001): """Create a netlist of a network running for a number of steps, dump that netlist to file. """ # Build the network, assuming EthernetIO model = Model(dt) node_io = Ethernet() model.build(network, **node_io.builder_kwargs) # Build the netlist netlist = model.make_netlist(n_steps).as_rig_arguments() pickle_netlist(netlist, fp)
def test_build_node(self): """Test that building a Node does nothing. """ with nengo.Network() as net: a = nengo.Node(lambda t, x: x**2, size_in=3, size_out=3) # Create the model model = Model() model.config = net.config # Build the Node nioc = NodeIOController() nioc.build_node(model, a) # Assert that no new operators were created assert model.object_operators == dict() assert model.extra_operators == list()
def test_passthrough_nodes_with_other_nodes(self): """Test the handling of passthrough when other Nodes are present.""" with nengo.Network() as net: a = nengo.Node(lambda t: t, size_in=0, size_out=1) b = nengo.Node(None, size_in=1, label="Passthrough Node") c = nengo.Node(lambda t, x: None, size_in=1, size_out=0) a_b = nengo.Connection(a, b) b_c = nengo.Connection(b, c) # Create a model and build the Nodes model = Model() model.config = net.config nioc = NodeIOController() nioc.build_node(model, a) nioc.build_node(model, b) nioc.build_node(model, c) # Check the passthrough Node resulted in a new operator but that the # others didn't assert a not in model.object_operators assert b in model.object_operators assert c not in model.object_operators # Get the source and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_source_for_node") as gssfn: spec = nioc.get_node_source(model, b_c) assert spec.target.obj is model.object_operators[b] assert spec.target.port is OutputPort.standard # Get the sink and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_sink_for_node"): assert nioc.get_node_sink(model, b_c) is not None assert c in nioc._input_nodes # Get the sink and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_sink_for_node") as gssfn: spec = nioc.get_node_sink(model, a_b) assert spec.target.obj is model.object_operators[b] assert spec.target.port is InputPort.standard # Get the source and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_source_for_node") as gssfn: assert nioc.get_node_source(model, a_b) is not None assert a in nioc._output_nodes
def test_passthrough_nodes(self, width): """Test the handling of passthrough Nodes.""" with nengo.Network() as net: a = nengo.Ensemble(100, width) b = nengo.Node(None, size_in=width, label="Passthrough Node") c = nengo.Ensemble(100, width) a_b = nengo.Connection(a, b) b_c = nengo.Connection(b, c) # Create a model and build the Node model = Model() model.config = net.config nioc = NodeIOController() nioc.build_node(model, b) # Check the passthrough Node resulted in a new operator assert model.object_operators[b].size_in == b.size_in assert model.object_operators[b].transmission_delay == 1 assert model.object_operators[b].interpacket_pause == 1 # Get the source and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_source_for_node") as gssfn: spec = nioc.get_node_source(model, b_c) assert spec.target.obj is model.object_operators[b] assert spec.target.port is OutputPort.standard # Assert this _didn't_ call `get_spinnaker_source_for_node` assert not gssfn.called # Get the sink and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_sink_for_node") as gssfn: spec = nioc.get_node_sink(model, a_b) assert spec.target.obj is model.object_operators[b] assert spec.target.port is InputPort.standard # Assert this _didn't_ call `get_spinnaker_sink_for_node` assert not gssfn.called # There should be nothing in the host network assert nioc.host_network.all_nodes == list() assert nioc.host_network.all_connections == list()
def test_build_node_constant_value_is_function_of_time(self): """Test that building a Node with a constant value is equivalent to building a function of time Node. """ with nengo.Network() as net: a = nengo.Node(np.array([0.5, 0.1])) # Create the model model = Model() model.config = net.config # Build the Node nioc = NodeIOController() nioc.build_node(model, a) # Assert that this added a new operator to the model assert model.object_operators[a].function is a.output assert model.object_operators[a].period is model.dt assert model.extra_operators == list()
def test_build_node_process_is_not_constant(self): """Test that building a Node with a process is not treated the same as building a constant valued Node. """ with nengo.Network() as net: a = nengo.Node(nengo.processes.Process()) # Create the model model = Model() model.config = net.config # Build the Node nioc = NodeIOController() nioc.build_node(model, a) # Assert that this added a new operator to the model assert model.object_operators[a].function is a.output assert model.object_operators[a].period is None assert model.extra_operators == list()
def test_passthrough_nodes(self): """Test the handling of passthrough Nodes.""" with nengo.Network() as net: a = nengo.Ensemble(100, 1) b = nengo.Node(size_in=1, label="Passthrough Node") c = nengo.Ensemble(100, 1) a_b = nengo.Connection(a, b) b_c = nengo.Connection(b, c) # Create a model and build the Node model = Model() model.config = net.config nioc = NodeIOController() nioc.build_node(model, b) # Check the passthrough Node resulted in a new operator assert isinstance(model.object_operators[b], PassthroughNode) # Get the source and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_source_for_node") as gssfn: spec = nioc.get_node_source(model, b_c) assert spec.target.obj is model.object_operators[b] assert spec.target.port is OutputPort.standard # Assert this _didn't_ call `get_spinnaker_source_for_node` assert not gssfn.called # Get the sink and ensure that the appropriate object is returned with mock.patch.object(nioc, "get_spinnaker_sink_for_node") as gssfn: spec = nioc.get_node_sink(model, a_b) assert spec.target.obj is model.object_operators[b] assert spec.target.port is InputPort.standard # Assert this _didn't_ call `get_spinnaker_sink_for_node` assert not gssfn.called # There should be nothing in the host network assert nioc.host_network.all_nodes == list() assert nioc.host_network.all_connections == list()
def run_test(nengo_network, nodes_as_function_of_time, nodes_as_function_of_time_time_period): # build via gfe nengo_spinnaker_gfe spinnaker seed = 11111 timer_period = 10 app_graph_builder = NengoApplicationGraphBuilder() (app_graph, host_network, nengo_to_app_graph_map, random_number_generator) = app_graph_builder( nengo_network=nengo_network, machine_time_step=1.0, nengo_random_number_generator_seed=seed, decoder_cache=NoDecoderCache(), utilise_extra_core_for_probes=True, nengo_nodes_as_function_of_time=nodes_as_function_of_time, function_of_time_nodes_time_period=( nodes_as_function_of_time_time_period)) interposer_installer = NengoUtiliseInterposers() app_graph = interposer_installer( app_graph, nengo_to_app_graph_map, random_number_generator, seed) machine_graph, graph_mapper = NengoPartitioner(app_graph) # build via nengo_spinnaker_gfe - spinnaker nengo_spinnaker.add_spinnaker_params(nengo_network.config) for nengo_node in nodes_as_function_of_time: nengo_network.config[nengo_node].function_of_time = True for nengo_node in nodes_as_function_of_time_time_period: nengo_network.config[nengo_node].function_of_time_period = \ nodes_as_function_of_time_time_period[nengo_node] io_controller = Ethernet() builder_kwargs = io_controller.builder_kwargs nengo_spinnaker_network_builder = Model() nengo_spinnaker_network_builder.build(nengo_network, **builder_kwargs) nengo_spinnaker_network_builder.add_interposers() nengo_spinnaker_network_builder.make_netlist(timer_period) nengo_operators = dict() nengo_operators.update( nengo_spinnaker_network_builder.object_operators) nengo_operators.update(io_controller._sdp_receivers) nengo_operators.update(io_controller._sdp_transmitters) match = compare_against_the_nengo_spinnaker_and_gfe_impls( nengo_operators, nengo_to_app_graph_map, nengo_spinnaker_network_builder.connection_map, app_graph, nengo_spinnaker_network_builder) if not match: raise Exception("didnt match")
def test_make_vertices_no_outgoing_signals(self): """Test that no vertices or constraints result if there are no outgoing signals. """ # Create a small filter operator filter_op = Filter(3) # Create an empty model m = Model() # Make vertices using the model netlistspec = filter_op.make_vertices(m, 10000) assert len(netlistspec.vertices) == 0 assert netlistspec.before_simulation_function is None assert netlistspec.after_simulation_function is None assert netlistspec.constraints is None
def test_get_spinnaker_sink_for_node(): """Check that getting the SpiNNaker sink for a Node returns an SDP Tx operator as the sink object with InputPort.standard as the port. """ with nengo.Network(): a = nengo.Ensemble(100, 1) b = nengo.Node(lambda t, x: None, size_in=1) a_b = nengo.Connection(a, b) # Create an empty model and an Ethernet object model = Model() io = ethernet_io.Ethernet() spec = io.get_node_sink(model, a_b) assert isinstance(spec.target.obj, SDPTransmitter) assert spec.target.port is InputPort.standard assert model.extra_operators == [spec.target.obj]
def test_build_passthrough_node(self): # Create a network with nengo.Network(): a = nengo.Node(None, size_in=5) b = nengo.Ensemble(100, 7) a_b = nengo.Connection(a[0:2], b, transform=np.ones((7, 2))) # Create an empty model to build into model = Model() # Build the transmission parameters params = build_node_transmission_parameters(model, a_b) assert params.size_in == 5 assert params.size_out == 7 assert np.array_equal(params.slice_in, np.arange(2)) assert np.array_equal(params.slice_out, np.arange(7)) assert np.array_equal(params.transform, np.ones((7, 2)))
def test_get_spinnaker_source_for_node_repeated(): """Getting the source twice for the same Node should return the same object. """ with nengo.Network(): a = nengo.Node(lambda t: t**2, size_out=1) b = nengo.Ensemble(100, 1) a_b0 = nengo.Connection(a, b) a_b1 = nengo.Connection(a, b, transform=-0.5) # Create an empty model and an Ethernet object model = Model() io = ethernet_io.Ethernet() spec0 = io.get_node_source(model, a_b0) spec1 = io.get_node_source(model, a_b1) assert spec0.target.obj is spec1.target.obj assert model.extra_operators == [spec0.target.obj]
def test_get_spinnaker_sink_for_node_repeated(): """Check that getting the SpiNNaker sink for a Node twice returns the same target. """ with nengo.Network(): a = nengo.Ensemble(100, 1) b = nengo.Node(lambda t, x: None, size_in=1) a_b0 = nengo.Connection(a, b) a_b1 = nengo.Connection(a, b, synapse=0.3) # Create an empty model and an Ethernet object model = Model() io = ethernet_io.Ethernet() spec0 = io.get_node_sink(model, a_b0) spec1 = io.get_node_sink(model, a_b1) assert spec0.target.obj is spec1.target.obj assert model.extra_operators == [spec0.target.obj]
def test_get_spinnaker_source_for_node(): """Check that getting the SpiNNaker source for a Node returns an SDP Rx operator as the source object with OutputPort.standard as the port. The spec should indicate that the connection should be latching. """ with nengo.Network(): a = nengo.Node(lambda t: t**2, size_out=1) b = nengo.Ensemble(100, 1) a_b = nengo.Connection(a, b) # Create an empty model and an Ethernet object model = Model() io = ethernet_io.Ethernet() spec = io.get_node_source(model, a_b) assert isinstance(spec.target.obj, SDPReceiver) assert spec.target.port is OutputPort.standard assert spec.latching assert model.extra_operators == [spec.target.obj]
def test_build_standard_node(self): # Create a network with nengo.Network(): a = nengo.Node(lambda t: [t] * 5, size_out=5) b = nengo.Ensemble(100, 7) func = mock.Mock(side_effect=lambda x: x**2) a_b = nengo.Connection(a[0:2], b, function=func, transform=np.ones((7, 2))) # Create an empty model to build into model = Model() # Build the transmission parameters params = build_node_transmission_parameters(model, a_b) assert params.pre_slice == slice(0, 2) assert params.transform.shape == (7, 2) assert params.function is func assert np.all(params.transform == 1.0)
def test_get_passthrough_node_dependencies(): """Check that the creation of a passthrough Node dependency graph works as expected. """ # Construct a mock network with three sets of passthrough Nodes in the # configuration: # # 0 --> 2 --> 3 # 1 --/ \--> 4 # # 5 --------> 6 # # 7 # Create the Nodes and operators ns = [nengo.Node(size_in=1, label="N{}".format(i), add_to_container=False) for i in range(8)] ops = [mock.Mock(name="O{}".format(i)) for i, _ in enumerate(ns)] # Create the model m = Model() m.object_operators = ptns = dict(zip(ns, ops)) # Add the connections for i, j in ((0, 2), (1, 2), (2, 3), (2, 4), (5, 6)): m.connection_map.add_connection( ops[i], None, model.SignalParameters(), None, ops[j], None, None) # Check the dependencies against the expected dependencies. deps = model_utils.get_passthrough_node_dependencies(m, ptns) assert deps == { (ns[0], ops[0]): set(), (ns[1], ops[1]): set(), (ns[2], ops[2]): {(ns[0], ops[0]), (ns[1], ops[1])}, (ns[3], ops[3]): {(ns[2], ops[2])}, (ns[4], ops[4]): {(ns[2], ops[2])}, (ns[5], ops[5]): set(), (ns[6], ops[6]): {(ns[5], ops[5])}, (ns[7], ops[7]): set(), }
def test_make_vertices_one_group_many_cores_1_chip(self): """Test that many vertices are returned if the matrix has many rows and that there is an appropriate constraint forcing the co-location of the vertices. """ # Create a small filter operator filter_op = Filter(3) # Create a model and add some connections which will cause packets to # be transmitted from the filter operator. m = Model() signal_parameters = SignalParameters(False, 3, m.keyspaces["nengo"]) signal_parameters.keyspace.length = 32 transmission_parameters = PassthroughNodeTransmissionParameters( Transform(size_in=3, size_out=96, transform=np.ones((96, 3)))) m.connection_map.add_connection(filter_op, OutputPort.standard, signal_parameters, transmission_parameters, None, None, None) # Make vertices using the model netlistspec = filter_op.make_vertices(m, 10000) assert len(netlistspec.vertices) == 2 # Two vertices for vx in netlistspec.vertices: assert "filter" in vx.application assert vx.resources[Cores] == 1 assert vx.regions[Regions.system].column_slice == slice(0, 3) keys_region = vx.regions[Regions.keys] assert keys_region.signals_and_arguments == [ (signal_parameters, dict(index=i)) for i in range(32 * 3) ] assert len(keys_region.fields) == 1 assert keys_region.partitioned is True assert vx.regions[Regions.transform].matrix.shape == (32 * 3, 3)
def run_test(nengo_network, nodes_as_function_of_time, nodes_as_function_of_time_time_period): seed = 11111 app_graph_builder = NengoApplicationGraphBuilder() (app_graph, host_network, nengo_to_app_graph_map, random_number_generator) = app_graph_builder( nengo_network=nengo_network, machine_time_step=1.0, nengo_random_number_generator_seed=1234, decoder_cache=NoDecoderCache(), utilise_extra_core_for_probes=True, nengo_nodes_as_function_of_time=nodes_as_function_of_time, function_of_time_nodes_time_period=( nodes_as_function_of_time_time_period)) interposer_installer = NengoUtiliseInterposers() app_graph = interposer_installer(app_graph, random_number_generator, seed) virtual_machine_generator = VirtualMachineGenerator() machine = virtual_machine_generator(width=16, height=16, virtual_has_wrap_arounds=False, version=5, n_cpus_per_chip=18, with_monitors=True, down_chips=None, down_cores=None, down_links=None, max_sdram_size=None) partitioner = NengoPartitioner() machine_graph, graph_mapper = partitioner(app_graph, machine, random_number_generator, pre_allocated_resources=None) # build via nengo_spinnaker_gfe - spinnaker nengo_spinnaker.add_spinnaker_params(nengo_network.config) for nengo_node in nodes_as_function_of_time: nengo_network.config[nengo_node].function_of_time = True for nengo_node in nodes_as_function_of_time_time_period: nengo_network.config[nengo_node].function_of_time_period = \ nodes_as_function_of_time_time_period[nengo_node] io_controller = Ethernet() builder_kwargs = io_controller.builder_kwargs nengo_spinnaker_network_builder = Model() nengo_spinnaker_network_builder.build(nengo_network, **builder_kwargs) net_list = nengo_spinnaker_network_builder.make_netlist(200) nengo_app_operators = dict() nengo_app_operators.update( nengo_spinnaker_network_builder.object_operators) nengo_app_operators.update(io_controller._sdp_receivers) nengo_app_operators.update(io_controller._sdp_transmitters) match = \ compare_against_the_nengo_spinnaker_and_gfe_impls_machine_graphs( # nengo bits nengo_app_operators, nengo_to_app_graph_map, nengo_spinnaker_network_builder.connection_map, net_list, # gfe bits machine_graph, graph_mapper, app_graph, nengo_spinnaker_network_builder) if not match: raise Exception("didnt match")