def test_ens_decoded_on_host(precompute, allclose, Simulator, seed, plt): out_synapse = nengo.synapses.Alpha(0.03) simtime = 0.6 with nengo.Network(seed=seed) as model: add_params(model) stim = nengo.Node(lambda t: [np.sin(t * 2 * np.pi / simtime)]) a = nengo.Ensemble(100, 1) model.config[a].on_chip = False b = nengo.Ensemble(100, 1) nengo.Connection(stim, a) nengo.Connection(a, b, function=lambda x: -x) p_stim = nengo.Probe(stim, synapse=out_synapse) p_a = nengo.Probe(a, synapse=out_synapse) p_b = nengo.Probe(b, synapse=out_synapse) with Simulator(model, precompute=precompute) as sim: sim.run(simtime) plt.plot(sim.trange(), sim.data[p_stim]) plt.plot(sim.trange(), sim.data[p_a]) plt.plot(sim.trange(), sim.data[p_b]) assert allclose(sim.data[p_a], sim.data[p_stim], atol=0.05, rtol=0.01) assert allclose(sim.data[p_b], -sim.data[p_a], atol=0.15, rtol=0.1)
def test_chip_learning_errors(): with nengo.Network() as net: add_params(net) a = nengo.Ensemble(100, 1) b = nengo.Ensemble(100, 1) net.config[b].on_chip = True nengo.Connection(a, b, learning_rule_type=nengo.PES()) with pytest.raises(BuildError, match="Post ensemble"): Split(net) with nengo.Network() as net: add_params(net) a = nengo.Ensemble(100, 1) b = nengo.Ensemble(100, 1) error = nengo.Ensemble(100, 1) net.config[error].on_chip = True conn = nengo.Connection(a, b, learning_rule_type=nengo.PES()) nengo.Connection(error, conn.learning_rule) with pytest.raises(BuildError, match="Pre ensemble"): Split(net)
def test_place_probes(): with nengo.Network() as net: add_params(net) offchip1 = nengo.Node(0) with nengo.Network(): onchip1 = nengo.Ensemble(10, 1) offchip2 = nengo.Ensemble(10, 1) net.config[offchip2].on_chip = False onchip2 = nengo.Ensemble(10, 1) nengo.Connection(onchip1, onchip2) nengo.Connection(offchip1, offchip2) offchip_probes = [ nengo.Probe(offchip1), nengo.Probe(offchip2), ] onchip_probes = [ nengo.Probe(onchip1), nengo.Probe(onchip2), ] split = Split(net) assert split.on_chip(onchip1) assert split.on_chip(onchip2) assert not split.on_chip(offchip1) assert not split.on_chip(offchip2) assert not any(split.on_chip(p) for p in offchip_probes) assert all(split.on_chip(p) for p in onchip_probes)
def build(self, obj, *args, **kwargs): # Don't build the objects marked as "to_remove" by PassthroughSplit if self.split is not None and obj in self.split.passthrough.to_remove: return None if not isinstance(obj, (Node, Ensemble, Probe)): model = self elif self.split.on_chip(obj): model = self else: # Note: callbacks for the host_model will not be invoked model = self.host_model(obj) # done for compatibility with nengo<=2.8.0 # otherwise we could just copy over the initial # seeding to all other models model.seeds[obj] = self.seeds[obj] model.seeded[obj] = self.seeded[obj] if isinstance(obj, Network): # some build functions assume the network has nengo-loihi config params add_params(obj) built = model.builder.build(model, obj, *args, **kwargs) if self.build_callback is not None: self.build_callback(obj) return built
def test_precompute_remove_passthrough(): with nengo.Network() as net: add_params(net) host = nengo.Node(0, label="host") onchip1 = nengo.Ensemble(1, 1, label="onchip1") passthrough1 = nengo.Node(size_in=1, label="passthrough1") onchip2 = nengo.Ensemble(1, 1, label="onchip2") passthrough2 = nengo.Node(size_in=1, label="passthrough2") onchip3 = nengo.Ensemble(1, 1, label="onchip3") nengo.Connection(host, onchip1) nengo.Connection(onchip1, passthrough1) nengo.Connection(passthrough1, onchip2) nengo.Connection(onchip2, passthrough2) nengo.Connection(passthrough2, onchip3) split = Split(net, precompute=True, remove_passthrough=True) assert split.is_precomputable(host) assert not split.on_chip(host) for obj in (onchip1, passthrough1, onchip2, passthrough2, onchip3): assert not split.is_precomputable(obj) for obj in (onchip1, onchip2, onchip3): assert split.on_chip(obj)
def test_place_ensembles(): with nengo.Network() as net: add_params(net) offchip = nengo.Ensemble(10, 1, label="offchip") net.config[offchip].on_chip = False direct = nengo.Ensemble(1, 1, neuron_type=nengo.Direct(), label="direct") with nengo.Network(): onchip = nengo.Ensemble(20, 1, label="onchip") pre = nengo.Ensemble(10, 1, label="pre") post = nengo.Ensemble(10, 1, label="post") error = nengo.Ensemble(10, 1, label="error") conn = nengo.Connection(pre, post, learning_rule_type=nengo.PES()) nengo.Connection(error, conn.learning_rule) networks = SplitNetworks(net, node_neurons=default_node_neurons) place_ensembles(networks) assert networks.moves[offchip] == "host" assert networks.moves[direct] == "host" assert networks.moves[onchip] == "chip" assert networks.moves[pre] == "chip" assert networks.moves[post] == "host" assert networks.moves[error] == "host"
def test_place_ensembles(): # builder will move the learning stuff onto the host with nengo.Network() as net: add_params(net) offchip = nengo.Ensemble(10, 1, label="offchip") net.config[offchip].on_chip = False direct = nengo.Ensemble( 1, 1, neuron_type=nengo.Direct(), label="direct") with nengo.Network(): onchip = nengo.Ensemble(20, 1, label="onchip") pre = nengo.Ensemble(10, 1, label="pre") post = nengo.Ensemble(10, 1, label="post") error = nengo.Ensemble(10, 1, label="error") conn = nengo.Connection(pre, post, learning_rule_type=nengo.PES()) nengo.Connection(error, conn.learning_rule) split = Split(net) assert not split.on_chip(offchip) assert not split.on_chip(direct) assert split.on_chip(onchip) assert split.on_chip(pre) assert not split.on_chip(post) assert not split.on_chip(error) for obj in net.all_ensembles + net.all_nodes: assert not split.is_precomputable(obj) with pytest.raises(BuildError, match="Locations are only established"): split.on_chip(conn)
def test_place_internetwork_connections(): with nengo.Network() as net: add_params(net) offchip = nengo.Ensemble(10, 1) net.config[offchip].on_chip = False onchip = nengo.Ensemble(10, 1) onon = nengo.Connection(onchip, onchip) onoff = nengo.Connection(onchip, offchip) offon = nengo.Connection(offchip, onchip) offoff = nengo.Connection(offchip, offchip) split = Split(net) assert split.on_chip(onon.pre) assert split.on_chip(onon.post) assert split.on_chip(onoff.pre) assert not split.on_chip(onoff.post) assert not split.on_chip(offon.pre) assert split.on_chip(offon.post) assert not split.on_chip(offoff.pre) assert not split.on_chip(offoff.post)
def test_split_host_to_learning_rule(): with nengo.Network() as net: add_params(net) pre = nengo.Ensemble(10, 1, label="pre") post = nengo.Ensemble(10, 1, label="post") err_onchip = nengo.Ensemble(10, 1, label="err_onchip") err_offchip = nengo.Ensemble(10, 1, label="err_offchip") net.config[err_offchip].on_chip = False ens_conn = nengo.Connection(pre, post, learning_rule_type=nengo.PES()) neurons_conn = nengo.Connection(pre.neurons, post.neurons, learning_rule_type=nengo.PES()) nengo.Connection(err_onchip, ens_conn.learning_rule) nengo.Connection( err_onchip, neurons_conn.learning_rule) nengo.Connection(err_offchip, ens_conn.learning_rule) nengo.Connection( err_offchip, neurons_conn.learning_rule) split = Split(net) assert split.on_chip(pre) assert not split.on_chip(post) assert not split.on_chip(err_onchip) assert not split.on_chip(err_offchip)
def test_n2n_on_host(precompute, allclose, Simulator, seed_ens, seed, plt): """Ensure that neuron to neuron connections work on and off chip.""" if not seed_ens and nengo.version.version_info <= (2, 8, 0): plt.saveas = None pytest.xfail("Seeds change when moving ensembles off/on chip") n_neurons = 50 # When the ensemble is seeded, the output plots will make more sense, # but the test should work whether they're seeded or not. ens_seed = (seed + 1) if seed_ens else None simtime = 1.0 with nengo.Network(seed=seed) as model: add_params(model) stim = nengo.Node(lambda t: [np.sin(t * 2 * np.pi / simtime)]) # pre receives stimulation and represents the sine wave pre = nengo.Ensemble(n_neurons, dimensions=1, seed=ens_seed) model.config[pre].on_chip = False nengo.Connection(stim, pre) # post has pre's neural activity forwarded to it. # Since the neuron parameters are the same, it should also represent # the same sine wave. # The 0.015 scaling is chosen so the values match visually, # though a more principled reason would be better. post = nengo.Ensemble(n_neurons, dimensions=1, seed=ens_seed) nengo.Connection(pre.neurons, post.neurons, transform=np.eye(n_neurons) * 0.015) p_synapse = nengo.synapses.Alpha(0.03) p_stim = nengo.Probe(stim, synapse=p_synapse) p_pre = nengo.Probe(pre, synapse=p_synapse) p_post = nengo.Probe(post, synapse=p_synapse) with Simulator(model, precompute=precompute) as sim: sim.run(simtime) t = sim.trange() model.config[pre].on_chip = True with Simulator(model, precompute=precompute) as sim2: sim2.run(simtime) t2 = sim2.trange() plt.plot(t, sim.data[p_stim], c="k", label="input") plt.plot(t, sim.data[p_pre], label="pre off-chip") plt.plot(t, sim.data[p_post], label="post (pre off-chip)") plt.plot(t2, sim2.data[p_pre], label="pre on-chip") plt.plot(t2, sim2.data[p_post], label="post (pre on-chip)") plt.legend() assert allclose(sim.data[p_pre], sim2.data[p_pre], atol=0.1) assert allclose(sim.data[p_post], sim2.data[p_post], atol=0.1)
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)
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="Cannot precompute"): Split(net, precompute=True)
def test_precompute_host_to_learning_rule_unsupported(): with nengo.Network() as net: add_params(net) pre = nengo.Ensemble(10, 1, label="pre") post = nengo.Ensemble(10, 1, label="post") nengo.Connection(pre, post, learning_rule_type=nengo.PES()) with pytest.raises(BuildError, match="learning rules"): Split(net, precompute=True)
def test_neurons_to_ensemble_transform(pre_on_chip, post_ensemble, Simulator, seed, rng, allclose, plt): with nengo.Network(seed=seed) as net: add_params(net) stim = nengo.Node(lambda t: [np.sin(t * 2 * np.pi)]) n_pre = 50 pre_encoders = np.ones((n_pre, 1)) pre_encoders[n_pre // 2:] *= -1 pre = nengo.Ensemble(n_pre, 1, encoders=pre_encoders) net.config[pre].on_chip = pre_on_chip nengo.Connection(stim, pre, synapse=None) n_post = 51 pre_decoders = pre_encoders.T / (100 * n_pre / 2) post = nengo.Ensemble(n_post, 1) if post_ensemble else nengo.Node( size_in=1) nengo.Connection(pre.neurons, post, transform=pre_decoders, synapse=0.005) p_pre = nengo.Probe(pre, synapse=nengo.synapses.Alpha(0.03)) p_post = nengo.Probe(post, synapse=nengo.synapses.Alpha(0.03)) with nengo.Simulator(net) as nengosim: nengosim.run(1.0) with Simulator(net) as sim: sim.run(1.0) y0 = nengo.synapses.Lowpass(0.01).filt(nengosim.data[p_post].sum(axis=1)) y1 = sim.data[p_post].sum(axis=1) t = sim.trange() plt.subplot(2, 1, 1) plt.plot(t, nengosim.data[p_pre], c="k") plt.plot(t, sim.data[p_pre], c="g") plt.ylim([-1, 1]) plt.ylabel("Decoded pre value") plt.xlabel("Time (s)") plt.subplot(2, 1, 2) plt.plot(t, y0, c="k") plt.plot(t, y1, c="g") plt.ylim([-1, 1]) plt.ylabel("Decoded post value") plt.xlabel("Time (s)") assert allclose(y1, y0, rtol=1e-1, atol=0.1 * y0.max())
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)
def test_block_shape_errors(): with pytest.raises(ValidationError, match="[Mm]ust be a tuple"): BlockShape([5], [15]) with pytest.raises(ValidationError, match="[Mm]ust be an int"): BlockShape((5,), (15.0,)) with pytest.raises(ValidationError, match="[Mm]ust be the same length"): BlockShape((2, 2), (8,)) with nengo.Network() as net: add_params(net) a = nengo.Ensemble(10, 1) with pytest.raises(ValidationError, match="Block shape ensemble size"): net.config[a].block_shape = BlockShape((3, 2), (6, 2))
def __init__(self, network): # We call this in case it hasn't been called before, as we expect the # on_chip configuration option to be defined for these objects. # It is safe to call it twice. add_params(network) # Objects split to the host. self.host_objs = set() # Objects split to the chip. self.chip_objs = set() # Place objects on host or chip self._place_nodes(network) self._place_ensembles(network) self._place_probes(network)
def test_dists(Simulator, seed): # check that distributions on connection transforms are handled correctly with nengo.Network(seed=seed) as net: a = nengo.Node([1]) b = nengo.Ensemble(50, 1, radius=2) conn0 = nengo.Connection(a, b, transform=nengo.dists.Uniform(-1, 1)) c = nengo.Ensemble(50, 1) nengo.Connection(b, c, transform=nengo.dists.Uniform(-1, 1), seed=seed + 3) d = nengo.Ensemble(50, 1) conn1 = nengo.Connection(c.neurons, d.neurons, transform=nengo.dists.Uniform(-1, 1)) add_params(net) net.config[d].on_chip = False p0 = nengo.Probe(c) p1 = nengo.Probe(d) p2 = nengo.Probe(b.neurons) simtime = 0.1 with Simulator(net) as sim: sim.run(simtime) with Simulator(net) as sim2: sim2.run(simtime) assert np.allclose(sim.data[p0], sim2.data[p0]) assert np.allclose(sim.data[p1], sim2.data[p1]) assert np.allclose(sim.data[p2], sim2.data[p2]) conn0.seed = seed + 1 with Simulator(net) as sim2: sim2.run(simtime) assert not np.allclose(sim.data[p2], sim2.data[p2]) conn0.seed = None conn1.seed = seed + 1 with Simulator(net) as sim2: sim2.run(simtime) assert not np.allclose(sim.data[p1], sim2.data[p1])
def test_sliced_passthrough_bug(): with nengo.Network() as model: add_params(model) a = nengo.Ensemble(1, 1, label="a") passthrough = nengo.Node(size_in=1, label="passthrough") nengo.Connection(a, passthrough) p = nengo.Probe(passthrough[0]) split = Split(model, remove_passthrough=True) assert len(split.passthrough.to_add) == 0 assert len(split.passthrough.to_remove) == 0 assert split.on_chip(a) assert not split.on_chip(passthrough) assert not split.on_chip(p)
def test_split_remove_passthrough(remove_passthrough): with nengo.Network() as net: add_params(net) keep1 = nengo.Node(0, label="keep1") keep2 = nengo.Node(lambda t, x: x, size_in=1, label="keep2") keep3 = nengo.Node(size_in=1, label="keep3") chip1 = nengo.Ensemble(10, 1, label="chip1") discard1 = nengo.Node(size_in=1, label="discard1") chip2 = nengo.Ensemble(10, 1, label="chip2") discard2 = nengo.Node(size_in=1, label="discard2") chip3 = nengo.Ensemble(10, 1, label="chip3") keep4 = nengo.Node(size_in=1, label="keep4") probe = nengo.Probe(keep4) nengo.Connection(keep1, keep2) nengo.Connection(keep2, keep3) nengo.Connection(keep3, chip1) conn1 = nengo.Connection(chip1, discard1) conn2 = nengo.Connection(discard1, chip2) conn3 = nengo.Connection(chip2, discard2) conn4 = nengo.Connection(discard2, chip3) nengo.Connection(chip3, keep4) split = Split(net, remove_passthrough=remove_passthrough) assert not split.on_chip(probe) if remove_passthrough: assert split.passthrough.to_remove == { conn1, conn2, conn3, conn4, discard1, discard2, } conns = list(split.passthrough.to_add) assert len(conns) == 2 prepost = {(conn.pre, conn.post) for conn in conns} assert prepost == {(chip1, chip2), (chip2, chip3)} else: assert split.passthrough.to_remove == set() assert split.passthrough.to_add == set()
def test_split_pre_from_host(): with nengo.Network() as net: add_params(net) pre_1 = nengo.Node(0, label="pre_1") pre_2 = nengo.Ensemble(10, 1, label="pre_2") pre_3 = nengo.Node(size_in=1, label="pre_3") pre_4 = nengo.Ensemble(1, 1, label="pre_4") pre_5 = nengo.Probe(pre_4) onchip = nengo.Ensemble(1, 1, label="onchip") post1 = nengo.Ensemble(10, 1, label="post1") post2 = nengo.Node(size_in=1, label="post2") post3 = nengo.Probe(post2, label="post3") nengo.Connection(pre_1, pre_2) nengo.Connection(pre_2, pre_3) nengo.Connection(pre_3, pre_4) nengo.Connection(pre_4.neurons, onchip) nengo.Connection(onchip, post1) nengo.Connection(post1, post2) net.config[pre_2].on_chip = False net.config[pre_4].on_chip = False net.config[post1].on_chip = False split = Split(net, precompute=True) host_precomputable = {pre_1, pre_2, pre_3, pre_4, pre_5} for obj in host_precomputable: assert not split.on_chip(obj) assert split.is_precomputable(obj) host_nonprecomputable = {post1, post2, post3} for obj in host_nonprecomputable: assert not split.on_chip(obj) assert not split.is_precomputable(obj) assert split.on_chip(onchip) assert not split.is_precomputable(onchip) with pytest.raises(BuildError, match="not a part of the network"): split.is_precomputable( nengo.Node(0, add_to_container=False))
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
def test_place_nodes(): # all nodes go on the host # ChipReceiveNodes and HostSendNodes are created later by the builder with nengo.Network() as net: add_params(net) offchip1 = nengo.Node(0) with nengo.Network(): offchip2 = nengo.Node(np.sin) ensemble = nengo.Ensemble(100, 1) offchip3 = nengo.Node(size_in=1) nengo.Connection(ensemble, offchip3) with nengo.Network(): nowhere = nengo.Node(0) split = Split(net) assert not split.on_chip(offchip1) assert not split.on_chip(offchip2) assert not split.on_chip(offchip3) with pytest.raises(BuildError, match="not a part of the network"): split.on_chip(nowhere)
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)
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)