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_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_addWithNeuronSize(self): """tests manual placement with custom neuron size""" marocco = PyMarocco() useOne = HICANNOnWafer(Enum(276)) useTwo = HICANNOnWafer(Enum(277)) use = [useOne, useTwo] # place a population to a single HICANN (scalar parameter) pop = pynn.Population(10, pynn.IF_cond_exp, {}) marocco.manual_placement.on_hicann(pop, useOne, 8) # place a population onto multiple HICANNs pop = pynn.Population(10, pynn.IF_cond_exp, {}) marocco.manual_placement.on_hicann(pop, use, 4) # only set the neuron size for the population, but no HICANN. marocco.manual_placement.with_size(pop, 12) self.assertRaises(ValueError, marocco.manual_placement.with_size, pop, 1)
def __init__(self, xmlfile, coordinate): self.xmlfile = xmlfile self.coordinate = coordinate if self.coordinate.toNeuronOnQuad().x() != left: raise Exception("Simulator supports only left denmem") # find (horizontally) neighboring denmem :) self.neighbor = None if coordinate.toNeuronOnQuad().x() == left: self.neighbor = NeuronOnHICANN(coordinate.toQuadrantOnHICANN(), NeuronOnQuad(right, coordinate.toNeuronOnQuad().y())) #elif coordinate.toNeuronOnQuad().x() == right: # self.neighbor = NeuronOnHICANN(coordinate.toQuadrantOnHICANN(), NeuronOnQuad(left, coordinate.toNeuronOnQuad().y())) else: raise Exception("WARG") self.neighbor = NeuronGlobal(self.neighbor, self.coordinate.hicann()) self.neighbor_fgblock = FGBlockOnHICANN(Enum(int(self.coordinate.toNeuronFGBlock().id())+1)) self.tree = etree.parse(self.xmlfile) # storage of parameters -> to be used for transformation self.out = dict() # output: denmem simulator compatible data dictionary #self.json_out = { # 'voltages': { # 'neuron': {}, # 'synapses0': {}, # 'synapses1': {}, # 'syndrv_synpart': {}, # 'syndrv_synctrl': {} # }, # 'currents': { # 'neuron': {}, # 'synapses0': {}, # 'synapses1': {}, # 'syndrv_synpart': {}, # 'syndrv_synctrl': {} # } #} self.json_out = copy.deepcopy(somedefault_values)
def main(args): ip = IPv4.from_string(args.ip) on_wafer = False dnc = DNCOnFPGA(Enum(args.dnc)) f = Coordinate.FPGAGlobal(Enum(0)) fpga = Handle.FPGA(f, ip, dnc, on_wafer) hicann = fpga.get(dnc, HICANNOnDNC(Enum(args.hicann))) reset(hicann) init(hicann, True) # write FG Blocks first, before any topology set_fg_values(hicann, FGControl()) # configure backgroud generator 7 for stimulation of Neuron0 bg = BackgroundGeneratorArray() bg[7].enable(True) bg[7].random(False) bg[7].seed(200) bg[7].period(1500) bg[7].address(L1Address(0)) set_background_generator(hicann, bg) # write default Neuron config set_neuron_config(hicann, NeuronConfig()) neurons = [ (NeuronOnHICANN(Enum(0)), L1Address(0)), (NeuronOnHICANN(Enum(1)), L1Address(32)), ] nquad = NeuronQuad() for nrn, addr in neurons: neu = nquad[nrn.toNeuronOnQuad()] neu.address(addr) neu.activate_firing(True) neu.enable_spl1_output(True) neu.enable_aout(True) set_denmem_quad(hicann, neurons[0][0].toQuadOnHICANN(), nquad) # config analog outputs to observe neurons aout = Analog() for idx, nrn in enumerate(neurons): aout.enable(AnalogOnHICANN(idx)) if int(nrn[0].x()) % 2 == 0: #even aout.set_membrane_top_even(AnalogOnHICANN(idx)) else: aout.set_membrane_top_odd(AnalogOnHICANN(idx)) set_analog(hicann, aout) # L1 Topology dncmerger = DNCMergerLine() for mm in map(DNCMergerOnHICANN, range(8)): dncmerger[mm].config = DNCMerger.RIGHT_ONLY set_dnc_merger(hicann, dncmerger) set_merger_tree(hicann, MergerTree()) set_phase(hicann, 0) # write default RepeatBlocks for ii in map(RepeaterBlockOnHICANN, map(Enum, range(6))): set_repeater_block(hicann, ii, RepeaterBlock()) cb = Crossbar() sw = SynapseSwitch() paths = [ (SendingRepeaterOnHICANN(0), VLineOnHICANN(28), SynapseSwitchRowOnHICANN(Y(111), LEFT), 0), # BG7 -> neuron0 (SendingRepeaterOnHICANN(7), VLineOnHICANN(0), SynapseSwitchRowOnHICANN(Y(97), LEFT), 1) ] # neuron0 -> neuron1 for repeater, vline, row, target_nrn in paths: sr = HorizontalRepeater() sr.setOutput(RIGHT) set_repeater(hicann, repeater, sr) # crossbar switches cb.set(vline, repeater.line(), True) switches = cb.get_row(repeater.line(), row.toSideHorizontal()) set_crossbar_switch_row(hicann, repeater.line(), row.toSideHorizontal(), switches) # synapse driver switches sw.set(vline, row.line(), True) set_syndriver_switch_row(hicann, row, sw.get_row(row)) # Synapse Driver driver = SynapseDriver() driver.set_l1() rconfig = RowConfig() rconfig.set_gmax_div(LEFT, 1) rconfig.set_gmax_div(RIGHT, 1) rconfig.set_syn_in(LEFT, 1) driver[TOP] = driver[BOTTOM] = rconfig set_synapse_driver(hicann, row.toSynapseDriverOnHICANN(), driver) # Synapses nrn = int(neurons[target_nrn][0].x()) # synapse decoders decoders = DecoderDoubleRow() for ii in range(2): for jj in range(256): decoders[ii][jj] = 0xf # blocks L1Addres(0) decoders[ii][nrn] = 0 set_decoder_double_row(hicann, row.toSynapseDriverOnHICANN(), decoders) # synapse weights weights = WeightRow() weights[nrn] = 15 set_weights_row(hicann, SynapseRowOnHICANN(row.toSynapseDriverOnHICANN(), TOP), weights) set_weights_row( hicann, SynapseRowOnHICANN(row.toSynapseDriverOnHICANN(), BOTTOM), weights)
def extract_fg_values(self): ncolumns = 24 nrows = 128 if not self.out.has_key('fg_shared'): self.out['fg_shared'] = [None, None] for hicann, parameters in self.get_all_functions('set_fg_values'): assert len(parameters) in [1, 2] fgc = None fgb_left = None fgb_right = None # FGCtrl-based overload if len(parameters) == 1: fgc = self.coordinate.toNeuronFGBlock() fgb_left = parameters[0].xpath('blocks/elems/item')[int(fgc.id())] fgb_right = parameters[0].xpath('blocks/elems/item')[int(self.neighbor_fgblock.id())] # FGBlockOnHICANN + FGBlock data overload elif len(parameters) == 2: fgc = FGBlockOnHICANN(Enum(int(self.recursive_dict(parameters[0])['e']))) if fgc == self.coordinate.toNeuronFGBlock(): fgb_left = parameters[1] elif fgc == self.neighbor_fgblock: fgb_right = parameters[1] else: continue shared_left = None neuron = None if fgb_left is not None: # neuron is on the left :) shared_left = array([int(x) for x in fgb_left.xpath('shared/elems/item/value/text()')]).reshape(ncolumns) neuron = array([int(x) for x in fgb_left.xpath('neuron/elems/item/elems/item/value/text()')]).reshape((nrows, ncolumns)) if fgb_right is not None: shared_right = array([int(x) for x in fgb_right.xpath('shared/elems/item/value/text()')]).reshape(ncolumns) if shared_left is not None: self.out['fg_shared'][int(left)] = [int(x) for x in shared_left] if shared_right is not None: self.out['fg_shared'][int(right)] = [int(x) for x in shared_right] self.out['fg_neuron'] = [ self.values_to_int(neuron[self.coordinate.toNeuronOnFGBlock()]), # left self.values_to_int(neuron[self.neighbor.toNeuronOnFGBlock()]) ] # right mydictupdates = copy.deepcopy(emptyjson) # translate shared FG parameters for key, data in fg_name_lut['shared'].items(): HALbeType = data[0] leftOrRight = data[1] sectionName = data[2] valueWidth = data[3] if leftOrRight == left: mydictupdates[sectionName]['neuron'][key] = { 'width': valueWidth, 'values': valueWidth * [self.out['fg_shared'][int(leftOrRight)][FGBlock.getSharedHardwareIdx(self.coordinate.toNeuronFGBlock(), HALbeType)]] } else: mydictupdates[sectionName]['neuron'][key] = { 'width': valueWidth, 'values': valueWidth * [self.out['fg_shared'][int(leftOrRight)][FGBlock.getSharedHardwareIdx(self.neighbor_fgblock, HALbeType)]] } # translate neuron FG parameters for key, data in fg_name_lut['neuron'].items(): HALbeType = data[0] sectionName = data[1] valueWidth = data[2] mydictupdates[sectionName]['neuron'][key] = { 'width': valueWidth, 'values': [ self.out['fg_neuron'][int(left) ][FGBlock.getNeuronHardwareIdx(self.coordinate.toNeuronFGBlock(), HALbeType)], self.out['fg_neuron'][int(right)][FGBlock.getNeuronHardwareIdx(self.coordinate.toNeuronFGBlock(), HALbeType)] ] } #if str(key) == 'Vsyni': #print "jap" #print mydictupdates # convert FG DAC values to voltages/currents for k, v in mydictupdates['voltages'].items(): for k2, v2 in v.items(): v2['values'] = self.dac_to_volt(v2['values']) for k, v in mydictupdates['currents'].items(): for k2, v2 in v.items(): v2['values'] = self.dac_to_current(v2['values']) #print 'zzz', mydictupdates #print mydictupdates['voltages']['neuron'].keys() merge(self.json_out, mydictupdates)
'width': 4, 'values': self.out['syn_weights'+str(i)]['db'] } merge(self.json_out, mydictupdates) if __name__ == '__main__': import argparse parser = argparse.ArgumentParser() parser.add_argument('-i', '--input-file', help='Specify HALbe XML input file') parser.add_argument('-o', '--output-file', help='Specify SimDenmem output file') parser.add_argument('-N', '--neuron', default=0, type=int, help='Specify NeuronOnHICANN for simulation') parser.add_argument('-H', '--hicann', default=216, type=int, help='Specify HICANNGlobal for simulation') args = parser.parse_args() inf = args.input_file outf = args.output_file nrn = args.neuron # non-empty source file assert os.path.exists(inf) and os.stat(inf).st_size != 0 # empty target file #assert not os.path.exists(outf) or os.stat(outf).st_size == 0 ng = NeuronGlobal(NeuronOnHICANN(Enum(args.neuron)), HICANNGlobal(Enum(args.hicann))) sim = HALbeXML2Sim2Denmem(inf, ng) sim.extract() sim.write(outf)
# This test checks API properties of ManualPlacement::on_hicann import pyhmf as pynn import pyhalbe, pymarocco from pymarocco import PyMarocco from pyhalbe.Coordinate import HICANNOnWafer, Enum marocco = PyMarocco() useOne = HICANNOnWafer(Enum(276)) useTwo = HICANNOnWafer(Enum(277)) use = [useOne, useTwo] use_tpl = tuple(use) # place a population to a single HICANN (scalar parameter) pop = pynn.Population(10, pynn.IF_cond_exp, {}) marocco.manual_placement.on_hicann(pop, useOne) # place a population onto multiple HICANNs # using a Python list() pop = pynn.Population(10, pynn.IF_cond_exp, {}) marocco.manual_placement.on_hicann(pop, use) # place a population onto multiple HICANNs # using a Python tuple() pop = pynn.Population(10, pynn.IF_cond_exp, {}) marocco.manual_placement.on_hicann(pop, use_tpl)
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)