예제 #1
0
def test_filter_routing_region_duplicate_connection():
    """Test that an error is raised if mismatched connections with the same key
    are identified.
    """
    # Define a single keyspace
    ksc = KeyspaceContainer()
    ks = ksc["nengo"](connection_id=3)
    ksc.assign_fields()

    # Define some signals to hold these keyspaces
    sig_a = SignalParameters(keyspace=ks)
    sig_b = SignalParameters(keyspace=ks)

    # Define the filter routes, these map a keyspace to an integer
    signal_routes = [(sig_a, 12), (sig_b, 12), (sig_b, 17)]

    # Create the region
    filter_region = FilterRoutingRegion(
        signal_routes,
        filter_routing_tag=ksc.filter_routing_tag,
        index_field="index")

    # Extract a dictionary of the constraints on the signal keys (no
    # constraints because the keyspace was specified before).
    assert len(filter_region.get_signal_constraints()) == 0

    # Check that an error is raised because two signals with the same key route
    # in different directions
    fp = tempfile.TemporaryFile()
    with pytest.raises(AssertionError):
        filter_region.build_routes()
예제 #2
0
    def test_forced_filter_width(self):
        """Test construction of filter regions from signals and keyspaces."""
        # Create two keyspaces, two signals and two connections with equivalent
        # synapses.
        # Create two keyspaces, two signals and two reception parameters with
        # different synapses.
        ks_a = mock.Mock(name="Keyspace[A]")
        signal_a = SignalParameters(keyspace=ks_a, latching=False)

        ks_b = mock.Mock(name="Keyspace[B]")
        signal_b = SignalParameters(keyspace=ks_b, latching=False)

        rp_a = ReceptionParameters(nengo.Lowpass(0.01), 3, None)
        rp_b = ReceptionParameters(None, 5, None)

        # Create the type of dictionary that is expected as input
        specs = [
            ReceptionSpec(signal_a, rp_a),
            ReceptionSpec(signal_b, rp_b),
        ]

        # Create the regions, with minimisation
        filter_region, routing_region = make_filter_regions(specs,
                                                            0.001,
                                                            width=1)

        # Check that the filter region is as expected
        for f in filter_region.filters:
            assert (f == LowpassFilter(1, False, 0.01)
                    or f == NoneFilter(1, False))  # noqa: E711
예제 #3
0
def test_filter_routing_region():
    """Test creation of a filter routing region."""
    # Define some keyspaces
    ksc = KeyspaceContainer()
    ks_a = ksc["nengo"](connection_id=3)
    ks_b = ksc["nengo"](connection_id=255, cluster=63, index=15)
    ksc.assign_fields()

    # Define some signals to hold these keyspaces
    sig_a = SignalParameters(keyspace=ks_a)
    sig_b = SignalParameters(keyspace=ks_b)

    # Define the filter routes, these map a keyspace to an integer
    signal_routes = [(sig_a, 12), (sig_b, 17)]

    # Create the region
    filter_region = FilterRoutingRegion(
        signal_routes,
        filter_routing_tag=ksc.filter_routing_tag,
        index_field="index")

    # Check that the memory requirement is sane
    assert filter_region.sizeof() == 4 * (1 + 4 * len(signal_routes))

    # Check that the set of expected keys and masks can be extracted
    assert filter_region.get_expected_keys_and_masks() == {
        (ks_a.get_value(tag=ksc.filter_routing_tag),
         ks_a.get_mask(tag=ksc.filter_routing_tag)),
        (ks_b.get_value(tag=ksc.filter_routing_tag),
         ks_b.get_mask(tag=ksc.filter_routing_tag)),
    }

    # Check that the written out data is sensible
    fp = tempfile.TemporaryFile()
    filter_region.build_routes()
    filter_region.write_subregion_to_file(fp)

    # Check that the data is sensible
    fp.seek(0)
    length, = struct.unpack("<I", fp.read(4))
    assert length == 2

    # Determine valid values
    valid_mask = ksc["nengo"].get_mask(tag=ksc.filter_routing_tag)
    valid_d_mask = ksc["nengo"].get_mask(field="index")

    for _ in range(len(signal_routes)):
        key, mask, d_mask, i = struct.unpack("<4I", fp.read(16))
        assert mask == valid_mask, hex(mask) + " != " + hex(valid_mask)
        assert d_mask == valid_d_mask

        for signal, j in signal_routes:
            ks = signal.keyspace
            if key == ks.get_value(tag=ksc.filter_routing_tag):
                assert i == j
                break
        else:
            assert False, "Unexpected key " + hex(key)
