def test_op_constant(dtype, diff, sess): ops = (SimNeurons(LIF(tau_rc=1), Signal(np.zeros(10)), None), SimNeurons(LIF(tau_rc=2 if diff else 1), Signal(np.zeros(10)), None)) signals = SignalDict(tf.float32, 1) const = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype) const1 = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype, ndims=1) const3 = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype, ndims=3) assert const.dtype.base_dtype == dtype sess.run(tf.variables_initializer(tf.get_collection("constants")), feed_dict=signals.constant_phs) x, x1, x3 = sess.run([const, const1, const3]) if diff: assert np.array_equal(x, [[1]] * 10 + [[2]] * 10) assert np.array_equal(x[:, 0], x1) assert np.array_equal(x, x3[..., 0]) else: assert np.array_equal(x, 1.0) assert np.array_equal(x, x1) assert np.array_equal(x, x3)
def test_op_constant(dtype, diff): ops = ( SimNeurons(LIF(tau_rc=1), Signal(np.zeros(10)), None), SimNeurons(LIF(tau_rc=2 if diff else 1), Signal(np.zeros(10)), None), ) signals = SignalDict(tf.float32, 1) const = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype ) const1 = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype, shape=(-1,), ) const3 = signals.op_constant( [op.neurons for op in ops], [op.J.shape[0] for op in ops], "tau_rc", dtype, shape=(1, -1, 1), ) assert const.dtype.base_dtype == dtype if diff: assert np.array_equal(const, [[1.0] * 10 + [2.0] * 10]) assert np.array_equal(const[0], const1) assert np.array_equal(const, const3[..., 0]) else: assert np.array_equal(const, 1.0) assert np.array_equal(const, const1) assert np.array_equal(const, const3)
def test_operators(): sig = Signal(np.array([0.0]), name="sig") assert fnmatch(repr(TimeUpdate(sig, sig)), "<TimeUpdate at 0x*>") assert fnmatch(repr(TimeUpdate(sig, sig, tag="tag")), "<TimeUpdate 'tag' at 0x*>") assert fnmatch(repr(Reset(sig)), "<Reset at 0x*>") assert fnmatch(repr(Reset(sig, tag="tag")), "<Reset 'tag' at 0x*>") assert fnmatch(repr(Copy(sig, sig)), "<Copy at 0x*>") assert fnmatch(repr(Copy(sig, sig, tag="tag")), "<Copy 'tag' at 0x*>") assert fnmatch(repr(ElementwiseInc(sig, sig, sig)), "<ElementwiseInc at 0x*>") assert fnmatch(repr(ElementwiseInc(sig, sig, sig, tag="tag")), "<ElementwiseInc 'tag' at 0x*>") assert fnmatch(repr(DotInc(sig, sig, sig)), "<DotInc at 0x*>") assert fnmatch(repr(DotInc(sig, sig, sig, tag="tag")), "<DotInc 'tag' at 0x*>") assert fnmatch(repr(SimPyFunc(sig, lambda x: 0.0, True, sig)), "<SimPyFunc at 0x*>") assert fnmatch( repr(SimPyFunc(sig, lambda x: 0.0, True, sig, tag="tag")), "<SimPyFunc 'tag' at 0x*>", ) assert fnmatch(repr(SimPES(sig, sig, sig, 0.1)), "<SimPES at 0x*>") assert fnmatch(repr(SimPES(sig, sig, sig, 0.1, tag="tag")), "<SimPES 'tag' at 0x*>") assert fnmatch(repr(SimBCM(sig, sig, sig, sig, 0.1)), "<SimBCM at 0x*>") assert fnmatch(repr(SimBCM(sig, sig, sig, sig, 0.1, tag="tag")), "<SimBCM 'tag' at 0x*>") assert fnmatch(repr(SimOja(sig, sig, sig, sig, 0.1, 1.0)), "<SimOja at 0x*>") assert fnmatch(repr(SimOja(sig, sig, sig, sig, 0.1, 1.0, tag="tag")), "<SimOja 'tag' at 0x*>") assert fnmatch(repr(SimVoja(sig, sig, sig, sig, 1.0, sig, 1.0)), "<SimVoja at 0x*>") assert fnmatch( repr(SimVoja(sig, sig, sig, sig, 0.1, sig, 1.0, tag="tag")), "<SimVoja 'tag' at 0x*>", ) assert fnmatch(repr(SimRLS(sig, sig, sig, sig)), "<SimRLS at 0x*>") assert fnmatch( repr(SimRLS(sig, sig, sig, sig, tag="tag")), "<SimRLS 'tag' at 0x*>", ) assert fnmatch(repr(SimNeurons(LIF(), sig, {"sig": sig})), "<SimNeurons at 0x*>") assert fnmatch( repr(SimNeurons(LIF(), sig, {"sig": sig}, tag="tag")), "<SimNeurons 'tag' at 0x*>", ) assert fnmatch(repr(SimProcess(WhiteNoise(), sig, sig, sig)), "<SimProcess at 0x*>") assert fnmatch( repr(SimProcess(WhiteNoise(), sig, sig, sig, tag="tag")), "<SimProcess 'tag' at 0x*>", )
def test_simneuronsmerger_warning(rng): nt = nengo.PoissonSpiking(nengo.Tanh()) op1 = SimNeurons( nt, J=Signal(shape=(1,)), output=Signal(shape=(1,)), state={"rng": rng} ) op2 = SimNeurons( nt, J=Signal(shape=(1,)), output=Signal(shape=(1,)), state={"rng": rng} ) assert SimNeuronsMerger.is_mergeable(op1, op2) with pytest.warns(UserWarning, match="Extra state has been modified"): SimNeuronsMerger.merge([op1, op2])
def build_LIF(model, LIF, neurons): model.sig[neurons]['voltage'] = Signal(np.zeros(neurons.size_in), name="%s.voltage" % neurons) model.sig[neurons]['refractory_time'] = Signal(np.zeros(neurons.size_in), name="%s.refractory_time" % neurons) model.sig[neurons]['pre_filtered'] = Signal(np.zeros(neurons.size_in), name="%s.pre_filtered" % neurons) model.sig[neurons]['post_filtered'] = Signal(np.zeros(neurons.size_in), name="%s.post_filtered" % neurons) model.sig[neurons]['inhib'] = Signal(np.zeros(neurons.size_in), name="%s.inhib" % neurons) model.sig[neurons]['adaptation'] = Signal(np.zeros(neurons.size_in), name="%s.adaptation" % neurons) # set neuron output for a given input model.add_op( SimNeurons(neurons=LIF, J=model.sig[neurons]['in'], output=model.sig[neurons]['out'], state={ "voltage": model.sig[neurons]['voltage'], "refractory_time": model.sig[neurons]['refractory_time'], "adaptation": model.sig[neurons]['adaptation'], "inhib": model.sig[neurons]['inhib'] }))
def test_order_signals_neuron_states(): # test with neuron states (should be treated as reads) inputs = [dummies.Signal(label=str(i)) for i in range(10)] plan = [ tuple(SimNeurons(None, inputs[0], inputs[1], states=[x]) for x in inputs[2::2]), tuple(SimNeurons(None, inputs[0], inputs[1], states=[x]) for x in inputs[3::2])] sigs, new_plan = order_signals(plan) assert contiguous(inputs[2::2], sigs) assert contiguous(inputs[3::2], sigs) # note: block=0 is just a single signal, so it's always "ordered" assert ordered(new_plan[0], sigs, block=1) assert ordered(new_plan[1], sigs, block=1)
def build_adlnlognormal(model, adLNlognormal, neurons): model.sig[neurons]['mu_in'] = Signal(np.zeros(neurons.size_in), name="%s.mu_in" % neurons) model.sig[neurons]['sq_in'] = Signal(np.zeros(neurons.size_in), name="%s.sq_in" % neurons) model.add_op( SimNeurons( neurons=adLNlognormal, J=model.sig[neurons]['in'], output=model.sig[neurons]['out'], states=[model.sig[neurons]['mu_in'], model.sig[neurons]['sq_in']]))
def build_if(model, neuron_type, neurons): """Builds a `.IF` object into a model. """ model.sig[neurons]['voltage'] = Signal( np.zeros(neurons.size_in), name="%s.voltage" % neurons) model.sig[neurons]['refractory_time'] = Signal( np.zeros(neurons.size_in), name="%s.refractory_time" % neurons) model.add_op(SimNeurons( neurons=neuron_type, J=model.sig[neurons]['in'], output=model.sig[neurons]['out'], states=[model.sig[neurons]['voltage'], model.sig[neurons]['refractory_time']]))
def merge(ops): def gather(ops, key): return [getattr(o, key) for o in ops] J, J_sigr = SigMerger.merge(gather(ops, 'J')) output, out_sigr = SigMerger.merge(gather(ops, 'output')) states = [] states_sigr = {} for signals in zip(*gather(ops, 'states')): st, st_sigr = SigMerger.merge(signals) states.append(st) states_sigr.update(st_sigr) return (SimNeurons(ops[0].neurons, J, output, states), Merger.merge_dicts(J_sigr, out_sigr, states_sigr))
def merge(ops): J, J_sigr = SigMerger.merge([op.J for op in ops]) state = {} state_sigr = {} for key in ops[0].state_sigs: st, st_sigr = SigMerger.merge( [op.sets[op.state_sigs[key]] for op in ops]) state[key] = st state_sigr.update(st_sigr) state.update(ops[0].state_extra) if any(len(op.state_extra) > 0 for op in ops[1:]): warnings.warn( "Extra state has been modified when merging two or more SimNeurons " "ops associated with %r neuron types. If this causes issues, turn off " "the optimizer." % (type(ops[0].neurons).__name__)) return ( SimNeurons(ops[0].neurons, J, state=state), Merger.merge_dicts(J_sigr, state_sigr), )
def build_stpLIF(model, stplif, neurons): model.sig[neurons]['voltage'] = Signal(np.zeros(neurons.size_in), name="%s.voltage" % neurons) model.sig[neurons]['refractory_time'] = Signal(np.zeros(neurons.size_in), name="%s.refractory_time" % neurons) model.sig[neurons]['resources'] = Signal(np.ones(neurons.size_in), name="%s.resources" % neurons) model.sig[neurons]['calcium'] = Signal(np.full(neurons.size_in, 0.2), name="%s.calcium" % neurons) model.add_op( SimNeurons(neurons=stplif, J=model.sig[neurons]['in'], output=model.sig[neurons]['out'], states=[ model.sig[neurons]['voltage'], model.sig[neurons]['refractory_time'], model.sig[neurons]['resources'], model.sig[neurons]['calcium'] ]))
def test_mergeable(): # anything is mergeable with an empty list assert mergeable(None, []) # ops with different numbers of sets/incs/reads/updates are not mergeable assert not mergeable(dummies.Op(sets=[dummies.Signal()]), [dummies.Op()]) assert not mergeable(dummies.Op(incs=[dummies.Signal()]), [dummies.Op()]) assert not mergeable(dummies.Op(reads=[dummies.Signal()]), [dummies.Op()]) assert not mergeable(dummies.Op(updates=[dummies.Signal()]), [dummies.Op()]) assert mergeable(dummies.Op(sets=[dummies.Signal()]), [dummies.Op(sets=[dummies.Signal()])]) # check matching dtypes assert not mergeable(dummies.Op(sets=[dummies.Signal(dtype=np.float32)]), [dummies.Op(sets=[dummies.Signal(dtype=np.float64)])]) # shape mismatch assert not mergeable(dummies.Op(sets=[dummies.Signal(shape=(1, 2))]), [dummies.Op(sets=[dummies.Signal(shape=(1, 3))])]) # display shape mismatch assert not mergeable( dummies.Op(sets=[dummies.Signal(base_shape=(2, 2), shape=(4, 1))]), [dummies.Op(sets=[dummies.Signal(base_shape=(2, 2), shape=(1, 4))])]) # first dimension mismatch assert mergeable(dummies.Op(sets=[dummies.Signal(shape=(3, 2))]), [dummies.Op(sets=[dummies.Signal(shape=(4, 2))])]) # Copy (inc must match) assert mergeable(Copy(dummies.Signal(), dummies.Signal(), inc=True), [Copy(dummies.Signal(), dummies.Signal(), inc=True)]) assert not mergeable(Copy(dummies.Signal(), dummies.Signal(), inc=True), [Copy(dummies.Signal(), dummies.Signal(), inc=False)]) # elementwise (first dimension must match) assert mergeable( ElementwiseInc(dummies.Signal(), dummies.Signal(), dummies.Signal()), [ElementwiseInc(dummies.Signal(), dummies.Signal(), dummies.Signal())]) assert mergeable( ElementwiseInc(dummies.Signal(shape=(1,)), dummies.Signal(), dummies.Signal()), [ElementwiseInc(dummies.Signal(shape=()), dummies.Signal(), dummies.Signal())]) assert not mergeable( ElementwiseInc(dummies.Signal(shape=(3,)), dummies.Signal(), dummies.Signal()), [ElementwiseInc(dummies.Signal(shape=(2,)), dummies.Signal(), dummies.Signal())]) # simpyfunc (t input must match) time = dummies.Signal() assert mergeable(SimPyFunc(None, None, time, None), [SimPyFunc(None, None, time, None)]) assert mergeable(SimPyFunc(None, None, None, dummies.Signal()), [SimPyFunc(None, None, None, dummies.Signal())]) assert not mergeable(SimPyFunc(None, None, dummies.Signal(), None), [SimPyFunc(None, None, None, dummies.Signal())]) # simneurons # check matching TF_NEURON_IMPL assert mergeable(SimNeurons(LIF(), dummies.Signal(), dummies.Signal()), [SimNeurons(LIF(), dummies.Signal(), dummies.Signal())]) assert not mergeable(SimNeurons(LIF(), dummies.Signal(), dummies.Signal()), [SimNeurons(LIFRate(), dummies.Signal(), dummies.Signal())]) # check custom with non-custom implementation assert not mergeable(SimNeurons(LIF(), dummies.Signal(), dummies.Signal()), [SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal())]) # check non-custom matching assert not mergeable( SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal()), [SimNeurons(AdaptiveLIF(), dummies.Signal(), dummies.Signal())]) assert not mergeable( SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(dtype=np.float32)]), [SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(dtype=np.int32)])]) assert mergeable( SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(shape=(3,))]), [SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(shape=(2,))])]) assert not mergeable( SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(shape=(2, 1))]), [SimNeurons(Izhikevich(), dummies.Signal(), dummies.Signal(), states=[dummies.Signal(shape=(2, 2))])]) # simprocess # mode must match assert not mergeable( SimProcess(Lowpass(0), None, dummies.Signal(), dummies.Signal(), mode="inc"), [SimProcess(Lowpass(0), None, dummies.Signal(), dummies.Signal(), mode="set")]) # check that lowpass match assert mergeable(SimProcess(Lowpass(0), None, None, dummies.Signal()), [SimProcess(Lowpass(0), None, None, dummies.Signal())]) # check that lowpass and linear don't match assert not mergeable(SimProcess(Lowpass(0), None, None, dummies.Signal()), [SimProcess(Alpha(0), None, None, dummies.Signal())]) # check that two linear do match assert mergeable( SimProcess(Alpha(0.1), dummies.Signal(), None, dummies.Signal()), [SimProcess(LinearFilter([1], [1, 1, 1]), dummies.Signal(), None, dummies.Signal())]) # check custom and non-custom don't match assert not mergeable(SimProcess(Triangle(0), None, None, dummies.Signal()), [SimProcess(Alpha(0), None, None, dummies.Signal())]) # check non-custom matching assert mergeable(SimProcess(Triangle(0), None, None, dummies.Signal()), [SimProcess(Triangle(0), None, None, dummies.Signal())]) # simtensornode a = SimTensorNode(None, dummies.Signal(), None, dummies.Signal()) assert not mergeable(a, [a]) # learning rules a = SimBCM(dummies.Signal((4,)), dummies.Signal(), dummies.Signal(), dummies.Signal(), dummies.Signal()) b = SimBCM(dummies.Signal((5,)), dummies.Signal(), dummies.Signal(), dummies.Signal(), dummies.Signal()) assert not mergeable(a, [b])
def test_mergeable(): # anything is mergeable with an empty list assert mergeable(None, []) # ops with different numbers of sets/incs/reads/updates are not mergeable assert not mergeable(DummyOp(sets=[DummySignal()]), [DummyOp()]) assert not mergeable(DummyOp(incs=[DummySignal()]), [DummyOp()]) assert not mergeable(DummyOp(reads=[DummySignal()]), [DummyOp()]) assert not mergeable(DummyOp(updates=[DummySignal()]), [DummyOp()]) assert mergeable(DummyOp(sets=[DummySignal()]), [DummyOp(sets=[DummySignal()])]) # check matching dtypes assert not mergeable(DummyOp(sets=[DummySignal(dtype=np.float32)]), [DummyOp(sets=[DummySignal(dtype=np.float64)])]) # shape mismatch assert not mergeable(DummyOp(sets=[DummySignal(shape=(1, 2))]), [DummyOp(sets=[DummySignal(shape=(1, 3))])]) # display shape mismatch assert not mergeable( DummyOp(sets=[DummySignal(base_shape=(2, 2), shape=(4, 1))]), [DummyOp(sets=[DummySignal(base_shape=(2, 2), shape=(1, 4))])]) # first dimension mismatch assert mergeable(DummyOp(sets=[DummySignal(shape=(3, 2))]), [DummyOp(sets=[DummySignal(shape=(4, 2))])]) # Copy (inc must match) assert mergeable(Copy(DummySignal(), DummySignal(), inc=True), [Copy(DummySignal(), DummySignal(), inc=True)]) assert not mergeable(Copy(DummySignal(), DummySignal(), inc=True), [Copy(DummySignal(), DummySignal(), inc=False)]) # elementwise (first dimension must match) assert mergeable( ElementwiseInc(DummySignal(), DummySignal(), DummySignal()), [ElementwiseInc(DummySignal(), DummySignal(), DummySignal())]) assert mergeable( ElementwiseInc(DummySignal(shape=(1,)), DummySignal(), DummySignal()), [ElementwiseInc(DummySignal(shape=()), DummySignal(), DummySignal())]) assert not mergeable( ElementwiseInc(DummySignal(shape=(3,)), DummySignal(), DummySignal()), [ElementwiseInc(DummySignal(shape=(2,)), DummySignal(), DummySignal())]) # simpyfunc (t input must match) time = DummySignal() assert mergeable(SimPyFunc(None, None, time, None), [SimPyFunc(None, None, time, None)]) assert mergeable(SimPyFunc(None, None, None, DummySignal()), [SimPyFunc(None, None, None, DummySignal())]) assert not mergeable(SimPyFunc(None, None, DummySignal(), None), [SimPyFunc(None, None, None, DummySignal())]) # simneurons # check matching TF_NEURON_IMPL assert mergeable(SimNeurons(LIF(), DummySignal(), DummySignal()), [SimNeurons(LIF(), DummySignal(), DummySignal())]) assert not mergeable(SimNeurons(LIF(), DummySignal(), DummySignal()), [SimNeurons(LIFRate(), DummySignal(), DummySignal())]) # check custom with non-custom implementation assert not mergeable(SimNeurons(LIF(), DummySignal(), DummySignal()), [SimNeurons(Izhikevich(), DummySignal(), DummySignal())]) # check non-custom matching assert not mergeable( SimNeurons(Izhikevich(), DummySignal(), DummySignal()), [SimNeurons(AdaptiveLIF(), DummySignal(), DummySignal())]) assert not mergeable( SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(dtype=np.float32)]), [SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(dtype=np.int32)])]) assert mergeable( SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(shape=(3,))]), [SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(shape=(2,))])]) assert not mergeable( SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(shape=(2, 1))]), [SimNeurons(Izhikevich(), DummySignal(), DummySignal(), states=[DummySignal(shape=(2, 2))])]) # simprocess # mode must match assert not mergeable( SimProcess(Lowpass(0), None, None, DummySignal(), mode="inc"), [SimProcess(Lowpass(0), None, None, DummySignal(), mode="set")]) # check matching TF_PROCESS_IMPL # note: we only have one item in TF_PROCESS_IMPL at the moment, so no # such thing as a mismatch assert mergeable(SimProcess(Lowpass(0), None, None, DummySignal()), [SimProcess(Lowpass(0), None, None, DummySignal())]) # check custom vs non custom assert not mergeable(SimProcess(Lowpass(0), None, None, DummySignal()), [SimProcess(Alpha(0), None, None, DummySignal())]) # check non-custom matching assert mergeable(SimProcess(Triangle(0), None, None, DummySignal()), [SimProcess(Alpha(0), None, None, DummySignal())]) # simtensornode a = SimTensorNode(None, DummySignal(), None, DummySignal()) assert not mergeable(a, [a]) # learning rules a = SimBCM(DummySignal((4,)), DummySignal(), DummySignal(), DummySignal(), DummySignal()) b = SimBCM(DummySignal((5,)), DummySignal(), DummySignal(), DummySignal(), DummySignal()) assert not mergeable(a, [b])
def build_unit(model, unit, neurons): """Adds all unit neuron types to the nengo reference backend.""" model.add_op(SimNeurons(neurons=unit, J=model.sig[neurons]['in'], output=model.sig[neurons]['out']))