Пример #1
0
    def test_min_spl1_should_allow_external_input_on_same_chip(self):
        """
        Even when the rightmost neuron block / DNC merger is not reserved for external input, it
        should be possible to place external input on the same chip.
        """
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)
        self.marocco.merger_routing.strategy(
            self.marocco.merger_routing.minimize_number_of_sending_repeaters)
        # Do not reserve rightmost neuron block / DNC merger for external input.
        self.marocco.neuron_placement.restrict_rightmost_neuron_blocks(False)

        hicann = C.HICANNOnWafer(C.Enum(123))
        pops = []
        # All but the first neuron block are occupied.
        for nb in range(1, C.NeuronBlockOnHICANN.end):
            pop = pynn.Population(1, pynn.IF_cond_exp, {})
            self.marocco.manual_placement.on_neuron_block(
                pop, C.NeuronBlockOnWafer(C.NeuronBlockOnHICANN(nb), hicann))
            pops.append(pop)
        in_pop = pynn.Population(1, pynn.SpikeSourceArray, {})
        self.marocco.manual_placement.on_hicann(in_pop, hicann)

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        for pop in pops:
            nrn = pop[0]
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            self.assertEqual(neuron_size, logical_neuron.size())
            for denmem in logical_neuron:
                self.assertEqual(hicann, denmem.toHICANNOnWafer())
            address = placement_item.address()

            # All used neuron blocks should be connected to a single DNC merger.
            dnc = C.DNCMergerOnHICANN(3)
            self.assertEqual(hicann, address.toHICANNOnWafer())
            self.assertEqual(dnc, address.toDNCMergerOnHICANN())
            self.assertEqual(C.DNCMergerOnWafer(dnc, hicann),
                             address.toDNCMergerOnWafer())

        nrn = in_pop[0]
        placement_item, = results.placement.find(nrn)
        logical_neuron = placement_item.logical_neuron()
        self.assertTrue(logical_neuron.is_external())
        address = placement_item.address()

        # External input should be on the leftmost DNC merger, since all other
        # mergers do not have direct access to a background generator.
        dnc = C.DNCMergerOnHICANN(0)
        self.assertEqual(hicann, address.toHICANNOnWafer())
        self.assertEqual(dnc, address.toDNCMergerOnHICANN())
        self.assertEqual(C.DNCMergerOnWafer(dnc, hicann),
                         address.toDNCMergerOnWafer())
Пример #2
0
    def test_min_spl1_is_nongreedy_when_pops_are_placed_to_nbs(self, nbs):
        """
        See above.  Instead of a single population placed to the HICANN, populations are placed to
        specific neuron blocks.
        """
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)
        self.marocco.merger_routing.strategy(
            self.marocco.merger_routing.minimize_number_of_sending_repeaters)
        self.marocco.neuron_placement.restrict_rightmost_neuron_blocks(True)

        hicann = C.HICANNOnWafer(C.Enum(123))
        pops = []
        for nb in nbs:
            pop = pynn.Population(1, pynn.IF_cond_exp, {})
            self.marocco.manual_placement.on_neuron_block(
                pop, C.NeuronBlockOnWafer(C.NeuronBlockOnHICANN(nb), hicann))
            pops.append(pop)
        in_pop = pynn.Population(1, pynn.SpikeSourceArray, {})
        self.marocco.manual_placement.on_hicann(in_pop, hicann)

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        for pop in pops:
            nrn = pop[0]
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            self.assertEqual(neuron_size, logical_neuron.size())
            for denmem in logical_neuron:
                self.assertEqual(hicann, denmem.toHICANNOnWafer())
            address = placement_item.address()

            # All used neuron blocks should still be connected to a single DNC merger.
            dnc = C.DNCMergerOnHICANN(3)
            self.assertEqual(hicann, address.toHICANNOnWafer())
            self.assertEqual(dnc, address.toDNCMergerOnHICANN())
            self.assertEqual(C.DNCMergerOnWafer(dnc, hicann),
                             address.toDNCMergerOnWafer())

        nrn = in_pop[0]
        placement_item, = results.placement.find(nrn)
        logical_neuron = placement_item.logical_neuron()
        self.assertTrue(logical_neuron.is_external())
        address = placement_item.address()

        # External input should be on the rightmost DNC merger since that is tried first.
        dnc = C.DNCMergerOnHICANN(7)
        self.assertEqual(hicann, address.toHICANNOnWafer())
        self.assertEqual(dnc, address.toDNCMergerOnHICANN())
        self.assertEqual(C.DNCMergerOnWafer(dnc, hicann),
                         address.toDNCMergerOnWafer())