def test_get_net_keyspaces_fails_for_inconsistent_cluster():
    """Test specification of keyspaces for nets fails in the case that
    inconsistent cluster IDs are assigned (this is unlikely to happen unless a
    Net somehow ends up having two different Nengo objects in its source
    list)."""
    # Create the vertices
    vertex_A = [Vertex() for _ in range(4)]
    vertex_B = Vertex()

    # Create placements such that vertex A and B fall on two chips and A[0] and
    # A[1] are on the same chip.
    placements = {
        vertex_A[0]: (0, 0),
        vertex_A[1]: (0, 0),
        vertex_A[2]: (0, 1),
        vertex_A[3]: (0, 1),
        vertex_B: (0, 0)
    }
    resources = {v: {} for v in placements}
    allocations = {v: {} for v in placements}

    # Create a container for the keyspaces
    ksc = KeyspaceContainer()

    # Create the signals and nets
    signal_a = Signal(object(), [],
                      SignalParameters(keyspace=ksc["nengo"](connection_id=0)))
    signal_b = Signal(object(), [],
                      SignalParameters(keyspace=ksc["nengo"](connection_id=1)))
    signal_c = Signal(object(), [], SignalParameters(keyspace=ksc["spam"]))

    nets = {
        signal_a: NMNet(vertex_A, vertex_B, 1.0),
        signal_b: NMNet(vertex_B, vertex_A, 2.0),
        signal_c: NMNet(vertex_A, vertex_A, 3.0),
    }

    # Identify groups
    groups = [set(vertex_A)]

    # Manually identify clusters (and do it such that it is inconsistent)
    vertex_A[0].cluster = 0
    vertex_A[1].cluster = 1
    vertex_A[2].cluster = 2
    vertex_A[3].cluster = 3

    # Get the routing nets
    _, _, _, _, derived_nets = utils.get_nets_for_routing(
        resources, nets, placements, allocations)

    # Get the net keyspaces
    with pytest.raises(AssertionError):
        utils.get_net_keyspaces(placements, nets, derived_nets)
예제 #5
0
def test_get_transforms_and_keys():
    """Test that the complete transform matrix is constructed correctly and
    that appropriate keys are assigned.
    """
    # Create 2 mock signals and associated connections
    sig_a_ks_0 = mock.Mock()
    sig_a_ks_1 = mock.Mock()
    sig_a_kss = {
        0: sig_a_ks_0,
        1: sig_a_ks_1,
    }

    sig_a_ks = mock.Mock()
    sig_a_ks.side_effect = lambda index: sig_a_kss[index]
    sig_a = SignalParameters(keyspace=sig_a_ks)

    conn_a = PassthroughNodeTransmissionParameters(np.eye(2))

    sig_b_ks_0 = mock.Mock()
    sig_b_kss = {
        0: sig_b_ks_0,
    }

    sig_b_ks = mock.Mock()
    sig_b_ks.side_effect = lambda index: sig_b_kss[index]
    sig_b = SignalParameters(keyspace=sig_b_ks)

    conn_b = PassthroughNodeTransmissionParameters(np.array([[0.5, 0.5]]))
    transform_b = conn_b.transform

    # Create the dictionary type that will be used
    pars = [(sig_a, conn_a), (sig_b, conn_b)]

    # Get the transforms and keys
    transforms, keys, signal_parameter_slices = get_transforms_and_keys(pars)

    # Check that the transforms and keys are correct
    assert set(keys) == set([sig_a_ks_0, sig_a_ks_1, sig_b_ks_0])
    assert transforms.shape == (len(keys), 2)
    assert (np.all(transforms[0] == transform_b) or
            np.all(transforms[2] == transform_b))

    # Check that the signal parameter slices are correct
    for (par, sl) in signal_parameter_slices:
        if par == conn_a:
            assert sl == set(range(0, 2)) or sl == set(range(1, 3))
        else:
            assert par == conn_b
            assert sl == set(range(0, 1)) or sl == set(range(2, 3))
