Beispiel #1
0
    def __init__(self, network, precompute=False, remove_passthrough=True):
        self.network = network

        # subset of network: only nodes and ensembles;
        # probes are handled dynamically
        self._seen_objects = set()

        # subset of seen, marking which are run on the hardware;
        # those running on the host are "seen - chip"
        self._chip_objects = set()

        # Step 1. Place nodes on host
        self._seen_objects.update(network.all_nodes)

        # Step 2. Place all possible ensembles on chip
        # Note: assumes add_params already called by the simulator
        for ens in network.all_ensembles:
            if (network.config[ens].on_chip in (None, True)
                    and not isinstance(ens.neuron_type, Direct)):
                self._chip_objects.add(ens)
            self._seen_objects.add(ens)

        # Step 3. Move learning ensembles (post and error) to host
        for conn in network.all_connections:
            pre = base_obj(conn.pre)
            post = base_obj(conn.post)
            if (conn.learning_rule_type is not None
                    and isinstance(post, Ensemble)
                    and post in self._chip_objects):
                if network.config[post].on_chip:
                    raise BuildError("Post ensemble (%r) of learned "
                                     "connection (%r) must not be configured "
                                     "as on_chip." % (post, conn))
                self._chip_objects.remove(post)
            elif (isinstance(post, LearningRule)
                  and isinstance(pre, Ensemble)
                  and pre in self._chip_objects):
                if network.config[pre].on_chip:
                    raise BuildError("Pre ensemble (%r) of error "
                                     "connection (%r) must not be configured "
                                     "as on_chip." % (pre, conn))
                self._chip_objects.remove(pre)

        # Step 4. Mark passthrough nodes for removal
        if remove_passthrough:
            passthroughs = set(
                obj for obj in network.all_nodes if is_passthrough(obj))
            ignore = self._seen_objects - self._chip_objects - passthroughs
            self.passthrough = PassthroughSplit(network, ignore)
        else:
            self.passthrough = PassthroughSplit(None)

        # Step 5. Split precomputable parts of host
        # This is a subset of host, marking which are precomputable
        if precompute:
            self._host_precomputable_objects = self._preclosure()
        else:
            self._host_precomputable_objects = set()
def test_passthrough_placement():
    with nengo.Network() as model:
        stim = nengo.Node(0)
        a = nengo.Node(None, size_in=1)  # should be off-chip
        b = nengo.Ensemble(10, 1)
        c = nengo.Node(None, size_in=1)  # should be removed
        d = nengo.Node(None, size_in=1)  # should be removed
        e = nengo.Node(None, size_in=1)  # should be removed
        f = nengo.Ensemble(10, 1)
        g = nengo.Node(None, size_in=1)  # should be off-chip
        nengo.Connection(stim, a)
        nengo.Connection(a, b)
        conn_bc = nengo.Connection(b, c)
        conn_cd = nengo.Connection(c, d)
        conn_de = nengo.Connection(d, e)
        conn_ef = nengo.Connection(e, f)
        nengo.Connection(f, g)
        nengo.Probe(g)

    split = PassthroughSplit(model, ignore={stim})

    assert split.to_remove == {c, d, e, conn_bc, conn_cd, conn_de, conn_ef}
    assert len(split.to_add) == 1
    conn = next(iter(split.to_add))
    assert conn.pre is b
    assert conn.post is f
Beispiel #3
0
    def __init__(self, network, precompute=None, remove_passthrough=True):
        self.network = network

        # Place objects on host or chip
        self.hostchip = HostChipSplit(network)

        # Determine how passthrough nodes will be handled
        if remove_passthrough:
            self.passthrough = PassthroughSplit(self.network, self.hostchip)
        else:
            self.passthrough = PassthroughSplit(None, None)

        # Determine which host objects are precomputable
        self._precomputable = PrecomputableSplit(
            network, self.hostchip, self.passthrough, strict=precompute is True
        )
        self.precompute = precompute
        if self.precompute is None:
            self.precompute = self.precomputable()
