Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splitter refactoring #202

Merged
merged 13 commits into from
Apr 26, 2019
2 changes: 1 addition & 1 deletion .ci/hardware.sh.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
pip install -e .[tests]
pip install $NENGO_VERSION --upgrade
pip install ~/travis-ci/nxsdk-0.8.0.tar.gz
SLURM=1 pytest --target loihi --no-hang -v --durations 50 --color=yes -n 2 --cov=nengo_loihi --cov-report=xml --cov-report=term-missing || HW_STATUS=1
SLURM=1 pytest --target loihi --no-hang -v --durations 50 --color=yes -n 1 --cov=nengo_loihi --cov-report=xml --cov-report=term-missing || HW_STATUS=1
exit \$HW_STATUS
EOF
{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion .nengobones.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ ci_scripts:
pip_install:
- flake8
post_commands:
- flake8 nengo
- flake8 nengo_loihi
- flake8 --ignore=E226,E703,W391,W503 docs
- template: deploy

Expand Down
24 changes: 24 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,30 @@ Release history

- Switched to nengo-bones templating system for TravisCI config/scripts.
(`#204 <https://github.com/nengo/nengo-loihi/pull/204>`__)
- It is no longer possible to pass ``network=None`` to ``Simulator``.
Previously this was possible, but unlikely to work as expected.
(`#202 <https://github.com/nengo/nengo-loihi/pull/202>`__)
- Better error messages are raised when attempting to simulate networks
in which certain objects participating in a learning rule are on-chip.
(`#202 <https://github.com/nengo/nengo-loihi/pull/202>`__,
`#208 <https://github.com/nengo/nengo-loihi/issues/208>`__,
`#209 <https://github.com/nengo/nengo-loihi/issues/209>`__)

**Fixed**

- The splitting and passthrough removal procedures were significantly
refactored, which fixed an issue in which networks could be modified
in the splitting process.
(`#202 <https://github.com/nengo/nengo-loihi/pull/202>`__,
`#211 <https://github.com/nengo/nengo-loihi/issues/211>`__)
- It is now possible to make connections and probes with object slices
(e.g., ``nengo.Probe(my_ensemble[0])``).
(`#202 <https://github.com/nengo/nengo-loihi/pull/202>`__,
`#205 <https://github.com/nengo/nengo-loihi/issues/205>`__,
`#206 <https://github.com/nengo/nengo-loihi/issues/206>`__)
- We no longer disable the Nengo decoder cache for all models.
(`#202 <https://github.com/nengo/nengo-loihi/pull/202>`__,
`#207 <https://github.com/nengo/nengo-loihi/issues/207>`__)

0.6.0 (February 22, 2019)
=========================
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/adaptive_motor_control.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
" # Create node that calculates the OSC signal\n",
" model.osc_node = nengo.Node(\n",
" output=lambda t, x: ctrlr.generate(\n",
" q=x[:2], dq=x[2:4], target_pos=np.hstack([x[4:6], 0])),\n",
" q=x[:2], dq=x[2:4], target=np.hstack([x[4:6], np.zeros(4)])),\n",
" size_in=6, size_out=2)\n",
"\n",
" # Create node that runs the arm simulation and gets feedback\n",
Expand Down
52 changes: 49 additions & 3 deletions nengo_loihi/builder/builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from collections import defaultdict, OrderedDict
import logging

from nengo import Network
from nengo import Ensemble, Network, Node, Probe
from nengo.builder import Model as NengoModel
from nengo.builder.builder import Builder as NengoBuilder
from nengo.builder.network import build_network
from nengo.cache import NoDecoderCache
Expand Down Expand Up @@ -106,10 +107,27 @@ def __init__(self, dt=0.001, label=None, builder=None):
self.build_callback = None
self.decoder_cache = NoDecoderCache()

# TODO: these models may not look/behave exactly the same as
# standard nengo models, because they don't have a toplevel network
# built into them or configs set
self.host_pre = NengoModel(
dt=float(dt),
label="%s:host_pre, dt=%f" % (label, dt),
decoder_cache=NoDecoderCache(),
)
self.host = NengoModel(
dt=float(dt),
label="%s:host, dt=%f" % (label, dt),
decoder_cache=NoDecoderCache(),
)

# Objects created by the model for simulation on Loihi
self.inputs = OrderedDict()
self.blocks = OrderedDict()

# Will be filled in by the simulator __init__
self.split = None

# Will be filled in by the network builder
self.toplevel = None
self.config = None
Expand Down Expand Up @@ -145,8 +163,11 @@ def __init__(self, dt=0.001, label=None, builder=None):
# magnitude/weight resolution)
self.pes_wgt_exp = 4

# Will be provided by Simulator
# Used to track interactions between host models
self.chip2host_params = {}
self.chip2host_receivers = OrderedDict()
self.host2chip_senders = OrderedDict()
self.needs_sender = {}

def __getstate__(self):
raise NotImplementedError("Can't pickle nengo_loihi.builder.Model")
Expand All @@ -168,14 +189,39 @@ def add_block(self, block):
self.blocks[block] = len(self.blocks)

def build(self, obj, *args, **kwargs):
built = self.builder.build(self, obj, *args, **kwargs)
# Don't build the objects marked as "to_remove" by PassthroughSplit
if 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]

built = model.builder.build(model, obj, *args, **kwargs)
if self.build_callback is not None:
self.build_callback(obj)
return built

def has_built(self, obj):
return obj in self.params

def host_model(self, obj):
"""Returns the Model corresponding to where obj should be built."""
if self.split.is_precomputable(obj):
return self.host_pre
else:
return self.host


class Builder(NengoBuilder):
"""Fills in the Loihi Model object based on the Nengo Network.
Expand Down
Loading