예제 #6
0
    def test_equivalent_filters(self, minimise):
        """Test construction of filter regions from signals and keyspaces."""
        # Create two keyspaces, two signal parameters and two reception
        # parameters with equivalent synapses.
        ks_a = mock.Mock(name="Keyspace[A]")
        signal_a = SignalParameters(keyspace=ks_a, latching=False)

        ks_b = mock.Mock(name="Keyspace[B]")
        signal_b = SignalParameters(keyspace=ks_b, latching=False)

        rp_a = ReceptionParameters(nengo.Lowpass(0.01), 3, None)
        rp_b = ReceptionParameters(nengo.Lowpass(0.01), 3, None)

        # Create the data structure that is expected as input
        specs = [
            ReceptionSpec(signal_a, rp_a),
            ReceptionSpec(signal_b, rp_b),
        ]

        # Create the regions, with minimisation
        filter_region, routing_region = make_filter_regions(
            specs,
            0.001,
            minimise=minimise,
            filter_routing_tag="spam",
            index_field="eggs")

        # Check that the filter region is as expected
        assert filter_region.dt == 0.001

        if minimise:
            assert len(filter_region.filters) == 1
            assert filter_region.filters[0] == LowpassFilter(3, False, 0.01)
        else:
            assert len(filter_region.filters) == 2
            assert filter_region.filters[0] == LowpassFilter(3, False, 0.01)
            assert filter_region.filters[1] == LowpassFilter(3, False, 0.01)

        # Check that the routing region is as expected
        assert routing_region.filter_routing_tag == "spam"
        assert routing_region.index_field == "eggs"
        if minimise:
            assert (signal_a, 0) in routing_region.signal_routes
            assert (signal_b, 0) in routing_region.signal_routes
        else:
            if (signal_a, 0) in routing_region.signal_routes:
                assert (signal_b, 1) in routing_region.signal_routes
            else:
                assert (signal_b, 0) in routing_region.signal_routes
예제 #7
0
    def test_removes_sinkless_filters(self):
        """Test that making a netlist correctly filters out passthrough Nodes
        with no outgoing connections.
        """
        # Create the first operator
        object_a = mock.Mock(name="object A")
        vertex_a = mock.Mock(name="vertex A")
        load_fn_a = mock.Mock(name="load function A")
        pre_fn_a = mock.Mock(name="pre function A")
        post_fn_a = mock.Mock(name="post function A")

        operator_a = mock.Mock(name="operator A")
        operator_a.make_vertices.return_value = \
            netlistspec(vertex_a, load_fn_a, pre_fn_a, post_fn_a)

        # Create the second operator
        object_b = mock.Mock(name="object B")
        operator_b = operators.Filter(16)  # Shouldn't need building

        # Create the model, add the items and add an entry to the connection
        # map.
        model = Model()
        model.object_operators[object_a] = operator_a
        model.object_operators[object_b] = operator_b
        model.connection_map.add_connection(operator_a, None,
                                            SignalParameters(), None,
                                            operator_b, None, None)
        netlist = model.make_netlist(1)

        # The netlist should contain vertex a and no nets
        assert netlist.nets == list()
        assert netlist.vertices == [vertex_a]
예제 #8
0
def test_get_transforms_and_keys_removes_zeroed_rows(latching):
    """Check that zeroed rows (those that would always result in zero valued
    packets) are removed, and the keys miss this value as well.
    """
    transform = np.ones((10, 5))
    transform[1, :] = 0.0
    transform[4:7, :] = 0.0
    transform[:, 1] = 0.0

    # Create a signal and keyspace
    sig = SignalParameters(latching=latching)

    # Create a mock connection
    conn = PassthroughNodeTransmissionParameters(
        Transform(size_in=5, size_out=10, transform=transform))

    signals_connections = [(sig, conn)]

    # Get the transform and keys
    t, keys, _ = get_transforms_and_keys(signals_connections, slice(0, 5))

    if not latching:
        # Check the transform is correct
        assert np.all(t == np.vstack((transform[0], transform[2:4],
                                      transform[7:])))

        # Check the keys were called for correctly
        assert keys == [(sig, {"index": i}) for i in [0, 2, 3, 7, 8, 9]]
    else:
        # Check the transform is correct
        assert np.all(t == t)

        # Check the keys were called for correctly
        assert keys == [(sig, {"index": i}) for i in range(10)]
예제 #9
0
    def test_from_parameters_force_width(self, latching, width):
        # Create the mock signal and connection
        signal = SignalParameters(latching=latching)
        rps = ReceptionParameters(None, width, None)

        # Build the filter
        nf = NoneFilter.from_parameters(signal, rps, width=1)
        assert NoneFilter(1, latching) == nf