def test_full_array(n_ensembles, ens_dimensions):
    with nengo.Network() as model:
        a = nengo.networks.EnsembleArray(10, n_ensembles, ens_dimensions)
        b = nengo.networks.EnsembleArray(10, n_ensembles, ens_dimensions)
        D = n_ensembles * ens_dimensions
        nengo.Connection(a.output, b.input, transform=np.ones((D, D)))

    split = PassthroughSplit(model)

    assert len(split.to_add) == n_ensembles**2

    pairs = set()
    for conn in split.to_add:
        assert conn.pre in a.all_ensembles
        assert conn.post in b.all_ensembles
        assert np.allclose(transform_array(conn.transform),
                           np.ones((ens_dimensions, ens_dimensions)))
        pairs.add((conn.pre, conn.post))
    assert len(pairs) == n_ensembles**2
def test_transform_merging(d1, d2, d3):
    with nengo.Network() as model:
        a = nengo.Ensemble(10, d1)
        b = nengo.Node(None, size_in=d2)
        c = nengo.Ensemble(10, d3)

        t1 = np.random.uniform(-1, 1, (d2, d1))
        t2 = np.random.uniform(-1, 1, (d3, d2))

        conn_ab = nengo.Connection(a, b, transform=t1)
        conn_bc = nengo.Connection(b, c, transform=t2)

    split = PassthroughSplit(model)

    assert split.to_remove == {b, conn_ab, conn_bc}

    assert len(split.to_add) == 1
    conn = next(iter(split.to_add))
    assert np.allclose(transform_array(conn.transform), np.dot(t2, t1))
Beispiel #6
0
def test_identity_array(n_ensembles, ens_dimensions):
    with nengo.Network() as net:
        a = nengo.networks.EnsembleArray(10, n_ensembles, ens_dimensions)
        b = nengo.networks.EnsembleArray(10, n_ensembles, ens_dimensions)
        nengo.Connection(a.output, b.input)

    split = PassthroughSplit(net, HostChipSplit(net))

    assert len(split.to_add) == n_ensembles

    pre = set()
    post = set()
    for conn in split.to_add:
        assert conn.pre in a.all_ensembles or conn.pre_obj is a.input
        assert conn.post in b.all_ensembles
        assert np.allclose(conn.transform.init, np.eye(ens_dimensions))
        pre.add(conn.pre)
        post.add(conn.post)
    assert len(pre) == n_ensembles
    assert len(post) == n_ensembles
def test_synapse_merging(Simulator, seed):
    with nengo.Network(seed=seed) as model:
        a = nengo.networks.EnsembleArray(10, n_ensembles=2)
        b = nengo.Node(None, size_in=2)
        c = nengo.networks.EnsembleArray(10, n_ensembles=2)
        nengo.Connection(a.output[0], b[0], synapse=None)
        nengo.Connection(a.output[1], b[1], synapse=0.1)
        nengo.Connection(b[0], c.input[0], synapse=None)
        nengo.Connection(b[0], c.input[1], synapse=0.2)
        nengo.Connection(b[1], c.input[0], synapse=None)
        nengo.Connection(b[1], c.input[1], synapse=0.2)

    split = PassthroughSplit(model)

    assert len(split.to_add) == 4

    desired_filters = {
        ('0', '0'): None,
        ('0', '1'): 0.2,
        ('1', '0'): 0.1,
        ('1', '1'): 0.3,
    }
    for conn in split.to_add:
        if desired_filters[(conn.pre.label, conn.post.label)] is None:
            assert conn.synapse is None
        else:
            assert isinstance(conn.synapse, nengo.Lowpass)
            assert np.allclose(
                conn.synapse.tau,
                desired_filters[(conn.pre.label, conn.post.label)])

    # check that model builds/runs, and issues the warning
    with pytest.warns(UserWarning) as record:
        with Simulator(model, remove_passthrough=True) as sim:
            sim.step()

    assert any("Combining two Lowpass synapses" in r.message.args[0]
               for r in record)