Пример #3
0
    def test_BGToNeuronMembrane(self):
        """Try to send periodic events from a background generator to a neuron.
        Please note that this test relies on the default config values in most objects
        and only changes those necessary to run the test."""

        weight = 15
        period = 700 * 2
        event = HICANN.L1Address(0)
        offevent = HICANN.L1Address(55)

        trace_length = 19500

        exc = True
        inh = False
        E_syn = (570, 570)

        firing = False
        firingevent = HICANN.L1Address(42)

        # FIXME: Differs from HICANN to HICANN, this needs connection database
        analog = Coordinate.AnalogOnHICANN(1)
        adc_channel = 7

        neuron = Coordinate.NeuronOnHICANN(Enum(15))
        vline = Coordinate.VLineOnHICANN(28)  # or 60, 92, 124
        driver = Coordinate.SynapseDriverOnHICANN(Y(111), left)
        synapse_row = Coordinate.SynapseRowOnHICANN(driver, top)

        ##############################
        #  set floating gate values  #
        ##############################

        fgcfg = HICANN.FGConfig()
        fgctrl = HICANN.FGControl()

        # Set same reverse potential for both synaptic inputs (for all neurons)
        for ii in range(512):
            nrn = Coordinate.NeuronOnHICANN(Enum(ii))
            fgctrl.setNeuron(nrn, HICANN.neuron_parameter.E_synx, E_syn[0])
            fgctrl.setNeuron(nrn, HICANN.neuron_parameter.E_syni, E_syn[1])
            fgctrl.setNeuron(nrn, HICANN.neuron_parameter.I_bexp, 0)

        for block in Coordinate.iter_all(Coordinate.FGBlockOnHICANN):
            HICANN.set_fg_config(self.h, block, fgcfg)
        HICANN.set_fg_values(self.h, fgctrl)

        ##############################
        #  set global neuron config  #
        ##############################

        nconf = HICANN.NeuronConfig()
        nconf.bigcap[int(top)] = True
        nconf.bigcap[int(bottom)] = True
        HICANN.set_neuron_config(self.h, nconf)

        #################
        #  set mergers  #
        #################

        dnc = HICANN.DNCMergerLine()
        for i in range(8):
            mer = Coordinate.DNCMergerOnHICANN(i)
            dnc[mer].slow = True
            dnc[mer].config = HICANN.Merger.RIGHT_ONLY

        # Tree defaults to one on one passthrough (forward downwards)
        tree = HICANN.MergerTree()

        HICANN.set_dnc_merger(self.h, dnc)
        HICANN.set_merger_tree(self.h, tree)

        ##########################
        #  background generator  #
        ##########################

        # We use one background generator to provide events
        gens = HICANN.BackgroundGeneratorArray()
        g = gens[7]
        g.enable(True)
        g.random(False)
        g.period(period)
        g.address(event)
        HICANN.set_background_generator(self.h, gens)

        # Forward its output to this HICANN
        srepeater = Coordinate.OutputBufferOnHICANN(7).repeater()

        sr = HICANN.HorizontalRepeater()
        sr.setOutput(right)

        HICANN.set_repeater(self.h, srepeater.horizontal(), sr)

        ###############################################
        #  connect via Crossbars and SynapseSwitches  #
        ###############################################

        hline = srepeater.toHLineOnHICANN()

        cb = HICANN.Crossbar()
        cb.set(vline, hline, True)

        HICANN.set_crossbar_switch_row(
            self.h, hline, vline.toSideHorizontal(),
            cb.get_row(hline, vline.toSideHorizontal()))

        # Connect VLine to synapse driver
        sw = HICANN.SynapseSwitch()
        sw.set(vline, driver.toHLineOnHICANN(), True)

        HICANN.set_syndriver_switch_row(
            self.h, driver.toSynapseSwitchRowOnHICANN(),
            sw.get_row(driver.toSynapseSwitchRowOnHICANN()))

        ########################
        #  set synapse driver  #
        ########################

        drv = HICANN.SynapseDriver()
        drv.set_l1()
        drv[top].set_syn_in(left, exc)
        drv[top].set_syn_in(right, inh)
        drv[bottom].set_syn_in(left, exc)
        drv[bottom].set_syn_in(right, inh)

        HICANN.set_synapse_driver(self.h, driver, drv)

        decoders = HICANN.DecoderDoubleRow()
        weights = HICANN.WeightRow()

        # Reset decoders and weights to 'off' state
        for ii in range(2):
            for jj in range(256):
                decoders[ii][jj] = offevent.getSynapseDecoderMask()

        for ii in range(256):
            weights[ii] = 0

        # Only enable decoders/weights for background generator and neuron
        decoders[0][int(neuron.x())] = event.getSynapseDecoderMask()
        weights[int(neuron.x())] = weight

        HICANN.set_decoder_double_row(self.h, driver, decoders)
        HICANN.set_weights_row(self.h, synapse_row, weights)

        ###################
        #  get ADC trace  #
        ###################

        self.set_denmem_quads(neuron,
                              address=firingevent,
                              activate_firing=firing,
                              enable_aout=True)
        self.set_analog(analog, neuron)
        trace, v, t = self.get_trace(adc_channel, trace_length)

        if False:
            import pylab
            fig, ax = pylab.subplots()
            ax.plot(t, v)
            pylab.show()

        ## Case 1: Sometimes the membrane seems 'stuck' at 1.2V
        self.assertNotAlmostEqual(v.mean(), 1.2, places=1)
        self.assertGreater(v.std(), 0.01)