예제 #10
0
    def test_from_parameters_force_width(self):
        # Create the mock signal and connection
        signal = SignalParameters(latching=True)
        rps = ReceptionParameters(nengo.LinearFilter([1.0], [0.5, 1.0]), 1)

        # Create the filter
        lpf = LinearFilter.from_parameters(signal, rps, width=2)
        assert lpf == LinearFilter(2, True, [1.0], [0.5, 1.0])
예제 #11
0
    def test_from_parameters_force_width(self, width, latching, tc):
        # Create the mock signal and connection
        signal = SignalParameters(latching=latching)
        rps = ReceptionParameters(nengo.Lowpass(tc), width, None)

        # Create the filter
        lpf = LowpassFilter.from_parameters(signal, rps, width=2)
        assert lpf == LowpassFilter(2, latching, tc)
예제 #12
0
def test_get_transforms_and_keys():
    """Test that the complete transform matrix is constructed correctly and
    that appropriate keys are assigned.
    """
    # Create 2 mock signals and associated connections
    sig_a = SignalParameters()
    conn_a = PassthroughNodeTransmissionParameters(
        Transform(size_in=2, size_out=2, transform=np.eye(2)))

    sig_b = SignalParameters()
    conn_b = PassthroughNodeTransmissionParameters(
        Transform(size_in=2, size_out=1, transform=np.array([[0.5, 0.5]])))
    transform_b = conn_b.transform

    # Create the dictionary type that will be used
    pars = [(sig_a, conn_a), (sig_b, conn_b)]

    # Get the transforms and keys
    transforms, keys, signal_parameter_slices = \
        get_transforms_and_keys(pars, slice(0, 2))

    # Check that the transforms and keys are correct
    assert (keys == [(sig_b, {
        "index": 0
    }), (sig_a, {
        "index": 0
    }), (sig_a, {
        "index": 1
    })] or keys == [(sig_a, {
        "index": 0
    }), (sig_a, {
        "index": 1
    }), (sig_b, {
        "index": 0
    })])
    assert transforms.shape == (len(keys), 2)
    assert (np.all(transforms[0] == transform_b)
            or np.all(transforms[2] == transform_b))

    # Check that the signal parameter slices are correct
    for (par, sl) in signal_parameter_slices:
        if par == conn_a:
            assert sl == set(range(0, 2)) or sl == set(range(1, 3))
        else:
            assert par == conn_b
            assert sl == set(range(0, 1)) or sl == set(range(2, 3))
예제 #13
0
def test_filter_routing_region_get_signal_constraints():
    """Test the reporting of which signals cannot share a routing identifier.
    """
    # Define some signals
    sig_a = SignalParameters()
    sig_b = SignalParameters()

    # Define the filter routes, these map a keyspace to an integer
    signal_routes = [(sig_a, 12), (sig_b, 12), (sig_b, 17)]

    # Create the region
    filter_region = FilterRoutingRegion(signal_routes)

    # Extract a dictionary of the constraints on the signal keys
    assert filter_region.get_signal_constraints() == {
        id(sig_a): {id(sig_b)},
        id(sig_b): {id(sig_a)},
    }
예제 #14
0
def _multiply_signals(in_kwargs, out_conn_kwargs):
    """Multiply an input connection by a selection of outgoing connection and
    yield keywords for every new connection.

    Yields
    ------
    dict
        Keyword arguments for `ConnectionMap.add_connection`
    """
    # For every outgoing connection
    for out_conn in out_conn_kwargs:
        # Combine the transmission parameters
        transmission_parameters, sink_port = _combine_transmission_params(
            in_kwargs["transmission_parameters"],
            out_conn["transmission_parameters"], out_conn["sink_port"])

        # If the connection has been optimised out then move on
        if transmission_parameters is None and sink_port is None:
            continue

        # Combine the reception parameters
        reception_parameters = _combine_reception_params(
            in_kwargs["reception_parameters"],
            out_conn["reception_parameters"],
        )

        # Combine the signal parameters: the new signal will be latching if
        # either the input or the output signals require it be so, it will have
        # the weight assigned by the reception parameters. If either the input
        # or output keyspace are None then the keyspace assigned to the other
        # signal will be used; if neither are None then we break because
        # there's no clear way to merge keyspaces.
        in_sig_pars = in_kwargs["signal_parameters"]
        out_sig_pars = out_conn["signal_parameters"]

        latching = in_sig_pars.latching or out_sig_pars.latching
        weight = out_sig_pars.weight

        if in_sig_pars.keyspace is None or out_sig_pars.keyspace is None:
            keyspace = in_sig_pars.keyspace or out_sig_pars.keyspace
        else:
            raise NotImplementedError("Cannot merge keyspaces")

        # Construct the new signal parameters
        signal_parameters = SignalParameters(latching, weight, keyspace)

        # Yield the new keyword arguments
        yield {
            "source_object": in_kwargs["source_object"],
            "source_port": in_kwargs["source_port"],
            "signal_parameters": signal_parameters,
            "transmission_parameters": transmission_parameters,
            "sink_object": out_conn["sink_object"],
            "sink_port": sink_port,
            "reception_parameters": reception_parameters,
        }
