예제 #1
0
def test_split_no_node_neuron_error():
    with nengo.Network() as net:
        add_params(net)
        node_offchip = nengo.Node(np.sin)
        ens_onchip = nengo.Ensemble(10, 1)
        nengo.Connection(node_offchip, ens_onchip)

    with pytest.raises(BuildError, match="DecodeNeurons"):
        split(net, precompute=False, node_neurons=None, node_tau=None)
예제 #2
0
def test_split_precompute_loop_error():
    with nengo.Network() as net:
        add_params(net)
        node_offchip = nengo.Node(lambda t, x: x + 1, size_in=1, size_out=1)
        ens_onchip = nengo.Ensemble(10, 1)
        nengo.Connection(node_offchip, ens_onchip)
        nengo.Connection(ens_onchip, node_offchip)

    with pytest.raises(BuildError, match="precompute"):
        split(net,
              precompute=True,
              node_neurons=default_node_neurons,
              node_tau=0.005)
예제 #3
0
def test_split_conv2d_transform_error():
    with nengo.Network() as net:
        add_params(net)
        node_offchip = nengo.Node([1])
        ens_onchip = nengo.Ensemble(10, 1)
        conv2d = nengo.Convolution(n_filters=1,
                                   input_shape=(1, 1, 1),
                                   kernel_size=(1, 1))
        nengo.Connection(node_offchip, ens_onchip, transform=conv2d)

    with pytest.raises(BuildError, match="Conv2D"):
        split(net,
              precompute=False,
              node_neurons=default_node_neurons,
              node_tau=0.005)
예제 #4
0
def test_identity_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)
        nengo.Connection(a.output, b.input)

    nengo_loihi.add_params(model)
    networks = splitter.split(model,
                              precompute=False,
                              remove_passthrough=True,
                              max_rate=1000,
                              inter_tau=0.005)

    # ignore the a.input -> a.ensemble connections
    connections = [
        c for c in networks.chip.connections
        if not (isinstance(c.pre_obj, splitter.ChipReceiveNode)
                and c.post_obj in a.ensembles)
    ]

    assert len(connections) == n_ensembles
    pre = set()
    post = set()
    for c in connections:
        assert c.pre in a.all_ensembles or c.pre_obj is a.input
        assert c.post in b.all_ensembles
        assert np.allclose(c.transform, np.eye(ens_dimensions))
        pre.add(c.pre)
        post.add(c.post)
    assert len(pre) == n_ensembles
    assert len(post) == n_ensembles
예제 #5
0
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)))

    nengo_loihi.add_params(model)
    networks = splitter.split(model,
                              precompute=False,
                              remove_passthrough=True,
                              max_rate=1000,
                              inter_tau=0.005)

    # ignore the a.input -> a.ensemble connections
    connections = [
        c for c in networks.chip.connections
        if not (isinstance(c.pre_obj, splitter.ChipReceiveNode)
                and c.post_obj in a.ensembles)
    ]

    assert len(connections) == n_ensembles**2
    pairs = set()
    for c in connections:
        assert c.pre in a.all_ensembles
        assert c.post in b.all_ensembles
        assert np.allclose(c.transform,
                           np.ones((ens_dimensions, ens_dimensions)))
        pairs.add((c.pre, c.post))
    assert len(pairs) == n_ensembles**2
예제 #6
0
def test_consistent_order():
    with nengo.Network() as model:
        add_params(model)

        u0 = nengo.Node(0, label="u0")
        for i in range(5):
            e = nengo.Ensemble(i + 1, 1, label="e%d" % i)
            f = nengo.Ensemble(i + 1, 1, label="f%d" % i)
            nengo.Connection(u0, e, label="c0%d" % i)
            nengo.Connection(e, f, label="cf%d" % i)
            nengo.Probe(e)
            nengo.Probe(f.neurons)

    # Test splitting a number of times, making sure the order of things matches
    # the original network each time
    split_params = dict(
        precompute=False,
        node_neurons=OnOffDecodeNeurons(dt=0.001),
        node_tau=0.005,
        remove_passthrough=False,
    )

    networks0 = split(model, **split_params)
    for _ in range(5):
        networks = split(model, **split_params)

        # --- order matches original network
        assert len(model.all_ensembles) == len(networks.chip.all_ensembles)
        for ea, eb in zip(model.all_ensembles, networks.chip.all_ensembles):
            assert ea.n_neurons == eb.n_neurons and ea.label == eb.label

        # --- order matches previous split
        for attr in ('connections', 'ensembles', 'nodes', 'probes'):
            for net in ('host_pre', 'host', 'chip'):
                aa = getattr(getattr(networks0, net), 'all_' + attr)
                bb = getattr(getattr(networks, net), 'all_' + attr)
                for a, b in zip(aa, bb):
                    assert a.label == b.label
