def find_synapses(synapses, drv, addr): """ finds synapses with a given l1 addr on a synapse driver returns the Coordinates of all synapses on a synapse driver, which decode the L1 address, by comparing the 2 MSB per strobe Pattern and the 4 LSB per synapse params: synapses - a pysthal.SynapseArray object drv - synapse driver coordinate addr - L1Address of source neuron """ sd = addr.getSynapseDecoderMask() dd = addr.getDriverDecoderMask() rv = [] drv_cfg = synapses[drv] for row_on_driver in (Coord.top,Coord.bottom): row_addr = Coord.SynapseRowOnHICANN(drv,row_on_driver) decoders = synapses[row_addr].decoders # check 2 MSB row_cfg = drv_cfg[Coord.RowOnSynapseDriver(row_on_driver)] # halbe uses SideVertical to represent even and odd columns for parity in (Coord.top,Coord.bottom): if row_cfg.get_decoder(parity) == dd: for i in range(int(parity),len(decoders),2): if decoders[i] == sd: rv.append(Coord.SynapseOnHICANN(row_addr, Coord.SynapseColumnOnHICANN(i))) return rv
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 get_trace(self, adc_channel, trace_length): HICANN.flush(self.h) conf = ADC.Config(trace_length, Coordinate.ChannelOnADC(adc_channel), Coordinate.TriggerOnADC(0)) ADC.config(self.adc, conf) ADC.trigger_now(self.adc) trace = ADC.get_trace(self.adc) v = -0.00066535 * trace + 2.02391 t = np.arange(trace.size) * 1 / 96e6 return (trace, v, t)
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())
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())
def measure(adc, ip, port, channel, samples): handle = None if ip: assert port ip = Coordinate.IPv4.from_string(ip) port = Coordinate.TCPPort(port) handle = Handle.ADCRemoteHw(ip, port, adc) else: # local handle handle = Handle.ADCHw(adc) config = ADC.Config(samples, channel, Coordinate.TriggerOnADC(0)) ADC.config(handle, config) dt = 1.0 / ADC.get_sample_rate(handle) ADC.trigger_now(handle) time.sleep(dt * samples) trace = ADC.get_trace(handle) #FIXME: #Handle.freeADCHw(handle) t = np.arange(len(trace)) * dt return np.array([t, trace])
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(C.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 main(): parser = argparse.ArgumentParser(description='Reads (and plots) ADC trace') parser.add_argument('--adc', type=Coordinate.ADC, help='ADC Board Id', required=True) parser.add_argument('--ip', type=str, help='ADC Service IP', required=False) parser.add_argument('--port', type=int, help='ADC Service Port', required=False) parser.add_argument('--channel', type=lambda x: Coordinate.ChannelOnADC(int(x)), help="MUX", required=False, default=Coordinate.ChannelOnADC(0)) parser.add_argument('--samples', type=int, help='Number of samples to collect', required=True) parser.add_argument('--calibration', action='store_true', help='Try to apply calibration') parser.add_argument('--dump', action='store_true', help='Dump trace data to console') parser.add_argument('--plot', action='store_true', help='Plot trace data using matplotlib') args = parser.parse_args() init_logger() data = measure(args.adc, args.ip, args.port, args.channel, args.samples) if args.dump: dump(data) if args.plot: plot(data)
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 C.iter_all(C.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 C.iter_all(C.SynapseDriverOnHICANN): for row in C.iter_all(C.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(C.Enum(ii)) cfg.fg_biasn = 0 cfg.fg_bias = 0 fgs.setFGConfig(C.Enum(ii), cfg) for block in C.iter_all(C.FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_dllres, 275) fgs.setShared(block, HICANN.shared_parameter.V_ccas, 800)
def _BSS_set_hicann_sthal_params(_wafer, _hicann, gmax, gmax_div=1): fgs = _wafer[_hicann].floating_gates # set parameters influencing the synaptic strength for block in C.iter_all(C.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 C.iter_all(C.SynapseDriverOnHICANN): for row in C.iter_all(C.RowOnSynapseDriver): _wafer[_hicann].synapses[driver][row].set_gmax_div( C.left, gmax_div) _wafer[_hicann].synapses[driver][row].set_gmax_div( C.right, gmax_div) # don't change values below for ii in range(fgs.getNoProgrammingPasses()): cfg = fgs.getFGConfig(C.Enum(ii)) cfg.fg_biasn = 0 cfg.fg_bias = 0 fgs.setFGConfig(C.Enum(ii), cfg) for block in C.iter_all(C.FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_dllres, 275) fgs.setShared(block, HICANN.shared_parameter.V_ccas, 800)
def set_sthal_params(wafer, gmax, gmax_div): for hicann in wafer.getAllocatedHicannCoordinates(): fgs = wafer[hicann].floating_gates for ii in xrange(fgs.getNoProgrammingPasses()): cfg = fgs.getFGConfig(C.Enum(ii)) cfg.fg_biasn = 0 cfg.fg_bias = 0 fgs.setFGConfig(C.Enum(ii), cfg) for block in C.iter_all(C.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 block in C.iter_all(C.FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_dllres, 275) fgs.setShared(block, HICANN.shared_parameter.V_ccas, 800) for driver in C.iter_all(C.SynapseDriverOnHICANN): for row in C.iter_all(C.RowOnSynapseDriver): wafer[hicann].synapses[driver][row].set_gmax_div( C.left, gmax_div) wafer[hicann].synapses[driver][row].set_gmax_div( C.right, gmax_div)
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(C.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 set_denmem_quads(self, neuron, **kwargs): nquad = HICANN.NeuronQuad() for qq in range(Coordinate.QuadOnHICANN.end): HICANN.set_denmem_quad(self.h, Coordinate.QuadOnHICANN(qq), nquad) # All other neurons keep the default values nactive = nquad[neuron.toNeuronOnQuad()] for key, value in kwargs.iteritems(): getattr(nactive, key)(value) HICANN.set_denmem_quad(self.h, neuron.toQuadrantOnHICANN(), nquad)
def set_sthal_params(wafer, gmax, gmax_div): """ synaptic strength: gmax: 0 - 1023, strongest: 1023 gmax_div: 1 - 15, strongest: 1 """ # for all HICANNs in use for hicann in wafer.getAllocatedHicannCoordinates(): fgs = wafer[hicann].floating_gates # set parameters influencing the synaptic strength for block in C.iter_all(C.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 C.iter_all(C.SynapseDriverOnHICANN): for row in C.iter_all(C.RowOnSynapseDriver): wafer[hicann].synapses[driver][row].set_gmax_div( C.left, gmax_div) wafer[hicann].synapses[driver][row].set_gmax_div( C.right, gmax_div) # don't change values below for ii in xrange(fgs.getNoProgrammingPasses()): cfg = fgs.getFGConfig(C.Enum(ii)) cfg.fg_biasn = 0 cfg.fg_bias = 0 fgs.setFGConfig(C.Enum(ii), cfg) for block in C.iter_all(C.FGBlockOnHICANN): fgs.setShared(block, HICANN.shared_parameter.V_dllres, 275) fgs.setShared(block, HICANN.shared_parameter.V_ccas, 800)
def setup(self, timestep=1.0, min_delay=1.0, per_sim_params={}, **kwargs): setup_args = {'timestep': timestep, 'min_delay': min_delay} self._extra_config = per_sim_params if self.sim_name == BSS: #do extra setup for BrainScaleS wafer = per_sim_params.get("wafer", None) marocco = per_sim_params.get("marocco", PyMarocco()) if wafer is not None: sys.stdout.write("Specifying Wafer %d\n\n" % wafer) sys.stdout.flush() per_sim_params.pop('wafer') self.BSS_wafer = C.Wafer(int(wafer)) marocco.default_wafer = self.BSS_wafer self._wafer = WAL(wafer_id=wafer) runtime = Runtime(marocco.default_wafer) setup_args['marocco_runtime'] = runtime self.BSS_runtime = runtime calib_path = per_sim_params.get( "calib_path", "/wang/data/calibration/brainscales/wip") # "/wang/data/calibration/brainscales/current") marocco.calib_path = calib_path marocco.defects.path = marocco.calib_path # marocco.verification = PyMarocco.Skip # marocco.checkl1locking = PyMarocco.SkipCheck marocco.continue_despite_synapse_loss = True per_sim_params.pop('calib_path', None) setup_args['marocco'] = marocco self.marocco = marocco self.SYNAPSE_DECODER_DISABLED_SYNAPSE = HICANN.SynapseDecoder(1) for k in per_sim_params: setup_args[k] = per_sim_params[k] self._setup_args = setup_args self._sim.setup(**setup_args) # sys.exit(0) if self.sim_name == BSS: self._BSS_set_sthal_params(gmax=1023, gmax_div=1)
def setup_marocco(wafer=37): """Setup hardwarm mapping on a wafer. Defaults to 37""" marocco = PyMarocco() marocco.neuron_placement.default_neuron_size(4) marocco.neuron_placement.minimize_number_of_sending_repeaters(False) marocco.merger_routing.strategy(marocco.merger_routing.one_to_one) marocco.bkg_gen_isi = 125 marocco.pll_freq = 125e6 marocco.backend = PyMarocco.Hardware marocco.calib_backend = PyMarocco.XML marocco.defects.path = marocco.calib_path = "/wang/data/calibration/brainscales/default-2017-09-26-1" marocco.defects.backend = Defects.XML marocco.default_wafer = C.Wafer(int(os.environ.get("WAFER", wafer))) marocco.param_trafo.use_big_capacitors = True marocco.input_placement.consider_firing_rate(True) marocco.input_placement.bandwidth_utilization(0.8) return marocco
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(C.Enum(167)) target_hicann = C.HICANNOnWafer(C.Enum(240)) self.marocco.manual_placement.on_hicann(source, source_hicann) self.marocco.manual_placement.on_hicann(target, target_hicann) allowed_hicanns = [206] + range(167, 171) + range(240, 243) wafer = self.marocco.default_wafer for hicann in C.iter_all(C.HICANNOnWafer): if hicann.id().value() in allowed_hicanns: continue self.marocco.defects.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())
neuron_parameters = { 'cm': 0.2, 'v_reset': -70., 'v_rest': -20., 'v_thresh': -10, 'e_rev_I': -100., 'e_rev_E': 60., 'tau_m': 20., 'tau_refrac': 0.1, 'tau_syn_E': 5., 'tau_syn_I': 5., } marocco = PyMarocco() marocco.default_wafer = C.Wafer(int(os.environ.get("WAFER", 33))) runtime = Runtime(marocco.default_wafer) pynn.setup(marocco=marocco, marocco_runtime=runtime) # ——— set up network —————————————————————————————————————————————————————————— pop = pynn.Population(1, pynn.IF_cond_exp, neuron_parameters) pop.record() pop.record_v() hicann = C.HICANNOnWafer(C.Enum(297)) marocco.manual_placement.on_hicann(pop, hicann) connector = pynn.AllToAllConnector(weights=1)
'tau_syn_I': 5., } marocco = PyMarocco() marocco.neuron_placement.default_neuron_size(4) marocco.neuron_placement.minimize_number_of_sending_repeaters(False) marocco.merger_routing.strategy(marocco.merger_routing.one_to_one) marocco.bkg_gen_isi = 125 marocco.pll_freq = 125e6 marocco.backend = PyMarocco.Hardware marocco.calib_backend = PyMarocco.XML marocco.defects.path = marocco.calib_path = "/wang/data/calibration/ITL_2016" marocco.defects.backend = Defects.XML marocco.default_wafer = C.Wafer(33) marocco.param_trafo.use_big_capacitors = True marocco.input_placement.consider_firing_rate(True) marocco.input_placement.bandwidth_utilization(0.8) runtime = Runtime(marocco.default_wafer) pynn.setup(marocco=marocco, marocco_runtime=runtime) # ——— set up network —————————————————————————————————————————————————————————— pop = pynn.Population(1, pynn.IF_cond_exp, neuron_parameters) pop.record() pop.record_v() hicann = C.HICANNOnWafer(C.Enum(367))
def test_spike_input(self): self.marocco.wafer_cfg = os.path.join(self.temporary_directory, "wafer_cfg.bin") pynn.setup(marocco=self.marocco) target = pynn.Population(1, pynn.IF_cond_exp, {}) params = [[1., 2., 3.], [4., 3., 2.]] sources = [ pynn.Population(1, pynn.SpikeSourceArray, {'spike_times': times}) for times in params ] for source in sources: pynn.Projection(source, target, pynn.AllToAllConnector(weights=0.004)) pynn.run(1000.) results = self.load_results() self.assertEqual(0, len(results.spike_times.get(target[0]))) for spike_times, pop in zip(params, sources): self.assertSequenceEqual(spike_times, results.spike_times.get(pop[0])) spike_times.append(5.) results.spike_times.add(pop[0], 5.) self.assertSequenceEqual(spike_times, results.spike_times.get(pop[0])) spike_times.extend([6., 7.]) results.spike_times.add(pop[0], [6., 7.]) self.assertSequenceEqual(spike_times, results.spike_times.get(pop[0])) spike_times = [42., 123.] results.spike_times.set(pop[0], spike_times) self.assertSequenceEqual(spike_times, results.spike_times.get(pop[0])) params[-1][:] = [] results.spike_times.clear(pop[0]) self.assertEqual(0, len(results.spike_times.get(pop[0]))) # Check that modifications are reflected in sthal config container results.save(self.marocco.persist, overwrite=True) self.marocco.skip_mapping = True pynn.run(1000.) import pysthal wafer_cfg = pysthal.Wafer() wafer_cfg.load(self.marocco.wafer_cfg) for spike_times, pop in zip(params, sources): item, = results.placement.find(pop[0]) address = item.address() l1_address = address.toL1Address() hicann_cfg = wafer_cfg[address.toHICANNOnWafer()] hicann_cfg.sortSpikes() raw_spikes = hicann_cfg.sentSpikes( C.GbitLinkOnHICANN(address.toDNCMergerOnHICANN())) raw_spikes = raw_spikes[raw_spikes[:, 1] == l1_address.value(), 0] self.assertEqual(len(spike_times), len(raw_spikes)) pynn.end()
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)
def get_hicanns(center_hicann, n_kenyon, seed=1, max_dist=3, n_per_pop=4, manual=False): if manual: f = open("black_list_stats.txt", "a+") f.write(u"%s, -*-\n" % seed) f.close() np.random.seed(seed) ID, ROW, COL = range(3) w = WAL() hood = w.get_neighbours(center_hicann, max_dist=max_dist) ids = [] for r in hood: for c in hood[r]: ids.append(hood[r][c][ID]) pprint(hood) print(ids) pops = [ 'antenna', 'decision', 'feedback', 'exciter', # 'tick', 'exciter_src', # 'kenyon', ] ### ideal config is in a 3x3 grid places = {} blacklist = [] # ## blacklist = [73, 76, 99, 17, 18, 19, 20, 21, 37, 47, 167, 56, 6, 5, 7, 80, 100, 14] used = [] + blacklist k_places = [] for i in range(n_kenyon): avail = np.setdiff1d(ids, used) np.random.choice(avail, size=n_kenyon, replace=False) hicann_id = np.random.choice(avail, size=n_per_pop) hicann = [C.HICANNOnWafer(C.Enum(i)) for i in hicann_id] for i in hicann_id: used.append(i) k_places.append(hicann) places['kenyon'] = k_places for p in pops: avail = np.setdiff1d(ids, used) hicann_id = np.random.choice(avail, size=n_per_pop) hicann = [C.HICANNOnWafer(C.Enum(i)) for i in hicann_id] places[p] = hicann for i in hicann_id: used.append(i) for k in sorted(places): for p in places[k]: try: sys.stdout.write("{},".format(int(p.id()))) except: for q in p: sys.stdout.write("{},".format(int(q.id()))) print() print(places) else: places = { 'antenna': None, 'kenyon': [None] * n_kenyon, 'decision': None, 'tick': None, 'feedback': None, 'exciter src': None, 'exciter': None, } return places
proxy.decoder = SYNAPSE_DECODER_DISABLED_SYNAPSE else: proxy.weight = HICANN.SynapseWeight(digital_w) proxy.decoder = original_decoders[syn] return out_mtx ############################################################################ ############################################################################ ############################################################################ wafer = int(os.environ.get("WAFER", 33)) marocco = PyMarocco() marocco.backend = PyMarocco.Hardware marocco.default_wafer = C.Wafer(wafer) runtime = Runtime(marocco.default_wafer) # calib_path = "/wang/data/calibration/brainscales/WIP-2018-09-18" # marocco.calib_path = calib_path # marocco.defects.path = marocco.calib_path marocco.verification = PyMarocco.Skip marocco.checkl1locking = PyMarocco.SkipCheck marocco.continue_despite_synapse_loss = True SYNAPSE_DECODER_DISABLED_SYNAPSE = HICANN.SynapseDecoder(1) ### ====================== NETWORK CONSTRUCTION =========================== ### sim.setup(timestep=1.0, min_delay=1.0, marocco=marocco, marocco_runtime=runtime)
def setUp(self): if 'nose' in sys.modules.keys(): # ugly hack to support nose-based execution... self.FPGA_IP = '0.0.0.0' self.PMU_IP = '0.0.0.0' self.HICANN = 0 self.DNC = 1 self.FPGA = 0 self.LOGLEVEL = 2 self.ON_WAFER = False self.WAFER = 0 self.USE_SCHERIFF = False from pyhalbe import Handle, Coordinate, HICANN, FPGA, Coordinate, Debug # The module pyhalbe.apicheck wraps pyhalbe for hardware-less # apichecks. It will be enabled only if the environment variable # PYHALBE_API_CHECK is set to true. The attribute "enabled" will be set # accordingly. KHS. import pyhalbe_apicheck as apicheck Enum = Coordinate.Enum highspeed = True arq = True hicann_num = 1 fpga_ip = Coordinate.IPv4.from_string(self.FPGA_IP) pmu_ip = Coordinate.IPv4.from_string(self.pmu_IP) if self.LOGLEVEL >= 0: Debug.change_loglevel(self.LOGLEVEL) self.dnc = Coordinate.DNCOnFPGA(Enum(self.DNC)) self.hicann = Coordinate.HICANNOnDNC(Enum(self.HICANN)) self.f = Coordinate.FPGAGlobal(Enum(self.FPGA), Coordinate.Wafer(Enum(self.WAFER))) self.fpga = Handle.createFPGAHw(self.f, fpga_ip, self.dnc, self.ON_WAFER, hicann_num, self.KINTEX, pmu_ip) if self.USE_SCHERIFF: self.fpga.enableScheriff() self.addCleanup(Handle.freeFPGAHw, self.fpga) self.h = self.fpga.get(self.dnc, self.hicann) if self.ON_WAFER: self.h0 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(0))) self.h1 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(1))) self.h2 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(2))) self.h3 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(3))) self.h4 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(4))) self.h5 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(5))) self.h6 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(6))) self.h7 = self.fpga.get(self.dnc, Coordinate.HICANNOnDNC(Enum(7))) self.apicheck = apicheck.enabled() if apicheck.enabled(): # equals PYHALBE_API_CHECK # With hardware access disabled pyhalbe functions return anything # but the expected, i.e. all unittest assertions naturally fail. # I.e. for a functional API check they have to be disabled. KHS. apicheck.monkeyPatch( self, 'assert' ) # disables all functions in self that start with "assert" # ECM says: this should be part of the tests... automatic resets during construction isn't very "standalone" # OR it is necessary and in this case it should be a member function and documented somehow. # FPGA reset FPGA.reset(self.fpga) HICANN.init(self.h, False) if self.ON_WAFER: HICANN.init(self.h0, False) HICANN.init(self.h1, False) HICANN.init(self.h2, False) HICANN.init(self.h3, False) HICANN.init(self.h4, False) HICANN.init(self.h5, False) HICANN.init(self.h6, False) HICANN.init(self.h7, False)
def test_array_operators(self): from pyhalbe import HICANN, Coordinate quad = HICANN.NeuronQuad() neuron = HICANN.Neuron() neuron.enable_aout(True) quad[Coordinate.NeuronOnQuad(Coordinate.Enum(0))] = neuron self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(0))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(1))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(2))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(3))].enable_aout()) quad[Coordinate.NeuronOnQuad(Coordinate.Enum(1))].enable_aout(True) self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(0))].enable_aout()) self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(1))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(2))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(3))].enable_aout()) x = quad[Coordinate.NeuronOnQuad(Coordinate.Enum(2))] x.enable_aout(True) self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(0))].enable_aout()) self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(1))].enable_aout()) self.assertTrue(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(2))].enable_aout()) self.assertFalse(quad[Coordinate.NeuronOnQuad( Coordinate.Enum(3))].enable_aout())