예제 #15
0
    def test_different_filters(self):
        """Test construction of filter regions from signals and keyspaces."""
        # Create two keyspaces, two signals and two reception parameters with
        # different synapses.
        ks_a = mock.Mock(name="Keyspace[A]")
        signal_a = SignalParameters(keyspace=ks_a, latching=False)

        ks_b = mock.Mock(name="Keyspace[B]")
        signal_b = SignalParameters(keyspace=ks_b, latching=False)

        rp_a = ReceptionParameters(nengo.Lowpass(0.01), 3, None)
        rp_b = ReceptionParameters(None, 3, None)

        # Create the type of dictionary that is expected as input
        specs = [
            ReceptionSpec(signal_a, rp_a),
            ReceptionSpec(signal_b, rp_b),
        ]

        # Create the regions, with minimisation
        filter_region, routing_region = make_filter_regions(
            specs,
            0.001,
            minimise=True,  # Shouldn't achieve anything
            filter_routing_tag="spam",
            index_field="eggs")

        # Check that the filter region is as expected
        assert filter_region.dt == 0.001
        assert len(filter_region.filters) == 2

        for f in filter_region.filters:
            assert (f == LowpassFilter(3, False, 0.01)
                    or f == NoneFilter(3, False))  # noqa: E711

        # Check that the routing region is as expected
        assert routing_region.filter_routing_tag == "spam"

        assert routing_region.index_field == "eggs"
        if (signal_a, 0) in routing_region.signal_routes:
            assert (signal_b, 1) in routing_region.signal_routes
        else:
            assert (signal_b, 0) in routing_region.signal_routes
예제 #16
0
def test_get_transforms_and_keys_removes_zeroed_rows(latching):
    """Check that zeroed rows (those that would always result in zero valued
    packets) are removed, and the keys miss this value as well.
    """
    ks = mock.Mock()
    transform = np.ones((10, 5))
    transform[1, :] = 0.0
    transform[4:7, :] = 0.0
    transform[:, 1] = 0.0

    # Create a signal and keyspace
    sig = mock.Mock()
    sig.keyspace = ks
    sig.latching = latching
    sig = SignalParameters(keyspace=ks, latching=latching)

    # Create a mock connection
    conn = PassthroughNodeTransmissionParameters(transform)

    signals_connections = [(sig, conn)]

    # Get the transform and keys
    t, keys, _ = get_transforms_and_keys(signals_connections)

    if not latching:
        # Check the transform is correct
        assert np.all(t ==
                      np.vstack((transform[0], transform[2:4], transform[7:])))

        # Check the keys were called for correctly
        ks.assert_has_calls([mock.call(index=0),
                             mock.call(index=2),
                             mock.call(index=3),
                             mock.call(index=7),
                             mock.call(index=8),
                             mock.call(index=9)])
    else:
        # Check the transform is correct
        assert np.all(t == t)

        # Check the keys were called for correctly
        ks.assert_has_calls([mock.call(index=0),
                             mock.call(index=1),
                             mock.call(index=2),
                             mock.call(index=3),
                             mock.call(index=4),
                             mock.call(index=5),
                             mock.call(index=6),
                             mock.call(index=7),
                             mock.call(index=8),
                             mock.call(index=9)])
예제 #17
0
    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)
