From 8d1dfb4aefadfe9636dab89bdccbc6ed15c7452b Mon Sep 17 00:00:00 2001 From: Eric Hunsberger Date: Mon, 11 Nov 2019 10:39:24 -0500 Subject: [PATCH] Use proper queue in HostReceiveNode for speed This makes things faster by not requiring us to increment a counter through the node, and also makes sure we get all the data. We also fix the time in this node to use zero-based timesteps rather than one-based timesteps (to conform with core Nengo). --- nengo_loihi/builder/inputs.py | 17 +++++++++-------- nengo_loihi/emulator/interface.py | 2 +- nengo_loihi/hardware/interface.py | 2 +- nengo_loihi/hardware/snips/nengo_io.c.template | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/nengo_loihi/builder/inputs.py b/nengo_loihi/builder/inputs.py index 32123f92d..b9af4283c 100644 --- a/nengo_loihi/builder/inputs.py +++ b/nengo_loihi/builder/inputs.py @@ -1,3 +1,5 @@ +import collections + from nengo import Node from nengo.exceptions import SimulationError from nengo.params import Default @@ -24,8 +26,7 @@ class HostReceiveNode(Node): """For receiving chip->host messages""" def __init__(self, dimensions, label=Default, check_output=False): - self.queue = [(0, np.zeros(dimensions))] - self.queue_index = 0 + self.queue = collections.deque() super(HostReceiveNode, self).__init__( self.update, size_in=0, size_out=dimensions, label=label ) @@ -33,12 +34,12 @@ def __init__(self, dimensions, label=Default, check_output=False): self.check_output = check_output def update(self, t): - while ( - len(self.queue) > self.queue_index + 1 - and self.queue[self.queue_index][0] < t - ): - self.queue_index += 1 - return self.queue[self.queue_index][1] + if t <= 0: + return np.zeros(self.size_out) + + t1, x = self.queue.popleft() + assert abs(t - t1) < 1e-8 + return x def receive(self, t, x): self.queue.append((t, x)) diff --git a/nengo_loihi/emulator/interface.py b/nengo_loihi/emulator/interface.py index 52b611e57..7acf0b74d 100644 --- a/nengo_loihi/emulator/interface.py +++ b/nengo_loihi/emulator/interface.py @@ -638,7 +638,7 @@ def send(self, probe, already_sent, receiver): if probe.weights is not None: x = np.dot(x, probe.weights) for j, xx in enumerate(x): - receiver.receive(self.dt * (already_sent + j + 2), xx) + receiver.receive(self.dt * (already_sent + j + 1), xx) return len(x) def update(self, t, compartment): diff --git a/nengo_loihi/hardware/interface.py b/nengo_loihi/hardware/interface.py index 1d43523cd..b8bc0dad8 100644 --- a/nengo_loihi/hardware/interface.py +++ b/nengo_loihi/hardware/interface.py @@ -202,7 +202,7 @@ def _chip2host_monitor(self, probes_receivers): for j in range(len(x)): receiver.receive( - self.model.dt * (self._chip2host_sent_steps + j + 2), x[j] + self.model.dt * (self._chip2host_sent_steps + j + 1), x[j] ) if increment is not None: diff --git a/nengo_loihi/hardware/snips/nengo_io.c.template b/nengo_loihi/hardware/snips/nengo_io.c.template index d2b332833..b5e6539fe 100644 --- a/nengo_loihi/hardware/snips/nengo_io.c.template +++ b/nengo_loihi/hardware/snips/nengo_io.c.template @@ -173,7 +173,7 @@ void nengo_io(runState *s) { } } - buffer[0] = s->{{ obfs.step }}; + buffer[0] = s->{{ obfs.step }} - 1; // zero-based time step {% for n_out, core, compartment, key in probes %} {% if key == 'u' %} buffer[{{ n_out }}] = core{{ core }}->{{ obfs.state }}[{{ compartment }}].U;