def test_has_outbound_mergers(self): import pyhalbe import pysthal from pyhalco_common import Enum import pyhalco_hicann_v2 as C wafer_c = C.Wafer(33) gbitlink_c = C.GbitLinkOnHICANN(Enum(0)) fpga_on_wafer_c = C.FPGAOnWafer(Enum(0)) fpga_c = C.FPGAGlobal(fpga_on_wafer_c, wafer_c) hicann_cs = [ C.HICANNGlobal(h, wafer_c) for h in fpga_c.toHICANNOnWafer() ] hicann_c = hicann_cs[0] hicann_on_dnc_c = hicann_c.toHICANNOnWafer().toHICANNOnDNC() dnc_on_fpga_c = hicann_c.toDNCOnFPGA() w = pysthal.Wafer() h = w[hicann_c.toHICANNOnWafer()] f = w[fpga_on_wafer_c] self.assertFalse(f.hasOutboundMergers()) f[dnc_on_fpga_c][hicann_on_dnc_c].layer1[ gbitlink_c] = pyhalbe.HICANN.GbitLink.Direction.TO_DNC self.assertTrue(f.hasOutboundMergers())
def test_invalid_adds(self): """Check that errors a risen on invalid add calls""" db = pysthal.YAMLHardwareDatabase() with self.assertRaises(IndexError) as err: db.add_fpga(FPGAGlobal(FPGAOnWafer(0), Wafer(4)), IPv4.from_string("192.168.4.1")) self.assertEqual("map::at", str(err.exception)) with self.assertRaises(IndexError) as err: db.add_hicann(HICANNGlobal(HICANNOnWafer(Enum(88)), Wafer(4)), 2, "X") self.assertEqual("map::at", str(err.exception)) with self.assertRaises(IndexError) as err: db.add_adc(FPGAGlobal(FPGAOnWafer(0), Wafer(4)), AnalogOnHICANN(0), ADC("B201287"), ChannelOnADC(1), TriggerOnADC(0)) self.assertEqual("map::at", str(err.exception)) db.add_wafer(Wafer(4), SetupType.CubeSetup) self.assertFalse(db.has_fpga(FPGAGlobal(FPGAOnWafer(0), Wafer(4)))) with self.assertRaises(IndexError) as err: db.add_hicann(HICANNGlobal(HICANNOnWafer(Enum(88)), Wafer(4)), 2, "X") self.assertIn("map::at", str(err.exception))
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()
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())
def set_sthal_params(wafer, gmax, gmax_div): """ synaptic strength: gmax: 0 - 1023, strongest: 1023 gmax_div: 2 - 30, strongest: 2 """ # for all HICANNs in use for hicann in wafer.getAllocatedHicannCoordinates(): fgs = wafer[hicann].floating_gates # set parameters influencing the synaptic strength for block in iter_all(FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_gmax0, gmax) fgs.setShared(block, HICANN.shared_parameter.V_gmax1, gmax) fgs.setShared(block, HICANN.shared_parameter.V_gmax2, gmax) fgs.setShared(block, HICANN.shared_parameter.V_gmax3, gmax) for driver in iter_all(SynapseDriverOnHICANN): for row in iter_all(RowOnSynapseDriver): wafer[hicann].synapses[driver][row].set_gmax_div( HICANN.GmaxDiv(gmax_div)) # don't change values below for ii in xrange(fgs.getNoProgrammingPasses()): cfg = fgs.getFGConfig(Enum(ii)) cfg.fg_biasn = 0 cfg.fg_bias = 0 fgs.setFGConfig(Enum(ii), cfg) for block in iter_all(FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_dllres, 275) fgs.setShared(block, HICANN.shared_parameter.V_ccas, 800)
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()
def add_shared_param_pattern(self, lookup_func): """ Add a pattern over all shared parameters of four neurons (one on each block) using the lookup function `lookup_func` Note: Because floating gate cells are addressed by (neuron, parameter) all neurons are equivalent for shared parameters as long as they obtain their parameter values from the same block. """ nrns = [ C.NeuronOnHICANN(Enum(254)), C.NeuronOnHICANN(Enum(255)), C.NeuronOnHICANN(Enum(510)), C.NeuronOnHICANN(Enum(511))] shared_param_list = [ shared_parameter.V_reset, shared_parameter.int_op_bias, shared_parameter.V_dllres, shared_parameter.V_bout, shared_parameter.V_bexp, shared_parameter.V_fac, shared_parameter.I_breset, shared_parameter.V_dep, shared_parameter.I_bstim, shared_parameter.V_thigh, shared_parameter.V_gmax3, shared_parameter.V_tlow, shared_parameter.V_gmax0, shared_parameter.V_clra, shared_parameter.V_clrc, shared_parameter.V_gmax1, shared_parameter.V_stdf, shared_parameter.V_gmax2, shared_parameter.V_m, shared_parameter.V_bstdf, shared_parameter.V_dtc, shared_parameter.V_br, shared_parameter.V_ccas, ] logger = pylogging.get("test_fg_writing_precision") idx = 0 value = 0 for nrn in nrns: for param in shared_param_list: # NOTE: not all parameters available on all quads value = int(lookup_func(float(idx) / (len(nrns) * (len(shared_param_list) - 2)))) try: self.set_value(nrn, param, value) except IndexError: # NOTE: Skip parameters which are not present on this block logger.info("Skipping parameter {} for neuron {}".format( str(param), str(nrn))) continue idx += 1
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(), "")
def hicanns_on_dnc(dnc): per_dnc = C.HICANNOnDNC.enum_type.size offset = (per_dnc // 2 - 1) h0 = C.HICANNOnDNC(Enum(0)).toHICANNOnWafer(dnc) h1 = C.HICANNOnDNC(Enum(per_dnc // 2)).toHICANNOnWafer(dnc) top = list(range(h0.toEnum().value(), h0.toEnum().value() + offset + 1)) bot = list(range(h1.toEnum().value(), h1.toEnum().value() + offset + 1)) return top + bot
def print_hicanns_on_dnc(dnc, indent=""): per_dnc = Coordinate.HICANNOnDNC.enum_type.size offset = (per_dnc / 2 - 1) h0 = Coordinate.HICANNOnDNC(Enum(0)).toHICANNOnWafer(dnc) h1 = Coordinate.HICANNOnDNC(Enum(per_dnc / 2)).toHICANNOnWafer(dnc) hid0 = h0.toEnum() hid1 = h1.toEnum() return "{}{} - {} ({} - {}, {} - {})\n".format(indent, h0, h1, hid0, Enum(hid0.value() + offset), hid1, Enum(hid1.value() + offset))
def test_SweepNeurons(self): """When the exponential term of a neuron is disabled and firing is off V_t should not have any effect on the rest potential.""" # FIXME: Differs from HICANN to HICANN, this needs connection database analog = Coordinate.AnalogOnHICANN(0) adc_channel = 3 bigcap = True trace_length = 1950 neurons = [Coordinate.NeuronOnHICANN(Enum(ii)) for ii in range(512)] threshold_voltages = np.arange(0, 1024, step=20, dtype=np.ushort) membrane = np.zeros((len(neurons), threshold_voltages.size)) nconf = HICANN.NeuronConfig() nconf.bigcap[int(top)] = bigcap nconf.bigcap[int(bottom)] = bigcap HICANN.set_neuron_config(self.h, nconf) for ii, V_t in enumerate(threshold_voltages): fgctrl = HICANN.FGControl() for nrn in neurons: fgctrl.setNeuron(nrn, HICANN.neuron_parameter.V_t, V_t) fgctrl.setNeuron(nrn, HICANN.neuron_parameter.I_bexp, 0) for block in [Coordinate.FGBlockOnHICANN(Enum(xx)) for xx in range(4)]: HICANN.set_fg_values(self.h, block, fgctrl.getBlock(block)) for jj, neuron in enumerate(neurons): self.set_denmem_quads(neuron, enable_aout=True) self.set_analog(analog, neuron) trace, v, t = self.get_trace( adc_channel, trace_length) membrane[jj, ii] = v.mean() if False: import pylab import matplotlib fig, ax = pylab.subplots() cax = ax.imshow(membrane.T, interpolation='nearest', cmap=matplotlib.cm.coolwarm) fig.colorbar(cax, orientation='horizontal') fig.show() # Case 1: Radically different behaviour between upper neurons and lower neurons. std = membrane.std(axis=1) self.assertAlmostEqual(std[:256].mean(), std[256:].mean(), places=2) # Case 2: Ideally we would want uniform behaviour for all values of V_t. self.assertLess(membrane.mean(axis=0).std(), 0.05)
def test_wafer_with_backend(self): wid = Wafer(5) hid = HICANNOnWafer(Enum(23)) fid = FPGAOnWafer(Enum(42)) wafer = redman.WaferWithBackend(self.backend, wid) hicanns = wafer.hicanns() fpgas = wafer.fpgas() if not hicanns.has(hid): hicanns.enable(hid) self.assertTrue(hicanns.has(hid)) wafer.save() if not fpgas.has(fid): fpgas.enable(fid) self.assertTrue(fpgas.has(fid)) wafer.save() hicann = wafer.get(hid) self.assertTrue(hicann) nrns = hicann.neurons() absent = NeuronOnHICANN(Enum(7)) if nrns.has(absent): nrns.disable(absent) self.assertFalse(nrns.has(absent)) # hicann is lazy-loaded and cached self.assertFalse(wafer.get(hid).neurons().has(absent)) n = nrns.available() nrns.enable(absent) self.assertTrue(nrns.has(absent)) self.assertEqual(nrns.available(), n + 1) fpga = wafer.get(fid) self.assertTrue(fpga) hoss = fpga.hslinks() absent = HighspeedLinkOnDNC(Enum(7)) if hoss.has(absent): hoss.disable(absent) self.assertFalse(hoss.has(absent)) # fpga is lazy-loaded and cached self.assertFalse(wafer.get(fid).hslinks().has(absent)) n = hoss.available() hoss.enable(absent) self.assertTrue(hoss.has(absent)) self.assertEqual(hoss.available(), n + 1)
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_loss_in_wafer_routing(self, mode): h0 = HICANNGlobal(HICANNOnWafer(Enum(0)), Wafer(33)) h1 = HICANNGlobal(HICANNOnWafer(Enum(1)), Wafer(33)) # disable all horizontal buses on h0 hicann = pyredman.Hicann() for hbus in iter_all(HLineOnHICANN): hicann.hbuses().disable(hbus) self.marocco.defects.set(pyredman.Wafer()) self.marocco.defects.wafer().inject(h0, hicann) pynn.setup(marocco=self.marocco) n1 = 100 n2 = 100 p1 = pynn.Population(n1, pynn.EIF_cond_exp_isfa_ista) p2 = pynn.Population(n2, pynn.EIF_cond_exp_isfa_ista) self.marocco.manual_placement.on_hicann(p1, h0) self.marocco.manual_placement.on_hicann(p2, h1) n_post = 10 if mode == "Population": src = p1 tgt = p2 exp_loss = len(src) * n_post elif mode == "PopulationView": src = p1[n1 // 2:n1] tgt = p2[n2 // 2:n2] exp_loss = len(src) * n_post elif mode == "Assembly": src = pynn.Assembly(p1, p2) tgt = p2 exp_loss = len(p1) * n_post conn = pynn.FixedNumberPostConnector(n_post, allow_self_connections=True, weights=1.) proj = pynn.Projection(src, tgt, conn, target='excitatory') pynn.run(100) pynn.end() # check stats self.assertEqual(exp_loss, self.marocco.stats.getSynapseLossAfterL1Routing()) self.assertEqual(exp_loss, self.marocco.stats.getSynapseLoss()) # check weight matrices orig_weights = proj.getWeights(format="array") mapped_weights = self.marocco.stats.getWeights(proj) lost_syns = np.logical_and(np.isfinite(orig_weights), np.isnan(mapped_weights)) self.assertEqual(exp_loss, np.count_nonzero(lost_syns))
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)
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)
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)
def test_short_format(self): from pyhalco_common import Enum import pyhalco_hicann_v2 as C self.assertEqual( C.short_format( C.HICANNGlobal(C.HICANNOnWafer(Enum(42)), C.Wafer(12))), "W012H042") self.assertEqual( C.short_format(C.FPGAGlobal(C.FPGAOnWafer(Enum(11)), C.Wafer(5))), "W005F011") self.assertEqual(C.short_format(C.HICANNOnWafer(Enum(12))), "H012") self.assertEqual(C.short_format(C.FPGAOnWafer(Enum(12))), "F012") self.assertEqual(C.short_format(C.Wafer(32)), "W032")
def get_all_functions(self, foo, fpga=False): all = self.tree.xpath('/boost_serialization/type[text()="%s"]' % foo) for n in all: hicann, parameters = self.get_parameters(n) if not fpga: hc = HICANNGlobal(Enum(self.values_to_int(self.recursive_dict(hicann))['e'])) else: hc = HICANNGlobal(Enum(self.values_to_int(self.recursive_dict(hicann))['wafer'])) #or 'value' if self.coordinate.hicann() != hc and not fpga: print("ignore non-matching hicanns...") print("ignoring HICANN", hc, "(looking for", self.coordinate.hicann(), ")") continue else: yield hicann, parameters
def test_check_testports(self): """ Check if checking for more than one test output per test port per repeater block works. """ import pyhalbe import pysthal from pyhalco_common import Enum, left, top import pyhalco_hicann_v2 as C hicann = pysthal.HICANN() # HRepeaterOnHICANN 0 and 2 are on different test ports hicann.repeater[C.HRepeaterOnHICANN(Enum(0))].setOutput(left) hicann.repeater[C.HRepeaterOnHICANN(Enum(2))].setOutput(left) self.assertEqual(hicann.check(), "") hicann.repeater.clearReapeater() # HRepeaterOnHICANN 0 and 4 are on the same test port hicann.repeater[C.HRepeaterOnHICANN(Enum(0))].setOutput(left) hicann.repeater[C.HRepeaterOnHICANN(Enum(4))].setOutput(left) self.assertNotEqual(hicann.check(), "") hicann.repeater.clearReapeater() # VRepeaterOnHICANN 0 and 2 are on the same test port hicann.repeater[C.VRepeaterOnHICANN(Enum(0))].setOutput(top) hicann.repeater[C.VRepeaterOnHICANN(Enum(2))].setOutput(top) self.assertNotEqual(hicann.check(), "") hicann.repeater.clearReapeater() # VRepeaterOnHICANN 0 and 4 are on different test ports hicann.repeater[C.VRepeaterOnHICANN(Enum(0))].setOutput(top) hicann.repeater[C.VRepeaterOnHICANN(Enum(1))].setOutput(top) self.assertEqual(hicann.check(), "") hicann.repeater.clearReapeater()
def set_essential_shared(self): """ Set the parameters `V_m` and `int_op_bias` for neurons on all four blocks to 'safe' values. """ nrn_list = [ C.NeuronOnHICANN(Enum(254)), C.NeuronOnHICANN(Enum(255)), C.NeuronOnHICANN(Enum(510)), C.NeuronOnHICANN(Enum(511))] for nrn in nrn_list: self.set_value(nrn, shared_parameter.int_op_bias, 1023, False) self.set_value(nrn, shared_parameter.V_m, 100, False)
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()
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())
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)
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_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_adc_factory(self): """ Test that the ADC config is complete an has a factory set """ yaml = """ --- wafer: 20 setuptype: BSSWafer macu: 0.0.0.0 macuversion: 1 fpgas: - fpga: 0 ip: 192.168.1.1 adcs: - fpga: 0 dnc_on_fpga: 0 analog: 0 adc: "03" channel: 6 trigger: 1 - fpga: 0 dnc_on_fpga: 0 analog: 1 adc: "04" remote_ip: "123.123.123.123" remote_port: 321 channel: 6 trigger: 1 """ db = pysthal.YAMLHardwareDatabase() with tempfile.NamedTemporaryFile(mode="w+") as f: f.write(yaml) f.flush() db.load(f.name) hicann = HICANNGlobal(HICANNOnWafer(Enum(144)), Wafer(20)) analog = AnalogOnHICANN(0) cfg = db.get_adc_of_hicann(hicann, analog) self.assertEqual(cfg.channel, ChannelOnADC(6)) self.assertEqual(cfg.trigger, TriggerOnADC(1)) self.assertEqual(cfg.coord, ADC("03")) self.assertEqual(cfg.loadCalibration, pysthal.ADCConfig.CalibrationMode.LOAD_CALIBRATION) with self.assertRaises(TypeError): # If cfg.factory would be a null pointer cfg.factory would be None # and no error would be raised f = cfg.factory analog = AnalogOnHICANN(1) cfg = db.get_adc_of_hicann(hicann, analog) self.assertEqual(cfg.channel, ChannelOnADC(6)) self.assertEqual(cfg.trigger, TriggerOnADC(1)) self.assertEqual(cfg.coord, ADC("04")) self.assertEqual(cfg.loadCalibration, pysthal.ADCConfig.CalibrationMode.LOAD_CALIBRATION) with self.assertRaises(TypeError): # If cfg.factory would be a null pointer cfg.factory would be None # and no error would be raised f = cfg.factory
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 add_nrn_param_pattern(self, lookup_func): """ Add a pattern over all neuron parameters of four neurons (one on each block) using the lookup function `lookup_func` """ nrns = [ C.NeuronOnHICANN(Enum(204)), C.NeuronOnHICANN(Enum(205)), C.NeuronOnHICANN(Enum(460)), C.NeuronOnHICANN(Enum(461))] neuron_param_list = [ neuron_parameter.E_l, neuron_parameter.E_syni, neuron_parameter.E_synx, neuron_parameter.I_bexp, neuron_parameter.I_convi, neuron_parameter.I_convx, neuron_parameter.I_fire, neuron_parameter.I_gl, neuron_parameter.I_gladapt, neuron_parameter.I_intbbi, neuron_parameter.I_intbbx, neuron_parameter.I_pl, neuron_parameter.I_radapt, neuron_parameter.I_rexp, neuron_parameter.I_spikeamp, neuron_parameter.V_exp, neuron_parameter.V_syni, neuron_parameter.V_syntci, neuron_parameter.V_syntcx, neuron_parameter.V_synx, neuron_parameter.V_t, neuron_parameter.V_convoffi, neuron_parameter.V_convoffx, ] idx = 0 value = 0 for nrn in nrns: for param in neuron_param_list: idx += 1 value = int(lookup_func(float(idx) / (len(nrns) * len(neuron_param_list)))) self.set_value(nrn, param, value)
def test_FIFO_loopback(self): loop = False mergers = HICANN.DNCMergerLine() mer = HICANN.DNCMerger() for j in range(8): if (j % 2): mer.config = HICANN.Merger.RIGHT_ONLY else: mer.config = HICANN.Merger.LEFT_ONLY mer.slow = False mer.loopback = not (j % 2) mergers[Coordinate.DNCMergerOnHICANN(j)] = mer HICANN.set_dnc_merger(self.h, mergers) gbit = DNC.GbitReticle() link = HICANN.GbitLink() for i in range(8): if (i % 2): link.dirs[i] = HICANN.GbitLink.Direction.TO_DNC else: link.dirs[i] = HICANN.GbitLink.Direction.TO_HICANN gbit[self.h.to_HICANNOnDNC()] = link HICANN.set_gbit_link(self.h, link) DNC.set_hicann_directions(self.fpga, self.dnc, gbit) sent_data = [] received_data = FPGA.PulseEventContainer() sent_data.clear() received_data.clear() GbitLinkOnHICANN = Coordinate.GbitLinkOnHICANN for i in range(500): #500 events, first spike getTime non-zero sent_data.append( FPGA.PulseEvent( self.h.to_DNCOnFPGA(), #DNC-number (1 for vertical setup) self.h.to_HICANNOnDNC(), #HICANN number 0 GbitLinkOnHICANN(0), #channel number 0 HICANN.L1Address(0), #neuron number 0 500 * i + 500)) #every 500 cycles #send and receive events received_data = FPGA.send_and_receive( self.fpga, self.dnc, FPGA.PulseEventContainer(sent_data), loop, 100000) #0,1 seconds for i in range(8): link.dirs[i] = HICANN.GbitLink.Direction.OFF for i in range(8): gbit[Coordinate.HICANNOnDNC(Enum(i))] = link HICANN.set_gbit_link(self.h, link) DNC.set_hicann_directions(self.fpga, self.dnc, gbit) HICANN.flush(self.h) #flush to hardware print(len(sent_data), " packets sent, ", received_data.size(), " received") self.assertEqual(len(sent_data), received_data.size())