예제 #18
0
    def test_multiple_source_vertices(self):
        """Test that each of the vertices associated with a source is correctly
        included in the sources of a net.
        """
        class MyVertexSlice(VertexSlice):
            def __init__(self, *args, **kwargs):
                super(MyVertexSlice, self).__init__(*args, **kwargs)
                self.args = None

            def transmits_signal(self, signal_parameters,
                                 transmission_parameters):
                self.args = (signal_parameters, transmission_parameters)
                return False

        # Create the first operator
        vertex_a0 = VertexSlice(slice(0, 1))
        vertex_a1 = VertexSlice(slice(1, 2))
        vertex_a2 = MyVertexSlice(slice(2, 3))
        load_fn_a = mock.Mock(name="load function A")
        pre_fn_a = mock.Mock(name="pre function A")
        post_fn_a = mock.Mock(name="post function A")

        object_a = mock.Mock(name="object A")
        operator_a = mock.Mock(name="operator A", spec_set=["make_vertices"])
        operator_a.make_vertices.return_value = \
            netlistspec([vertex_a0, vertex_a1, vertex_a2],
                        load_fn_a, pre_fn_a, post_fn_a)

        # Create the second operator
        vertex_b = Vertex()
        load_fn_b = mock.Mock(name="load function B")

        object_b = mock.Mock(name="object B")
        operator_b = mock.Mock(name="operator B", spec_set=["make_vertices"])
        operator_b.make_vertices.return_value = \
            netlistspec((vertex_b, ), load_fn_b)

        # Create a signal between the operators
        keyspace = mock.Mock(name="keyspace")
        keyspace.length = 32
        signal_ab_parameters = SignalParameters(keyspace=keyspace, weight=43)

        # Create the model, add the items and then generate the netlist
        model = Model()
        model.object_operators[object_a] = operator_a
        model.object_operators[object_b] = operator_b
        model.connection_map.add_connection(operator_a, None,
                                            signal_ab_parameters, None,
                                            operator_b, None, None)
        netlist = model.make_netlist()

        # Check that the netlist is as expected
        assert netlist.operator_vertices == {
            operator_a: (vertex_a0, vertex_a1, vertex_a2),
            operator_b: (vertex_b, ),
        }
        assert len(netlist.nets) == 1
        for net in itervalues(netlist.nets):
            assert net.sources == [vertex_a0, vertex_a1]
            assert net.sinks == [vertex_b]

        assert len(netlist.constraints) == 0

        # Check that `transmit_signal` was called correctly
        sig, tp = vertex_a2.args
        assert sig.keyspace is keyspace
        assert tp is None
예제 #19
0
    def test_multiple_sink_vertices(self):
        """Test that each of the vertices associated with a sink is correctly
        included in the sinks of a net.
        """
        # Create the first operator
        vertex_a = mock.Mock(name="vertex A")
        load_fn_a = mock.Mock(name="load function A")
        pre_fn_a = mock.Mock(name="pre function A")
        post_fn_a = mock.Mock(name="post function A")

        object_a = mock.Mock(name="object A")
        operator_a = mock.Mock(name="operator A", spec_set=["make_vertices"])
        operator_a.make_vertices.return_value = \
            netlistspec((vertex_a, ), load_fn_a, pre_fn_a, post_fn_a)

        # Create the second operator
        vertex_b0 = mock.Mock(name="vertex B0")
        vertex_b1 = mock.Mock(name="vertex B1")
        load_fn_b = mock.Mock(name="load function B")

        object_b = mock.Mock(name="object B")
        operator_b = mock.Mock(name="operator B", spec_set=["make_vertices"])
        operator_b.make_vertices.return_value = \
            netlistspec([vertex_b0, vertex_b1], load_fn_b)

        # Create a third operator, which won't accept the signal
        vertex_c = mock.Mock(name="vertex C")
        vertex_c.accepts_signal.side_effect = lambda _, __: False

        object_c = mock.Mock(name="object C")
        operator_c = mock.Mock(name="operator C", spec_set=["make_vertices"])
        operator_c.make_vertices.return_value = netlistspec((vertex_c, ))

        # Create a signal between the operators
        keyspace = mock.Mock(name="keyspace")
        keyspace.length = 32
        signal_ab_parameters = SignalParameters(keyspace=keyspace, weight=3)

        # Create the model, add the items and then generate the netlist
        model = Model()
        model.object_operators[object_a] = operator_a
        model.object_operators[object_b] = operator_b
        model.object_operators[object_c] = operator_c
        model.connection_map.add_connection(operator_a, None,
                                            signal_ab_parameters, None,
                                            operator_b, None, None)
        model.connection_map.add_connection(operator_a, None,
                                            signal_ab_parameters, None,
                                            operator_c, None, None)
        netlist = model.make_netlist()

        # Check that the "accepts_signal" method of vertex_c was called with
        # reasonable arguments
        assert vertex_c.accepts_signal.called

        # Check that the netlist is as expected
        assert netlist.operator_vertices == {
            operator_a: (vertex_a, ),
            operator_b: (vertex_b0, vertex_b1),
            operator_c: (vertex_c, ),
        }
        assert len(netlist.nets) == 1
        for net in itervalues(netlist.nets):
            assert net.sources == [vertex_a]
            assert net.sinks == [vertex_b0, vertex_b1]
            assert net.weight == signal_ab_parameters.weight

        assert len(netlist.constraints) == 0
