示例#1
0
    def test(self):

        wafer = 99999  # a wafer for which no redman data is availale
        hicann = 82
        neuron_number = 12

        marocco = PyMarocco()
        marocco.neuron_placement.default_neuron_size(4)
        marocco.backend = PyMarocco.Without
        marocco.default_wafer = C.Wafer(wafer)

        used_hicann = C.HICANNGlobal(C.HICANNOnWafer(Enum(hicann)),
                                     C.Wafer(wafer))

        used_hicann  # prevent pep8 warning of unused variable

        pynn.setup(marocco=marocco)

        pop = pynn.Population(1, pynn.IF_cond_exp)
        topleft = C.NeuronOnWafer(C.NeuronOnHICANN(X(neuron_number), Y(0)),
                                  C.HICANNOnWafer(Enum(hicann)))
        logical_neuron = LogicalNeuron.rectangular(topleft, size=4)
        marocco.manual_placement.on_neuron(pop, logical_neuron)

        with self.assertRaises(RuntimeError):
            pynn.run(0)
            pynn.end()
示例#2
0
    def test_popview_on_hicann(self, size):
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)
        hicann = C.HICANNOnWafer(Enum(122))
        hicann_1 = C.HICANNOnWafer(Enum(123))
        hicann_2 = C.HICANNOnWafer(Enum(124))
        hicann_3 = C.HICANNOnWafer(Enum(125))
        pop = pynn.Population(size, pynn.IF_cond_exp, {})
        pop_1 = pynn.Population(size, pynn.IF_cond_exp, {})
        pop_view = pynn.PopulationView(pop,list(range(0,size,2)))
        pop_view_1 = pynn.PopulationView(pop,list(range(1,size,2)))
        pop_1_view = pynn.PopulationView(pop_1,list(range(1,size//2)))
        pop_1_view_1 = pynn.PopulationView(pop_1,list(range(size-2,size//2,-1)))
        pop_auto_placement = pynn.PopulationView(pop_1,[0,size//2,size-1])
        self.marocco.manual_placement.on_hicann(pop_view, hicann)
        self.marocco.manual_placement.on_hicann(pop_view_1, hicann_1)
        self.marocco.manual_placement.on_hicann(pop_1_view, hicann_2)
        self.marocco.manual_placement.on_hicann(pop_1_view_1, hicann_3)

        if neuron_size * size//2 > C.NeuronOnHICANN.enum_type.size:
            with self.assertRaises(RuntimeError):
                pynn.run(0)
                pynn.end()
            return

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        for nrn in pop_view:
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            for denmem in logical_neuron:
                self.assertEqual(hicann, denmem.toHICANNOnWafer())

        for nrn in pop_view_1:
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            for denmem in logical_neuron:
                self.assertEqual(hicann_1, denmem.toHICANNOnWafer())

        for nrn in pop_1_view:
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            for denmem in logical_neuron:
                self.assertEqual(hicann_2, denmem.toHICANNOnWafer())

        for nrn in pop_1_view_1:
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            for denmem in logical_neuron:
                self.assertEqual(hicann_3, denmem.toHICANNOnWafer())

        for nrn in pop_auto_placement:
            placement_item, = results.placement.find(nrn)
            logical_neuron = placement_item.logical_neuron()
            for denmem in logical_neuron:
                self.assertIsNotNone(denmem.toHICANNOnWafer())
示例#3
0
    def test_L1_detour_at_side_switch_usage(self):
        """
                                  [155]
                                   191
            [223]  224  225 x226x {227}

            test detour and predecessor settings at the edge of a wafer

        """

        pylogging.set_loglevel(pylogging.get("marocco"),
                               pylogging.LogLevel.TRACE)
        pylogging.set_loglevel(pylogging.get("Calibtic"),
                               pylogging.LogLevel.ERROR)

        self.marocco.persist = ''  # or add test suite TestWithRuntime?

        runtime = Runtime(self.marocco.default_wafer)
        pynn.setup(marocco=self.marocco, marocco_runtime=runtime)

        settings = pysthal.Settings.get()

        settings.synapse_switches.max_switches_per_column_per_side = 1
        settings.crossbar_switches.max_switches_per_row = 1

        source = pynn.Population(1, pynn.IF_cond_exp, {})
        target1 = pynn.Population(1, pynn.IF_cond_exp, {})
        target2 = pynn.Population(1, pynn.IF_cond_exp, {})

        proj = pynn.Projection(
            source, target1, pynn.AllToAllConnector(weights=1.))
        proj = pynn.Projection(
            source, target2, pynn.AllToAllConnector(weights=1.))

        source_hicann = C.HICANNOnWafer(Enum(227))
        target1_hicann = C.HICANNOnWafer(Enum(155))
        target2_hicann = C.HICANNOnWafer(Enum(225))

        self.marocco.manual_placement.on_hicann(source, source_hicann)
        self.marocco.manual_placement.on_hicann(target1, target1_hicann)
        self.marocco.manual_placement.on_hicann(target2, target2_hicann)

        disabled_hicanns = [226, 263]
        wafer = self.marocco.default_wafer
        self.marocco.defects.set(pyredman.Wafer(runtime.wafer().index()))
        for hicann in C.iter_all(C.HICANNOnWafer):
            if hicann.toEnum().value() in disabled_hicanns:
                self.marocco.defects.wafer().hicanns().disable(C.HICANNGlobal(hicann, wafer))
            continue

        pynn.run(0)
        pynn.end()

        for hicann in runtime.wafer().getAllocatedHicannCoordinates():
            h = runtime.wafer()[hicann]
            print(hicann, h.check())
            self.assertEqual(h.check(), "")
示例#4
0
 def test_dnc_copy(self):
     import copy
     wafer_c = C.Wafer(33)
     w = pysthal.Wafer(wafer_c)
     h_c = C.HICANNGlobal(C.HICANNOnWafer(Enum(297)), wafer_c)
     h = w[h_c.toHICANNOnWafer()]
     d = w[h_c.toFPGAOnWafer()][h_c.toDNCOnFPGA()]
     d2 = copy.deepcopy(d)
     self.assertEqual(d, d2)
     # change something to ensure that it's not a mere pointer copy
     h2 = w[C.HICANNOnWafer(Enum(298))]
     self.assertNotEqual(d, d2)
示例#5
0
 def test_dnc_pickle(self):
     import pickle
     wafer_c = C.Wafer(33)
     w = pysthal.Wafer(wafer_c)
     h_c = C.HICANNGlobal(C.HICANNOnWafer(Enum(297)), wafer_c)
     h = w[h_c.toHICANNOnWafer()]
     d = w[h_c.toFPGAOnWafer()][h_c.toDNCOnFPGA()]
     d_str = pickle.dumps(d)
     d2 = pickle.loads(d_str)
     self.assertEqual(d, d2)
     # change something to ensure that it's not a mere pointer copy
     h2 = w[C.HICANNOnWafer(Enum(298))]
     self.assertNotEqual(d, d2)
示例#6
0
    def test_save_and_load(self):
        import pysthal
        from pyhalco_common import Enum
        import pyhalco_hicann_v2 as Coordinate
        from pyhalbe import HICANN
        wafer = pysthal.Wafer(Coordinate.Wafer(3))
        hicann1 = wafer[Coordinate.HICANNOnWafer(Enum(30))]

        for row in Coordinate.iter_all(Coordinate.SynapseRowOnHICANN):
            d_pattern = numpy.random.randint(0, 16, 256)
            d_pattern[d_pattern[0] + 23] = 15
            hicann1.synapses[row].decoders[:] = [
                HICANN.SynapseDecoder(int(ii)) for ii in d_pattern
            ]
            w_pattern = numpy.random.randint(0, 16, 256)
            w_pattern[w_pattern[0] + 23] = 15
            hicann1.synapses[row].weights[:] = [
                HICANN.SynapseWeight(int(ii)) for ii in w_pattern
            ]

        wafer2 = pysthal.Wafer(Coordinate.Wafer(0))
        hicann2 = wafer2[Coordinate.HICANNOnWafer(Enum(42))]
        self.assertNotEqual(str(wafer.status()), str(wafer2.status()))

        for row in Coordinate.iter_all(Coordinate.SynapseRowOnHICANN):
            d1 = hicann1.synapses[row].decoders
            d2 = hicann2.synapses[row].decoders
            self.assertNotEqual(d1, d2)

            w1 = hicann1.synapses[row].weights
            w2 = hicann2.synapses[row].weights
            self.assertNotEqual(w1, w2)

        with tempfile.NamedTemporaryFile() as f:
            wafer.dump(f.name, True)
            wafer2.load(f.name)

        self.assertEqual(wafer.size(), wafer2.size())
        hicann1 = wafer[Coordinate.HICANNOnWafer(Enum(30))]
        hicann2 = wafer2[Coordinate.HICANNOnWafer(Enum(30))]
        self.assertEqual(hicann1.index(), hicann2.index())
        self.assertEqual(str(wafer.status()), str(wafer2.status()))

        for row in Coordinate.iter_all(Coordinate.SynapseRowOnHICANN):
            d1 = hicann1.synapses[row].decoders
            d2 = hicann2.synapses[row].decoders
            self.assertEqual(d1, d2)

            w1 = hicann1.synapses[row].weights
            w2 = hicann2.synapses[row].weights
            self.assertEqual(w1, w2)
示例#7
0
    def test_same_popview_on_hicann(self, size):
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)
        hicann = C.HICANNOnWafer(Enum(123))
        hicann_1 = C.HICANNOnWafer(Enum(122))
        pop = pynn.Population(size, pynn.IF_cond_exp, {})
        pop_view = pynn.PopulationView(pop,[0])
        pop_view_1 = pynn.PopulationView(pop,[0])
        self.marocco.manual_placement.on_hicann(pop_view, hicann)
        self.marocco.manual_placement.on_hicann(pop_view_1, hicann_1)

        with self.assertRaises(RuntimeError):
            pynn.run(0)
            pynn.end()
示例#8
0
    def test_popview_external_source(self):
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)

        size = 10
        pop_ext = pynn.Population(size, pynn.SpikeSourcePoisson, {'rate':2})
        pop_ext_1 = pynn.Population(size, pynn.SpikeSourcePoisson, {'rate':2})
        pop = pynn.Population(size, pynn.IF_cond_exp, {})
        connector = pynn.AllToAllConnector(weights=1)
        projections = [
            pynn.Projection(pop_ext, pop, connector, target='excitatory'),
            pynn.Projection(pop_ext_1, pop, connector, target='excitatory'),
        ]
        hicann = C.HICANNOnWafer(Enum(121))
        hicann_1 = C.HICANNOnWafer(Enum(122))

        pop_view = pynn.PopulationView(pop_ext,list(range(1,size,2)))
        pop_view_1 = pynn.PopulationView(pop_ext,list(range(0,size,2)))
        pop_1_view = pynn.PopulationView(pop_ext_1,list(range(1,size//2)))
        pop_1_view_1 = pynn.PopulationView(pop_ext_1,list(range(size-2,size//2,-1)))
        pop_1_auto_placement = pynn.PopulationView(pop_ext_1,[0,size//2,size-1])

        self.marocco.manual_placement.on_hicann(pop_view, hicann)
        self.marocco.manual_placement.on_hicann(pop_view_1, hicann_1)
        self.marocco.manual_placement.on_hicann(pop_1_view, hicann)
        self.marocco.manual_placement.on_hicann(pop_1_view_1, hicann_1)

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        for nrn in pop_view:
            placement_item, = results.placement.find(nrn)
            self.assertEqual(hicann, placement_item.dnc_merger().toHICANNOnWafer())
        for nrn in pop_view_1:
            placement_item, = results.placement.find(nrn)
            self.assertEqual(hicann_1, placement_item.dnc_merger().toHICANNOnWafer())
        for nrn in pop_1_view:
            placement_item, = results.placement.find(nrn)
            self.assertEqual(hicann, placement_item.dnc_merger().toHICANNOnWafer())
        for nrn in pop_1_view_1:
            placement_item, = results.placement.find(nrn)
            self.assertEqual(hicann_1, placement_item.dnc_merger().toHICANNOnWafer())
        for nrn in pop_1_auto_placement:
            placement_item, = results.placement.find(nrn)
            self.assertIsNotNone(placement_item.dnc_merger().toHICANNOnWafer())
示例#9
0
    def setUp(self):
        super(TestMultiHICANN, self).setUp()

        pylogging.set_loglevel(pylogging.get("Default"), pylogging.LogLevel.ERROR)
        pylogging.set_loglevel(pylogging.get("sthal"), pylogging.LogLevel.INFO)

        if None in (self.WAFER, self.HICANN):
            return

        self.wafer_c = Coord.Wafer(self.WAFER)

        self.w = pysthal.Wafer(self.wafer_c)
        self.h1 = self.w[Coord.HICANNOnWafer(Enum(324))]
        self.h2 = self.w[Coord.HICANNOnWafer(Enum(120))]

        self.addCleanup(self.w.disconnect)
示例#10
0
    def __init__(self, *args, **kwargs):
        super(Test_Pyhwdb, self).__init__(*args, **kwargs)
        if IS_PYPLUSPLUS:
            self.WAFER_COORD = coord.Wafer(10)
            self.WAFER_SETUP_TYPE = coord.SetupType.BSSWafer
            self.WAFER_MACU_IP = coord.IPv4.from_string("192.168.10.120")
            self.FPGA_COORD = coord.FPGAOnWafer(0)
            self.FPGA_HIGHSPEED = True
        self.FPGA_IP = coord.IPv4.from_string("192.168.10.1")
        if IS_PYPLUSPLUS:
            self.RETICLE_COORD = coord.DNCOnWafer(coord.common.Enum(0))
            self.RETICLE_TO_BE_POWERED = False
            self.HICANN_COORD = coord.HICANNOnWafer(coord.common.Enum(144))
            self.HICANN_VERSION = 4
            self.HICANN_LABEL = "bla"
            self.ADC_COORD = "B123456"
            self.ADC_MODE = "LOAD_CALIBRATION"
            self.ADC_CHAN = coord.ChannelOnADC(0)
            self.ADC_TRIGGER = coord.TriggerOnADC(1)
        self.ADC_IP = coord.IPv4.from_string("192.168.10.120")
        if IS_PYPLUSPLUS:
            self.ADC_PORT = coord.TCPPort(10101)

        self.DLS_SETUP_ID = "07_20"
        self.HXCUBE_ID = 9
示例#11
0
    def test_on_hicann(self, size):
        pynn.setup(marocco=self.marocco)
        neuron_size = 4
        self.marocco.neuron_placement.default_neuron_size(neuron_size)

        hicann = C.HICANNOnWafer(Enum(123))
        pop = pynn.Population(size, pynn.IF_cond_exp, {})
        self.marocco.manual_placement.on_hicann(pop, hicann)

        if neuron_size * size > C.NeuronOnHICANN.enum_type.size:
            with self.assertRaises(RuntimeError):
                pynn.run(0)
                pynn.end()
            return

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        for nrn in pop:
            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())
    def test_access_queue(self):
        """use queue handling"""
        class myPlacer(placer):
            def loop(self):
                print("reversing populations")

                # b = self.m_queue.access;  # use this or the following
                print((dir(self.m_queue.value()[0])))
                b = self.m_queue.value()
                print((dir(b)))

        marocco = self.marocco
        user_strat = myPlacer()

        marocco.neuron_placement.default_placement_strategy(user_strat)

        pynn.setup(marocco=marocco)

        self.network()

        result = self.load_results()
        hicann = C.HICANNOnWafer(Enum(42))
        nb = C.NeuronBlockOnHICANN(Enum(4))
        for pop in self.pops:
            for nrn in pop:
                placement_item, = result.placement.find(nrn)
                logical_neuron = placement_item.logical_neuron()
                for denmem in logical_neuron:
                    # all pops shall be on different NBs
                    self.assertFalse(nb == denmem.toNeuronBlockOnHICANN()
                                     and hicann == denmem.toHICANNOnWafer())
            nb = denmem.toNeuronBlockOnHICANN()
            hicann = denmem.toHICANNOnWafer()
示例#13
0
    def test_numpy_policies(self):
        import numpy
        import pysthal
        import pyhalco_hicann_v2
        from pyhalbe import HICANN
        w = pysthal.Wafer(pyhalco_hicann_v2.Wafer())
        h = w[pyhalco_hicann_v2.HICANNOnWafer()]

        addrs = numpy.array(numpy.random.randint(64, size=100),
                            dtype=numpy.ushort)
        times = numpy.cumsum(numpy.random.poisson(10.0, size=100)) * 1.e-6
        in_spikes = pysthal.Vector_Spike()
        for addr, t in zip(addrs, times):
            in_spikes.append(pysthal.Spike(HICANN.L1Address(addr), t))

        link = pyhalco_hicann_v2.GbitLinkOnHICANN(3)
        h.sendSpikes(link, in_spikes)
        h.sortSpikes()
        x = h.sentSpikes(link)
        times_t, addrs_t = x.T

        numpy.testing.assert_allclose(times,
                                      times_t,
                                      rtol=0.0,
                                      atol=1.0 / 250e6)
        numpy.testing.assert_array_equal(
            addrs, numpy.array(addrs_t, dtype=numpy.ushort))
    def test_hw_merging_spl1_should_merge_some(self):
        """
        some DNCs shall be merged, but not all, because of syndriver
        requirements on each NB. 2 neurons will be placed (same HICANN).
        A fully connected network is built.
        This results in 8*2 = 16 synapses being routed to each neuron.
        With neuron size 4 and chain length 3 -> 12 synapses can be realised
        on each neuron. As a result at maximum 12 synapses shall be on the
        same L1Route. The merger tries to merge them and will fail, then spit
        it and merge 8 to each merger [3,5].

        The result is a better L1 utilisation compared to one-to-one mapping,
        2 instead of 8 routes, while staying within hardware constrains,
        compared to merge all (16 synapses requiring 4 drivers, 1 driver will
        be lost).
        """
        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_as_possible)
        # restrict to 3 driver, so that this test is hardware agnostic
        self.marocco.synapse_routing.driver_chain_length(3)

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

        for p in pops:
            for other_p in pops:
                pynn.Projection(p, other_p, pynn.AllToAllConnector(weights=1.))

        pynn.run(0)
        pynn.end()

        merged_dncs = [3, 3, 3, 3, 5, 5, 5, 5]

        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()

            # some DNCs shall be merged.
            dnc = C.DNCMergerOnHICANN(merged_dncs[pop.euter_id()])
            self.assertEqual(hicann, address.toHICANNOnWafer())
            self.assertEqual(dnc, address.toDNCMergerOnHICANN())
            self.assertEqual(C.DNCMergerOnWafer(dnc, hicann),
                             address.toDNCMergerOnWafer())
    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(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 must not be on DNC 3 merger, since all other
        # mergers do not have direct access to a background generator.
        dnc = C.DNCMergerOnHICANN(3)
        self.assertEqual(hicann, address.toHICANNOnWafer())
        self.assertNotEqual(dnc, address.toDNCMergerOnHICANN())
        self.assertNotEqual(C.DNCMergerOnWafer(dnc, hicann),
                            address.toDNCMergerOnWafer())
    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(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())
    def test_vertical(self):
        pylogging.set_loglevel(pylogging.get("marocco"),
                               pylogging.LogLevel.TRACE)

        marocco = self.marocco

        user_strat = placer()
        user_strat.m_hicann_on_wafer_ordering = user_strat.vertical
        user_strat.m_spiral_center = user_strat.spiral_neighbours
        marocco.neuron_placement.default_placement_strategy(user_strat)

        pynn.setup(marocco=marocco)

        pops = {}
        pops[0] = pynn.Population(128, pynn.IF_cond_exp, {})
        pops[1] = pynn.Population(128, pynn.IF_cond_exp, {})
        pops[2] = pynn.Population(128, pynn.IF_cond_exp, {})

        proj1 = pynn.Projection(pops[0], pops[1],
                                pynn.OneToOneConnector(weights=0.01))
        proj2 = pynn.Projection(pops[1], pops[2],
                                pynn.OneToOneConnector(weights=0.01))

        h = {}
        h[pops[0]] = C.HICANNOnWafer(Enum(100))
        # the next free hicann (vertical order)
        h[pops[1]] = C.HICANNOnWafer(Enum(72))
        h[pops[2]] = C.HICANNOnWafer(Enum(48))
        marocco.manual_placement.on_hicann(pops[0], h[pops[0]])

        pynn.run(0)
        pynn.end()

        result = self.load_results()
        for key in pops:
            pop = pops[key]
            for nrn in pop:
                placement_item, = result.placement.find(nrn)
                logical_neuron = placement_item.logical_neuron()
                for denmem in logical_neuron:
                    self.assertEqual(h[pop].toEnum(),
                                     denmem.toHICANNOnWafer().toEnum())
示例#18
0
    def test_dijkstra_routing(self):
        """
        Integration test for Dijkstra-based L1 routing.

        Sets up a convoluted case that requires a convex route (which would
        not work using the backbone router).

         .------->------+
        167 168 169 170 |
                    206 v
            240 241 242 |
             ^---<------+
        """
        pynn.setup(marocco=self.marocco)

        source = pynn.Population(1, pynn.IF_cond_exp, {})
        target = pynn.Population(1, pynn.IF_cond_exp, {})
        proj = pynn.Projection(
            source, target, pynn.AllToAllConnector(weights=0.004))

        source_hicann = C.HICANNOnWafer(Enum(167))
        target_hicann = C.HICANNOnWafer(Enum(240))
        self.marocco.manual_placement.on_hicann(source, source_hicann)
        self.marocco.manual_placement.on_hicann(target, target_hicann)

        allowed_hicanns = [206] + list(range(167, 171)) + list(range(240, 243))
        wafer = self.marocco.default_wafer
        self.marocco.defects.set(pyredman.Wafer())
        for hicann in C.iter_all(C.HICANNOnWafer):
            if hicann.toEnum().value() in allowed_hicanns:
                continue
            self.marocco.defects.wafer().hicanns().disable(C.HICANNGlobal(hicann, wafer))

        self.marocco.l1_routing.algorithm(self.marocco.l1_routing.dijkstra)

        pynn.run(0)
        pynn.end()

        results = self.load_results()

        synapses = results.synapse_routing.synapses()
        self.assertEqual(1, synapses.size())
    def test_loop_modularity_nb(self):
        """tests to override the loop hook with NB handling"""
        class myPlacer(placer):
            def initialise(self):
                b = sorted(
                    self.m_neuron_blocks.access,
                    key=lambda nb: int(nb.toHICANNOnWafer().toEnum().value()))
                self.m_neuron_blocks.access = b

            def loop(self):
                print("removing the last NB")

                b = self.m_neuron_blocks.access  # use this or the following
                b = self.m_neuron_blocks.value()

                b = sorted(
                    b,
                    key=lambda nb: int(nb.toHICANNOnWafer().toEnum().value()))

                c = []
                for i in range(len(b) - 1):
                    c.append(b[i])

                # use access to set full vector
                self.m_neuron_blocks.access = c

                # or use the value() to access single elements
                for i in range(len(self.m_neuron_blocks.value())):
                    del (self.m_neuron_blocks.value()[0])
                for nb in c:
                    self.m_neuron_blocks.value().append(nb)

        marocco = self.marocco
        user_strat = myPlacer()

        marocco.neuron_placement.default_placement_strategy(user_strat)

        pynn.setup(marocco=marocco)

        self.network()

        result = self.load_results()
        hicann = C.HICANNOnWafer(Enum(42))
        nb = C.NeuronBlockOnHICANN(Enum(4))
        for pop in self.pops:
            for nrn in pop:
                placement_item, = result.placement.find(nrn)
                logical_neuron = placement_item.logical_neuron()
                for denmem in logical_neuron:
                    # all pops must be on different NBs
                    self.assertFalse(nb == denmem.toNeuronBlockOnHICANN()
                                     and hicann == denmem.toHICANNOnWafer())
            nb = denmem.toNeuronBlockOnHICANN()
            hicann = denmem.toHICANNOnWafer()
    def test_external_sources_projections(self, params):
        nprojections = params[0]
        nsources = params[1]
        print((nprojections, nsources))
        """
            An external sources has multiple projections
            so it should be split if it wuld not be of size 1
            so unfortunately the users would need to live with that.
        """
        pylogging.set_loglevel(pylogging.get("marocco"),
                               pylogging.LogLevel.TRACE)
        pylogging.set_loglevel(pylogging.get("Calibtic"),
                               pylogging.LogLevel.ERROR)

        pynn.setup(marocco=self.marocco)
        self.marocco.neuron_placement.default_neuron_size(4)

        # ensure a limited synapse driver chain length.
        self.marocco.synapse_routing.driver_chain_length(3)

        # we expect synapse loss, but we dont care, as the source cant be split.
        # we want this tests not to throw exceptions.
        self.marocco.continue_despite_synapse_loss = True

        target = pynn.Population(1, pynn.IF_cond_exp, {})
        hicann = C.HICANNOnWafer(Enum(100))
        self.marocco.manual_placement.on_hicann(target, hicann)

        exsource = pynn.Population(nsources, pynn.SpikeSourcePoisson,
                                   {'rate': 1.})
        for i in range(nprojections):
            proj = pynn.Projection(exsource, target,
                                   pynn.AllToAllConnector(weights=1.))

        # access to proj so flake8 keeps silent
        proj.size

        pynn.run(0)
        pynn.end()

        results = self.load_results()
        synapses = results.synapse_routing.synapses()
        placement = results.placement

        for dnc in C.iter_all(C.DNCMergerOnWafer):
            PonDNC = placement.find(dnc)  # PopulationOnDNC
            if PonDNC:
                ## if driver requirements exceeded, only one source should be
                ## placed on the DNC, but synapse loss is still expected
                if (nprojections > 4):  # this number is just guessed
                    self.assertTrue(len(PonDNC) <= 1)
                else:
                    self.assertTrue(len(PonDNC) <= 12)
    def test_cluster_target(self):
        marocco = self.marocco

        user_strat = placer()
        user_strat.m_spiral_center = user_strat.spiral_neighbours_target
        marocco.neuron_placement.default_placement_strategy(user_strat)

        pynn.setup(marocco=marocco)

        pops = {}
        pops[0] = pynn.Population(1, pynn.IF_cond_exp, {})
        pops[1] = pynn.Population(1, pynn.IF_cond_exp, {})
        pops[2] = pynn.Population(1, pynn.IF_cond_exp, {})

        proj1 = pynn.Projection(pops[0], pops[1],
                                pynn.AllToAllConnector(weights=0.01))
        proj2 = pynn.Projection(pops[1], pops[2],
                                pynn.AllToAllConnector(weights=0.01))

        h = {}
        h[pops[0]] = C.HICANNOnWafer(Enum(100))
        # average positon of target
        h[pops[1]] = C.HICANNOnWafer(Enum(102))
        h[pops[2]] = C.HICANNOnWafer(Enum(102))
        marocco.manual_placement.on_hicann(pops[0], h[pops[0]])
        marocco.manual_placement.on_hicann(pops[2], h[pops[2]])

        pynn.run(0)
        pynn.end()

        result = self.load_results()
        for key in pops:
            pop = pops[key]
            for nrn in pop:
                placement_item, = result.placement.find(nrn)
                logical_neuron = placement_item.logical_neuron()
                for denmem in logical_neuron:
                    self.assertEqual(h[pop].toEnum(),
                                     denmem.toHICANNOnWafer().toEnum())
示例#22
0
 def test_wafer_copy(self):
     import copy
     wafer_c = C.Wafer(33)
     w = pysthal.Wafer(wafer_c)
     h_c = C.HICANNOnWafer(Enum(297))
     h = w[h_c]
     self.assertTrue(h.has_wafer())
     w2 = copy.deepcopy(w)
     self.assertEqual(w, w2)
     h2 = w2[h_c]
     self.assertTrue(h2.has_wafer())
     # change something to ensure that it's not a mere pointer copy
     h.set_neuron_size(2)
     self.assertNotEqual(w, w2)
示例#23
0
 def test_wafer_pickle(self):
     import pickle
     wafer_c = C.Wafer(33)
     w = pysthal.Wafer(wafer_c)
     h_c = C.HICANNOnWafer(Enum(297))
     h = w[h_c]
     self.assertTrue(h.has_wafer())
     w_str = pickle.dumps(w)
     w2 = pickle.loads(w_str)
     self.assertEqual(w, w2)
     h2 = w2[h_c]
     self.assertTrue(h2.has_wafer())
     # change something to ensure that it's not a mere pointer copy
     h.set_neuron_size(2)
     self.assertNotEqual(w, w2)
    def test_external_sources_drivers(self, nsources):
        """
            A lot external sources are placed
            no error should be thrown
            the sources should be split
        """
        pylogging.set_loglevel(pylogging.get("marocco"),
                               pylogging.LogLevel.DEBUG)
        pylogging.set_loglevel(pylogging.get("Calibtic"),
                               pylogging.LogLevel.ERROR)

        pynn.setup(marocco=self.marocco)
        self.marocco.neuron_placement.default_neuron_size(4)

        # ensure a limited synapse driver chain length.
        self.marocco.synapse_routing.driver_chain_length(3)

        # if synapse loss occours we want to handle it on our own
        self.marocco.continue_despite_synapse_loss = True

        target = pynn.Population(1, pynn.IF_cond_exp, {})
        hicann = C.HICANNOnWafer(Enum(100))
        self.marocco.manual_placement.on_hicann(target, hicann)

        exsource = pynn.Population(nsources, pynn.SpikeSourcePoisson,
                                   {'rate': 1.})
        proj = pynn.Projection(exsource, target,
                               pynn.AllToAllConnector(weights=1.))

        # access to proj so flake8 keeps silent
        proj.size

        pynn.run(0)
        pynn.end()

        results = self.load_results()
        synapses = results.synapse_routing.synapses()
        placement = results.placement

        # test for synapse loss
        self.assertEqual(nsources, synapses.size())

        for dnc in C.iter_all(C.DNCMergerOnWafer):
            PonDNC = placement.find(dnc)  # PopulationOnDNC
            if PonDNC:
                ## with a neuron size of 4 and  a chain length of 3,
                ## around 12 sources can fit into a merger
                self.assertTrue(len(PonDNC) <= 12)
示例#25
0
 def test_wafer_dumpnload(self):
     import tempfile
     wafer_c = C.Wafer(33)
     w = pysthal.Wafer(wafer_c)
     h_c = C.HICANNOnWafer(Enum(297))
     h = w[h_c]
     with tempfile.NamedTemporaryFile() as f:
         w.dump(f.name, True)
         w2 = pysthal.Wafer(wafer_c)
         w2.load(f.name)
     self.assertEqual(w, w2)
     h2 = w2[h_c]
     self.assertTrue(h2.has_wafer())
     # change something to ensure that it's not a mere pointer copy
     h.set_neuron_size(2)
     self.assertNotEqual(w, w2)
示例#26
0
    def test_popview_combinations(self, view_number):
        # tests all possible combinations of mask lengths for different number of PopulationViews
        import pylogging
        from pymarocco import PyMarocco, Defects
        from pymarocco.results import Marocco
        pop_size = 5
        hicanns = [C.HICANNOnWafer(Enum(180 + view)) for view in range(view_number)]
        # generate possible mask lengths for Population Views
        pool = tuple(i for i in range(1, pop_size - view_number + 2))
        # generate all possible mask lengths for each PopulationView for a given total number of neurons
        # [[lengths_of_Popviews],number_of_used_neurons]
        view_lengths = [([], 0)]
        for _ in range(view_number):
            view_lengths = [(x+[y], csum+y) for x, csum in view_lengths for y in pool if csum <= pop_size - y]
        neurons = list(range(pop_size))
        for length in view_lengths:
            marocco = PyMarocco()
            marocco.backend = PyMarocco.Without
            marocco.persist = "results.bin"
            marocco.defects.backend = Defects.Backend.Without
            neuron_size = 4
            marocco.neuron_placement.default_neuron_size(neuron_size)
            pynn.setup(marocco=marocco)

            pop = pynn.Population(pop_size, pynn.IF_cond_exp, {})
            pop_views = []
            index = 0
            for view in range(view_number):
                # generate PopulationViews with all possible mask lengths
                # no permutations of neurons are tested
                pop_views.append(pynn.PopulationView(pop,neurons[index:index+length[0][view]]))
                marocco.manual_placement.on_hicann(pop_views[view],hicanns[view])
                index += length[0][view]

            pynn.run(0)
            pynn.end()
            results = Marocco.from_file(marocco.persist)

            for view in range(view_number):
                for nrn in pop_views[view]:
                    placement_item, = results.placement.find(nrn)
                    logical_neuron = placement_item.logical_neuron()
                    for denmem in logical_neuron:
                        self.assertEqual(hicanns[view], denmem.toHICANNOnWafer())
示例#27
0
    def test_analog_outputs(self, num_recorded_populations):
        """
        Test that analog outputs are correctly assigned and that
        mapping fails if per-HICANN constraints are broken.
        """
        pynn.setup(marocco=self.marocco)
        hicann = C.HICANNOnWafer(Enum(210))

        pops = []
        for i in range(num_recorded_populations):
            pop = pynn.Population(1, pynn.IF_cond_exp, {})
            self.marocco.manual_placement.on_hicann(pop, hicann)
            pop.record_v()
            pops.append(pop)

        if num_recorded_populations > 2:
            with self.assertRaises(RuntimeError):
                pynn.run(0)
                pynn.end()
            return

        pynn.run(0)
        pynn.end()

        results = self.load_results()
        placement_item, = results.placement.find(pop[0])

        aouts = list(results.analog_outputs)
        self.assertEqual(num_recorded_populations, len(aouts))

        for pop in pops:
            placement_item, = list(results.placement.find(pop[0]))

            logical_neuron = placement_item.logical_neuron()
            for aout_item in aouts:
                if aout_item.logical_neuron() == logical_neuron:
                    break
            else:
                self.fail("logical neuron not found in analog outputs result")

            aout_item_ = results.analog_outputs.record(logical_neuron)
            self.assertEqual(aout_item.analog_output(),
                             aout_item_.analog_output())
    def test_min_spl1_is_nongreedy(self):
        """
        When placing a single population to a HICANN there should still be room for external input.
        Previously the default merger routing strategy (min SPL1) merged as many adjacent neuron
        blocks as possible.  In doing this, the NeuronBlockOnHICANN(7) was connected to
        DNCMergerOnHICANN(3).
        This prevented the external input to be placed to DNCMergerOnHICANN(7) of the same HICANN,
        since the corresponding background generator could not be connected.
        """
        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(Enum(123))
        pop = pynn.Population(1, pynn.IF_cond_exp, {})
        self.marocco.manual_placement.on_hicann(pop, hicann)
        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()

        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())

        nrn = in_pop[0]
        placement_item, = results.placement.find(nrn)
        logical_neuron = placement_item.logical_neuron()
        self.assertTrue(logical_neuron.is_external())
        self.assertEqual(hicann, placement_item.address().toHICANNOnWafer())
    def test_external_sources_rates(self, nsources):
        """
            A lot external sources are placed
            no error should be thrown
        """
        pylogging.set_loglevel(pylogging.get("marocco"),
                               pylogging.LogLevel.DEBUG)
        pylogging.set_loglevel(pylogging.get("Calibtic"),
                               pylogging.LogLevel.ERROR)

        pynn.setup(marocco=self.marocco)
        self.marocco.neuron_placement.default_neuron_size(4)

        # ignore the synapse driver chain length.
        self.marocco.synapse_routing.driver_chain_length(100)

        # we expect synapse loss, but we dont care.
        # we want this tests not to throw exceptions.
        self.marocco.continue_despite_synapse_loss = True

        target = pynn.Population(1, pynn.IF_cond_exp, {})
        hicann = C.HICANNOnWafer(Enum(100))
        self.marocco.manual_placement.on_hicann(target, hicann)

        exsource = pynn.Population(nsources, pynn.SpikeSourcePoisson,
                                   {'rate': 1.})
        proj = pynn.Projection(exsource, target,
                               pynn.AllToAllConnector(weights=1.))

        # access to proj so flake8 keeps silent
        proj.size

        pynn.run(0)
        pynn.end()

        results = self.load_results()
        synapses = results.synapse_routing.synapses()

        self.assertEqual(nsources, synapses.size())
    def run_experiment(self,
                       marocco,
                       n_stim,
                       rate,
                       poisson=True,
                       shuffle=False):
        """
        runs experiment with `n_stim` SpikeSources, firing at
        `rate` Hz, all connected to 1 neuron.
        returns a  result dictionary, with keys `hicanns` and `fpgas`, each
        containing used FPGA/HICANN coords and number of sources mapped per
        FPGA/HICANN.
        further params:
        poisson - if True, use SpikeSourcePoisson, else use SpikeSourceArrays
                  with regular firing
        shuffle - if True, the spike times used for SpikeSourceArray are
                  shuffled, i.e. they are not sorted. Only valid if
                  poisson=True)
        """

        sim_duration = 200.
        marocco.persist = os.path.join(self.temporary_directory, "results.bin")
        pynn.setup(marocco=marocco)

        exc_pop = pynn.Population(1, pynn.IF_cond_exp, {})

        # place target onto a hicann in the center of reticle and at the border of the wafer
        # such that hicanns from the same reticle are used with preference (1 reticle -> same fpga)
        marocco.manual_placement.on_hicann(
            exc_pop, C.HICANNOnWafer(pyhalco_common.Enum(1)))

        if poisson:
            pop_stim = pynn.Population(n_stim, pynn.SpikeSourcePoisson, {
                'rate': rate,
                'duration': sim_duration
            })
        else:
            pop_stim = pynn.Population(n_stim, pynn.SpikeSourceArray)
            for i in range(n_stim):
                isi = 1.e3 / rate
                spike_times = np.arange((i + 1) * 1. / n_stim * isi,
                                        sim_duration, isi)
                if shuffle:
                    np.random.shuffle(spike_times)
                pop_stim[i:i + 1].set('spike_times', spike_times.tolist())
        a2a = pynn.AllToAllConnector(weights=0.001, delays=2.)
        pynn.Projection(pop_stim, exc_pop, a2a, target='excitatory')
        pynn.run(sim_duration)

        results = Marocco.from_file(marocco.persist)
        hicanns = {}  # count number of stimuli mapped on Hicann
        fpgas = {}  # count number of stimuli mapped on fpga
        for idx in range(len(pop_stim)):
            items = list(results.placement.find(pop_stim[idx]))
            # stim nrns are only placed once per wafer
            self.assertEqual(1, len(items))
            address = items[0].address()
            hicann_str = str(address.toHICANNOnWafer())
            hicanns[hicann_str] = hicanns.get(hicann_str, 0) + 1
            hicann_global = C.HICANNGlobal(address.toHICANNOnWafer(),
                                           C.Wafer())
            fpga_str = str(hicann_global.toFPGAGlobal())
            fpgas[fpga_str] = fpgas.get(fpga_str, 0) + 1

        pynn.end()
        return dict(hicanns=hicanns, fpgas=fpgas)