예제 #7
0
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)

    nengo_loihi.add_params(model)
    networks = splitter.split(model,
                              precompute=False,
                              remove_passthrough=True,
                              max_rate=1000,
                              inter_tau=0.005)

    # ignore the a.input -> a.ensemble connections
    connections = [
        c for c in networks.chip.connections
        if not (isinstance(c.pre_obj, splitter.ChipReceiveNode)
                and c.post_obj in a.ensembles)
    ]

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

    # check that model builds/runs correctly
    with Simulator(model, remove_passthrough=True) as sim:
        sim.step()
예제 #8
0
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)
        nengo.Connection(b, c)
        nengo.Connection(c, d)
        nengo.Connection(d, e)
        nengo.Connection(e, f)
        nengo.Connection(f, g)
        nengo.Probe(g)

    nengo_loihi.add_params(model)
    networks = splitter.split(model,
                              precompute=False,
                              remove_passthrough=True,
                              max_rate=1000,
                              inter_tau=0.005)
    chip = networks.chip
    host = networks.host

    assert a in host.nodes
    assert a not in chip.nodes
    assert c not in host.nodes
    assert c not in chip.nodes
    assert d not in host.nodes
    assert d not in chip.nodes
    assert e not in host.nodes
    assert e not in chip.nodes
    assert g in host.nodes
    assert g not in chip.nodes
예제 #9
0
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))

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

    nengo_loihi.add_params(model)
    networks = splitter.split(model,
                              precompute=False,
                              remove_passthrough=True,
                              max_rate=1000,
                              inter_tau=0.005)
    chip = networks.chip

    assert len(chip.connections) == 1
    conn = chip.connections[0]
    assert np.allclose(conn.transform, np.dot(t2, t1))
예제 #10
0
    def __init__(  # noqa: C901
            self,
            network,
            dt=0.001,
            seed=None,
            model=None,
            precompute=False,
            target=None,
            progress_bar=None,
            remove_passthrough=True,
            hardware_options=None,
    ):
        # initialize values used in __del__ and close() first
        self.closed = True
        self.precompute = precompute
        self.networks = None
        self.sims = OrderedDict()
        self._run_steps = None

        hardware_options = {} if hardware_options is None else hardware_options

        if progress_bar:
            warnings.warn("nengo-loihi does not support progress bars")

        if HAS_DL:
            install_dl_builders()

        if model is None:
            # Call the builder to make a model
            self.model = Model(dt=float(dt), label="%s, dt=%f" % (network, dt))
        else:
            assert isinstance(model, Model), (
                "model is not type 'nengo_loihi.builder.Model'")
            self.model = model
            assert self.model.dt == dt

        if network is not None:
            nengo.rc.set("decoder_cache", "enabled", "False")
            config.add_params(network)

            # ensure seeds are identical to nengo
            seed_network(network, seeds=self.model.seeds,
                         seeded=self.model.seeded)

            # split the host into one, two or three networks
            self.networks = split(
                network,
                precompute=precompute,
                node_neurons=self.model.node_neurons,
                node_tau=self.model.decode_tau,
                remove_passthrough=remove_passthrough,
            )
            network = self.networks.chip

            self.model.chip2host_params = self.networks.chip2host_params

            self.chip = self.networks.chip
            self.host = self.networks.host
            self.host_pre = self.networks.host_pre

            if len(self.host_pre.all_objects) > 0:
                host_pre_model = self._get_host_model(
                    self.host_pre, dt=dt, seeds=self.model.seeds,
                    seeded=self.model.seeded)
                self.sims["host_pre"] = nengo.Simulator(self.host_pre,
                                                        dt=self.dt,
                                                        model=host_pre_model,
                                                        progress_bar=False,
                                                        optimize=False)

            if len(self.host.all_objects) > 0:
                host_model = self._get_host_model(
                    self.host, dt=dt, seeds=self.model.seeds,
                    seeded=self.model.seeded)
                self.sims["host"] = nengo.Simulator(
                    self.host,
                    dt=self.dt,
                    model=host_model,
                    progress_bar=False,
                    optimize=False)
            elif not precompute:
                # If there is no host and precompute=False, then all objects
                # must be on the chip, which is precomputable in the sense that
                # no communication has to happen with the host.
                # We could warn about this, but we want to avoid people having
                # to specify `precompute` unless they absolutely have to.
                self.precompute = True

            # Build the network into the model
            self.model.build(network)

        self._probe_outputs = self.model.params
        self.data = ProbeDict(self._probe_outputs)
        for sim in self.sims.values():
            self.data.add_fallback(sim.data)

        if seed is None:
            if network is not None and network.seed is not None:
                seed = network.seed + 1
            else:
                seed = np.random.randint(npext.maxint)

        if target is None:
            target = 'loihi' if HAS_NXSDK else 'sim'
        self.target = target

        logger.info("Simulator target is %r", target)
        logger.info("Simulator precompute is %r", self.precompute)

        if target != "simreal":
            discretize_model(self.model)

        if target in ("simreal", "sim"):
            self.sims["emulator"] = EmulatorInterface(self.model, seed=seed)
        elif target == 'loihi':
            assert HAS_NXSDK, "Must have NxSDK installed to use Loihi hardware"
            self.sims["loihi"] = HardwareInterface(
                self.model, use_snips=not self.precompute, seed=seed,
                **hardware_options)
        else:
            raise ValidationError("Must be 'simreal', 'sim', or 'loihi'",
                                  attr="target")

        assert "emulator" in self.sims or "loihi" in self.sims

        self.closed = False
        self.reset(seed=seed)