예제 #20
0
    def test_single_vertices(self):
        """Test that operators which produce single vertices work correctly and
        that all functions and signals are correctly collected and included in
        the final netlist.
        """
        # Create the first operator
        vertex_a = mock.Mock(name="vertex A")
        load_fn_a = mock.Mock(name="load function A")
        pre_fn_a = mock.Mock(name="pre function A")
        post_fn_a = mock.Mock(name="post function A")
        constraint_a = mock.Mock(name="Constraint B")

        object_a = mock.Mock(name="object A")
        operator_a = mock.Mock(name="operator A", spec_set=["make_vertices"])
        operator_a.make_vertices.return_value = \
            netlistspec((vertex_a, ), load_fn_a, pre_fn_a, post_fn_a,
                        constraint_a)

        # Create the second operator
        vertex_b = mock.Mock(name="vertex B")
        load_fn_b = mock.Mock(name="load function B")
        constraint_b = mock.Mock(name="Constraint B")

        object_b = mock.Mock(name="object B")
        operator_b = mock.Mock(name="operator B", spec_set=["make_vertices"])
        operator_b.make_vertices.return_value = \
            netlistspec((vertex_b, ), load_fn_b, constraints=[constraint_b])

        # Create a signal between the operators
        keyspace = mock.Mock(name="keyspace")
        keyspace.length = 32
        signal_ab_parameters = SignalParameters(keyspace=keyspace, weight=43)

        # Create the model, add the items and then generate the netlist
        model = Model()
        model.object_operators[object_a] = operator_a
        model.object_operators[object_b] = operator_b
        model.connection_map.add_connection(operator_a, None,
                                            signal_ab_parameters, None,
                                            operator_b, None, None)
        netlist = model.make_netlist()

        # Check that the make_vertices functions were called
        operator_a.make_vertices.assert_called_once_with(model)
        operator_b.make_vertices.assert_called_once_with(model)

        # Check that the netlist is as expected
        assert len(netlist.nets) == 1
        for net in itervalues(netlist.nets):
            assert net.sources == [vertex_a]
            assert net.sinks == [vertex_b]
            assert net.weight == signal_ab_parameters.weight

        assert netlist.operator_vertices == {
            operator_a: (vertex_a, ),
            operator_b: (vertex_b, ),
        }

        assert netlist.keyspaces is model.keyspaces
        assert set(netlist.constraints) == set([constraint_a, constraint_b])
        assert set(netlist.load_functions) == set([load_fn_a, load_fn_b])
        assert netlist.before_simulation_functions == [pre_fn_a]
        assert netlist.after_simulation_functions == [post_fn_a]
