-
Notifications
You must be signed in to change notification settings - Fork 175
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
Core speedups #1629
Core speedups #1629
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saw a few style nitpicks while scanning this PR, looks great though!
762a9d4
to
e066052
Compare
Pushed some minor fixups:
Then I added two new changes that I discovered while looking into this
For those curious, I also checked how much impact each of these changes had (using the examples as a benchmark). The vast majority of the improvement comes from moving the BSR initialization outside the step function:
|
Change ndarray.clip to np.clip or, where possible, np.maximum Change all uses of np.clip to np.umath.clip in numpy>=1.17
e066052
to
ea03342
Compare
Thanks for the review and changes. Those benchmarking results are interesting because I saw the opposite on my particular test problems, although both sped up. Really nice independent verification! I went back though again and have one recommended change. @drasmuss, I'll let you do the modify and force push how you'd like. Plasticity with BsrDotInc: def make_step(self, signals, dt, rng):
X = signals[self.X]
A = signals[self.A]
Y = signals[self.Y]
if A.flags.writeable:
def step_dotinc():
mat_A = self.bsr_matrix((A, self.indices, self.indptr))
inc = mat_A.dot(X)
if self.reshape:
inc = inc.reshape(Y.shape)
Y[...] += inc
else:
mat_A = self.bsr_matrix((A, self.indices, self.indptr))
def step_dotinc():
inc = mat_A.dot(X)
if self.reshape:
inc = inc.reshape(Y.shape)
Y[...] += inc
return step_dotinc Stressing
|
Do you have a test case that shows the behaviour change (I'm guessing it would involve using online learning rules with a matrix that gets merged into a BsrDotInc?). It'd be good to add that as a unit test, since our existing tests didn't pick up that case. |
Changes implemented, but then more changes
Actually, I might have made the wrong conclusion, sorry. I don't have a test case, just hacked it with this # make a multi-ensemble network above
break_it = True # or False
sim = nengo.Simulator(network, optimize=True)
if break_it:
for op in sim.step_order:
if type(op).__name__ == 'BsrDotInc':
arr = sim.signals[op.A]
arr.setflags(write=1)
arr[...] = 0
with sim:
sim.run(1) What is supposed to happen is that it does in fact disconnect everything and behave differently when I don't use learning rules that much, so it would take some time. Do you think you could help write a realistic test case along the lines of datas = [None] * 2
for i, learning in enumerate([True, False]):
if learning:
network = give_network_with_learning()
else:
network = give_network_without_learning()
sim = nengo.Simulator(network, optimize=True)
with sim:
sim.run(1)
datas[i] = sim.data[some_probe]
assert not allclose(datas[0], datas[1]) |
Uses builtin math instead of np array math
ea03342
to
eb98cc8
Compare
I double checked and this is covered by our existing tests (i.e. we have tests with a BsrDotInc with a writeable A). So I think this is good to go. |
Merged, thanks again for the PR! |
Motivation and context:
General performance improvements to Nengo core simulations. Forum topic
SignalDict
missesnp.clip
from v1.17LinearFilter
step for one-dimensional ensemblestest_examples.py
How has this been tested?
How long should this take to review?
Changes are simple, but they are fairly deep within core. More extensive testing should be done to
Where should a reviewer start?
%%prun
in Jupyter.Types of changes:
OneXOneDim
: acts as drop-in for existing functionalityChecklist:
Still to do:
None that I'm aware of