예제 #11
0
    def __init__(  # noqa: C901
            self,
            network,
            dt=0.001,
            seed=None,
            model=None,
            precompute=False,
            target=None,
            progress_bar=None,
            remove_passthrough=True
    ):
        self.closed = True  # Start closed in case constructor raises exception
        if progress_bar is not None:
            raise NotImplementedError("progress bars not implemented")

        if model is None:
            # Call the builder to make a model
            self.model = Model(dt=float(dt), label="%s, dt=%f" % (network, dt))
        else:
            assert isinstance(model, Model), (
                "model is not type 'nengo_loihi.builder.Model'")
            self.model = model
            assert self.model.dt == dt

        max_rate = self.model.inter_rate * self.model.inter_n
        rtol = 1e-8  # allow for floating point inaccuracies
        if max_rate > (1. / self.dt) * (1 + rtol):
            raise BuildError("Simulator `dt` must be <= %s (got %s)"
                             % (1. / max_rate, self.dt))
        self.precompute = precompute
        self.networks = None
        self.sims = OrderedDict()
        self._run_steps = None

        if network is not None:
            nengo.rc.set("decoder_cache", "enabled", "False")
            config.add_params(network)

            # split the host into one, two or three networks
            self.networks = split(
                network,
                precompute,
                max_rate,
                self.model.inter_tau,
                remove_passthrough=remove_passthrough,
            )
            network = self.networks.chip

            self.model.chip2host_params = self.networks.chip2host_params

            self.chip = self.networks.chip
            self.host = self.networks.host
            self.host_pre = self.networks.host_pre

            if len(self.host_pre.all_objects) > 0:
                self.sims["host_pre"] = nengo.Simulator(self.host_pre,
                                                        dt=self.dt,
                                                        progress_bar=False,
                                                        optimize=False)

            if len(self.host.all_objects) > 0:
                self.sims["host"] = nengo.Simulator(
                    self.host, dt=self.dt, progress_bar=False, optimize=False)
            elif not precompute:
                # If there is no host and precompute=False, then all objects
                # must be on the chip, which is precomputable in the sense that
                # no communication has to happen with the host.
                # We could warn about this, but we want to avoid people having
                # to specify `precompute` unless they absolutely have to.
                self.precompute = True

            # Build the network into the model
            self.model.build(network)

        self._probe_outputs = self.model.params
        self.data = ProbeDict(self._probe_outputs)
        for sim in self.sims.values():
            self.data.add_fallback(sim.data)

        if seed is None:
            if network is not None and network.seed is not None:
                seed = network.seed + 1
            else:
                seed = np.random.randint(npext.maxint)

        if target is None:
            try:
                import nxsdk
                target = 'loihi'
            except ImportError:
                target = 'sim'
        self.target = target

        logger.info("Simulator target is %r", target)
        logger.info("Simulator precompute is %r", self.precompute)

        if target != "simreal":
            self.model.discretize()

        if target in ("simreal", "sim"):
            self.sims["emulator"] = CxSimulator(self.model, seed=seed)
        elif target == 'loihi':
            self.sims["loihi"] = LoihiSimulator(
                self.model, use_snips=not self.precompute, seed=seed)
        else:
            raise ValidationError("Must be 'simreal', 'sim', or 'loihi'",
                                  attr="target")

        assert "emulator" in self.sims or "loihi" in self.sims

        self.closed = False
        self.reset(seed=seed)