예제 #21
0
    def test_standard(self, use_make_connection):
        """Test building a single connection, ensure that all appropriate
        methods are called and that the signal is added to the connection map.
        """
        class A(object):
            pass

        # Create the connection (as a mock)
        connection_source = A()
        connection_sink = A()

        connection = mock.Mock()
        connection.pre_obj = connection_source
        connection.post_obj = connection_sink

        # Create the Model which we'll build with
        m = Model()

        # Modify the Model so that we can interpret calls to the connection map
        m.connection_map = mock.Mock(name="ConnectionMap")
        m.connection_map.insert_and_stack_interposers = mock.Mock(
            return_value=([], m.connection_map)  # NOP
        )

        source = mock.Mock(name="Source Object")
        source_port = mock.Mock(name="Source Port")
        sink = mock.Mock(name="Sink Object")
        sink_port = mock.Mock(name="Sink Port")

        # Add some build methods
        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))

        source_getters = {A: mock.Mock(side_effect=source_getter)}
        sink_getters = {A: mock.Mock(side_effect=sink_getter)}

        transmission_parameters = mock.Mock(name="Transmission Params")

        def transmission_builder(model, conn):
            assert model is m
            assert conn is connection
            return transmission_parameters

        reception_parameters = mock.Mock(name="Reception Params")

        def reception_builder(model, conn):
            assert model is m
            assert conn is connection
            return reception_parameters

        transmission_parameter_builders = {
            A: mock.Mock(side_effect=transmission_builder)
        }
        reception_parameter_builders = {
            A: mock.Mock(side_effect=reception_builder)
        }

        # Make the connection
        if use_make_connection:
            # Set an RNG to build with
            m.rng = np.random

            # Set the builders
            m._source_getters = source_getters
            m._sink_getters = sink_getters
            m._transmission_parameter_builders = \
                transmission_parameter_builders
            m._reception_parameter_builders = reception_parameter_builders

            # Build the connection directly
            m.make_connection(connection)
        else:
            # Embed the connection in a mock Nengo network and build that
            # instead.
            network = mock.Mock()
            network.seed = None
            network.connections = [connection]
            network.ensembles = []
            network.nodes = []
            network.networks = []
            network.probes = []

            # Build this (having overridden the builders)
            with mock.patch.object(m, "source_getters", source_getters), \
                    mock.patch.object(m, "sink_getters", sink_getters), \
                    mock.patch.object(m, "transmission_parameter_builders",
                                      transmission_parameter_builders), \
                    mock.patch.object(m, "reception_parameter_builders",
                                      reception_parameter_builders):
                m.build(network)

        # Assert the connection map received an appropriate call
        m.connection_map.add_connection.assert_called_once_with(
            source, source_port, SignalParameters(), transmission_parameters,
            sink, sink_port, reception_parameters)
def test_get_net_keyspaces():
    """Test the correct specification of keyspaces for nets."""
    # Create the vertices
    vertex_A = [Vertex() for _ in range(4)]
    vertex_B = Vertex()

    # Create placements such that vertex A and B fall on two chips and A[0] and
    # A[1] are on the same chip.
    placements = {
        vertex_A[0]: (0, 0),
        vertex_A[1]: (0, 0),
        vertex_A[2]: (0, 1),
        vertex_A[3]: (0, 1),
        vertex_B: (0, 0)
    }
    resources = {v: {} for v in placements}
    allocations = {v: {} for v in placements}

    # Manually assign cluster IDs
    vertex_A[0].cluster = 0
    vertex_A[1].cluster = 0
    vertex_A[2].cluster = 1
    vertex_A[3].cluster = 1

    # Create a container for the keyspaces
    ksc = KeyspaceContainer()

    # Create the signals and nets
    signal_a = Signal(object(), [],
                      SignalParameters(keyspace=ksc["nengo"](connection_id=0)))
    signal_b = Signal(object(), [],
                      SignalParameters(keyspace=ksc["nengo"](connection_id=1)))
    signal_c = Signal(object(), [], SignalParameters(keyspace=ksc["spam"]))

    nets = {
        signal_a: NMNet(vertex_A, vertex_B, 1.0),
        signal_b: NMNet(vertex_B, vertex_A, 2.0),
        signal_c: NMNet(vertex_A, vertex_A, 3.0),
    }

    # Get the routing nets
    _, _, _, _, derived_nets = utils.get_nets_for_routing(
        resources, nets, placements, allocations)

    # Get the net keyspaces
    net_keyspaces = utils.get_net_keyspaces(placements, nets, derived_nets)

    # Check the net keyspaces are correct
    # A -> B
    for xy, vertex in [((0, 0), vertex_A[0]), ((0, 1), vertex_A[2])]:
        net = derived_nets[nets[signal_a]][xy]
        cluster = vertex.cluster
        assert net_keyspaces[net] == signal_a.keyspace(cluster=cluster)

    # B -> A
    net = derived_nets[nets[signal_b]][(0, 0)]
    assert net_keyspaces[net] == signal_b.keyspace(cluster=0)

    # A -> A
    for xy in [(0, 0), (0, 1)]:
        net = derived_nets[nets[signal_c]][xy]
        assert net_keyspaces[net] == signal_c.keyspace  # No change