def test_get_denmems(self): pop_size = 2 for neuron_size in [4, 8, 12, 16, 32]: self.marocco.neuron_placement.default_neuron_size(neuron_size) pynn.setup(marocco=self.marocco) target = pynn.Population(pop_size, pynn.IF_cond_exp, {}) populations = [target] for i in range(3): p1 = pynn.Population(pop_size, pynn.SpikeSourceArray, {'spike_times': [1.]}) p2 = pynn.Population(pop_size, pynn.IF_cond_exp, {}) pynn.Projection(p1, target, pynn.OneToOneConnector(weights=0.004)) pynn.Projection(p2, target, pynn.OneToOneConnector(weights=0.004)) populations.append(p2) pynn.run(0) pynn.end() mapstats = self.marocco.getStats() results = Marocco.from_file(self.marocco.persist) for pop in populations: for nrn in range(pop_size): for item in results.placement.find(pop[nrn]): self.assertFalse(item.logical_neuron().is_external()) self.assertEqual(neuron_size, item.logical_neuron().size())
def helper_test_mapping(self, pop): results = Marocco.from_file(self.marocco.persist) for n in range(len(pop)): items = list(results.placement.find(pop[n])) if not items: self.fail("Neuron {} of population {} not placed".format( n, pop.euter_id())) for item in items: self.assertEqual(item.neuron_index(), n) self.assertEqual(pop.celltype == pynn.SpikeSourceArray, item.logical_neuron().is_external())
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())
def main(): app = QtGui.QApplication(sys.argv) parser = argparse.ArgumentParser() parser.add_argument('file', type=valid_file, help='marocco results file') parser.add_argument('-o', type=str, default=None, help='write rendering to file, e.g.: *.png, *.svg') parser.add_argument('--switches', action='store_true', help='draw switches (slows down rendering)') parser.add_argument('--l1routes', action='store_true', help='load pickled vector of l1routes from file') args = parser.parse_args() scene = QtGui.QGraphicsScene() wafer = Wafer(scene, args.switches) if args.l1routes: import pickle with open(args.file) as f: obj = pickle.load(f) if not isinstance(obj, list): obj = [obj] wafer.draw_routes(obj) else: from pymarocco.results import Marocco wafer.draw(Marocco.from_file(args.file)) if args.o: save_figure(scene, args.o) else: window = MainWindow(scene) window.show() sys.exit(app.exec_())
def test_basic(self): """ tests the routing and parameter trafo of a IF_multicond_exp neuron with 4 different synaptic input settings. For 4 synaptic targets and hardware neuron size 4, the mapping of synapse types is as follows: Denmem: | 0 | 1 | Synapse Type: |0 1|2 3| (left and right input) Build a minimal network with 1 neuron and 4 spike sources each connecting to different synaptic target on the neuron. Then check that the configuration of the synapse driver and synapses is as expected. Furthermore, check that the different parameters for e_rev and tau_syn are correctly transformed by getting the FG values (qualitatively). """ marocco = pymarocco.PyMarocco() marocco.backend = pymarocco.PyMarocco.Without marocco.calib_backend = pymarocco.PyMarocco.CalibBackend.Default marocco.defects.backend = pymarocco.Defects.Backend.Without marocco.neuron_placement.default_neuron_size(4) marocco.wafer_cfg = os.path.join(self.temporary_directory, "wafer.bin") marocco.persist = os.path.join(self.temporary_directory, "results.bin") used_hicann = HICANNGlobal(Enum(0)) pynn.setup(marocco=marocco) p1 = pynn.Population(1, pynn.IF_multicond_exp) # we use 4 different time constants and reversal potentials p1.set('e_rev', [0., -10, -80, -100]) p1.set('tau_syn', [2, 3, 4, 5]) # place to a certain HICANN to be able to extract config data afterwards topleft = NeuronOnWafer(NeuronOnHICANN(X(0), Y(0)), used_hicann) logical_neuron = LogicalNeuron.rectangular(topleft, size=4) marocco.manual_placement.on_neuron(p1, logical_neuron) s1 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) s2 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) s3 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) s4 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) prj1 = pynn.Projection(s1, p1, pynn.OneToOneConnector(weights=0.01), target="0") prj2 = pynn.Projection(s2, p1, pynn.OneToOneConnector(weights=0.01), target="1") prj3 = pynn.Projection(s3, p1, pynn.OneToOneConnector(weights=0.01), target="2") prj4 = pynn.Projection(s4, p1, pynn.OneToOneConnector(weights=0.01), target="3") p1.record() pynn.run(1.) h = debug_config.load_hicann_cfg(marocco.wafer_cfg, used_hicann) # routing config active_drivers = [] driver_c = None for driver in iter_all(SynapseDriverOnHICANN): drv_cfg = h.synapses[driver] if drv_cfg.is_enabled(): active_drivers.append(drv_cfg) driver_c = driver assert len(active_drivers) == 1 act_drv = active_drivers[0] # two different synaptic input sides are used on the synapse driver syn_input_top = debug_config.get_syn_in_side( act_drv[RowOnSynapseDriver(top)]) syn_input_bot = debug_config.get_syn_in_side( act_drv[RowOnSynapseDriver(bottom)]) self.assertNotEqual(syn_input_top, syn_input_bot) # assumed column and input side: exptected_mapping = [(s1, SynapseColumnOnHICANN(0), left), (s2, SynapseColumnOnHICANN(0), right), (s3, SynapseColumnOnHICANN(1), left), (s4, SynapseColumnOnHICANN(1), right)] results = Marocco.from_file(marocco.persist) for (src, col, side) in exptected_mapping: items = list(results.placement.find(src[0])) self.assertEqual(1, len(items)) item = items[0] addr = item.address().toL1Address() syns = debug_config.find_synapses(h.synapses, driver_c, addr) self.assertEqual(1, len(syns)) syn = syns[0] # check synapse column self.assertEqual(syn.toSynapseColumnOnHICANN(), col) # check synaptic input side row_addr = syn.toSynapseRowOnHICANN() self.assertEqual( debug_config.get_syn_in_side( act_drv[row_addr.toRowOnSynapseDriver()]), side) # FG values nrn_left = NeuronOnHICANN(X(0), Y(0)) nrn_right = NeuronOnHICANN(X(1), Y(0)) fgs = h.floating_gates # e_rev params are montonic decreasing E1 = fgs.getNeuron(nrn_left, nrn_param.E_synx) E2 = fgs.getNeuron(nrn_left, nrn_param.E_syni) E3 = fgs.getNeuron(nrn_right, nrn_param.E_synx) E4 = fgs.getNeuron(nrn_right, nrn_param.E_syni) E = [E1, E2, E3, E4] for k, l in zip(E, E[1:]): self.assertGreater(k, l) # tau_syn params are montonic increasing T1 = fgs.getNeuron(nrn_left, nrn_param.V_syntcx) T2 = fgs.getNeuron(nrn_left, nrn_param.V_syntci) T3 = fgs.getNeuron(nrn_right, nrn_param.V_syntcx) T4 = fgs.getNeuron(nrn_right, nrn_param.V_syntci) T = [T1, T2, T3, T4] # HICANN V4: The lower the DAC-Value, the higher the time constant for k, l in zip(T, T[1:]): self.assertGreater(k, l)
import pyhmf as pynn import Coordinate as C from pymarocco import PyMarocco, Defects from pymarocco.results import Marocco import pylogging for domain in ["Calibtic", "marocco"]: pylogging.set_loglevel(pylogging.get(domain), pylogging.LogLevel.INFO) marocco = PyMarocco() marocco.calib_backend = PyMarocco.CalibBackend.Default marocco.defects.backend = Defects.Backend.None marocco.neuron_placement.skip_hicanns_without_neuron_blacklisting(False) marocco.persist = "results.xml.gz" pynn.setup(marocco = marocco) pop = pynn.Population(1, pynn.IF_cond_exp) marocco.manual_placement.on_hicann(pop, C.HICANNOnWafer(C.X(5), C.Y(5)), 4) pynn.run(10) pynn.end() results = Marocco.from_file(marocco.persist) for neuron in pop: for item in results.placement.find(neuron): for denmem in item.logical_neuron(): print denmem
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)
def load_results(self): self.assertTrue(os.path.exists(self.marocco.persist)) return Marocco.from_file(self.marocco.persist)
def test_basic(self): """ tests whether synapses with short term plasticity are routed correctly. Build a minimal network with 1 neuron and 3 spike sources each connecting to with a different STP setting (depression, facilitation, static) to the neuron. Then check that the 3 synapses are routed via 3 different synaspe drivers and that STP mode of the synapse drivers is as expected. """ marocco = pymarocco.PyMarocco() marocco.backend = pymarocco.PyMarocco.None marocco.neuron_placement.default_neuron_size(4) marocco.wafer_cfg = os.path.join(self.temporary_directory, "wafer.bin") marocco.persist = os.path.join(self.temporary_directory, "results.bin") used_hicann = HICANNGlobal(Enum(0)) pynn.setup(marocco=marocco) p1 = pynn.Population(1, pynn.IF_cond_exp) # place to a certain HICANN to be able to extract config data afterwards marocco.manual_placement.on_hicann(p1, used_hicann) s1 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) s2 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) s3 = pynn.Population(1, pynn.SpikeSourcePoisson, {'rate': 5.}) depression = pynn.SynapseDynamics(fast=pynn.TsodyksMarkramMechanism( U=0.4, tau_rec=200., tau_facil=0.)) facilitation = pynn.SynapseDynamics(fast=pynn.TsodyksMarkramMechanism( U=0.4, tau_rec=0., tau_facil=200.)) static = None prj1 = pynn.Projection(s1, p1, pynn.OneToOneConnector(weights=0.05), synapse_dynamics=depression, target="excitatory") prj2 = pynn.Projection(s2, p1, pynn.OneToOneConnector(weights=0.05), synapse_dynamics=facilitation, target="excitatory") prj3 = pynn.Projection(s3, p1, pynn.OneToOneConnector(weights=0.05), synapse_dynamics=static, target="excitatory") p1.record() pynn.run(1.) h = debug_config.load_hicann_cfg(marocco.wafer_cfg, used_hicann) # There should be 3 active drivers with 3 different STP modes drivers = {} num_active_drivers = 0 for driver in iter_all(SynapseDriverOnHICANN): drv_cfg = h.synapses[driver] if drv_cfg.is_enabled(): num_active_drivers += 1 if drv_cfg.is_stf(): drivers['facilitation'] = driver elif drv_cfg.is_std(): drivers['depression'] = driver else: drivers['static'] = driver self.assertEqual(num_active_drivers, 3) self.assertEqual(len(drivers), 3) results = Marocco.from_file(marocco.persist) # check that synapses are on the drivers with the correct mode for src, mode in [(s1, 'depression'), (s2, 'facilitation'), (s3, 'static')]: items = list(results.placement.find(src[0])) self.assertEqual(1, len(items)) item = items[0] addr = item.address().toL1Address() syns = debug_config.find_synapses(h.synapses, drivers[mode], addr) self.assertEqual(len(syns), 1) # the addr of the source should be found once
def run_mapping(calib_dir, output_dir, wafer, hicann, skip_neurons, params): """ :type hicann: HICANNOnWafer :param params: dictionary containing neuron parameters :param skip_neurons: number of non-functional dummy neurons to insert """ from pymarocco import PyMarocco from pymarocco.results import Marocco from pymarocco.coordinates import BioNeuron import pyhmf as pynn import pysthal logger = setup_logger() marocco = PyMarocco() marocco.neuron_placement.default_neuron_size( utils.get_nested(params, "neuron.size", default=4)) marocco.neuron_placement.restrict_rightmost_neuron_blocks(True) marocco.neuron_placement.minimize_number_of_sending_repeaters(False) marocco.backend = PyMarocco.None marocco.calib_backend = PyMarocco.XML marocco.calib_path = calib_dir marocco.param_trafo.use_big_capacitors = False marocco.persist = os.path.join(output_dir, "marocco.xml.gz") marocco.wafer_cfg = os.path.join(output_dir, "wafer_cfg.bin") marocco.default_wafer = wafer # FIXME: remove? marocco.param_trafo.alpha_v = 1000.0 marocco.param_trafo.shift_v = 0.0 pynn.setup(marocco=marocco) synaptic_input = {} for input_type, input_params in params["synaptic_input"].iteritems(): if not utils.get_nested(input_params, "enabled", default=True): logger.info( "skipping disabled {!r} synaptic input".format(input_type)) continue spike_times = utils.get_nested(input_params, "spike_times", default=None) if spike_times: start = spike_times["start"] stop = spike_times["stop"] step = spike_times["step"] spike_times = np.arange(start, stop, step) input_pop_model = pynn.SpikeSourceArray input_pop_params = {"spike_times": spike_times} else: raise NotImplementedError( "unknown config for {!r} synaptic input".format(input_type)) logger.info( ("{!r} synaptic input will come from " "{} with parameters {!r}").format(input_type, input_pop_model.__name__, input_pop_params)) synaptic_input[input_type] = pynn.Population(1, input_pop_model, input_pop_params) neuron_params = utils.get_nested(params, "neuron.parameters") neuron_model = getattr( pynn, utils.get_nested(params, "neuron.model", default="IF_cond_exp")) logger.info("target population is {} neuron with parameters {!r}".format( neuron_model.__name__, neuron_params)) # Force marocco to give us a different neuron by inserting # `Neuron_Number - 1` dummy neurons. populations = [] for ii in range(0, skip_neurons + 1): populations.append(pynn.Population(1, neuron_model, neuron_params)) marocco.manual_placement.on_hicann(populations[-1], hicann) target_pop = populations[-1] for input_type, input_pop in synaptic_input.iteritems(): multiplicity = utils.get_nested(params, "synaptic_input", input_type, "multiplicity", default=1) assert multiplicity >= 1 weight = utils.get_nested(params, "synaptic_input", input_type, "weight") con = pynn.AllToAllConnector(weights=weight) logger.info(("connecting {!r} synaptic input " "to target population with weight {} " "via {} projections").format(input_type, weight, multiplicity)) for _ in xrange(multiplicity): pynn.Projection(input_pop, target_pop, con, target=input_type) pynn.run(params["duration"]) pynn.end() wafer_cfg = pysthal.Wafer() wafer_cfg.load(marocco.wafer_cfg) results = Marocco.from_file(marocco.persist) return (BioNeuron(target_pop[0]), results, wafer_cfg)
def run_mapping(calib_dir, output_dir, wafer, hicann, skip_neurons, params): """ :type hicann: HICANNOnWafer :param params: dictionary containing neuron parameters :param skip_neurons: number of non-functional dummy neurons to insert """ from pymarocco import PyMarocco from pymarocco.results import Marocco from pymarocco.coordinates import BioNeuron import pyhmf as pynn import pysthal logger = setup_logger() marocco = PyMarocco() marocco.neuron_placement.default_neuron_size( utils.get_nested(params, "neuron.size", default=4)) marocco.neuron_placement.restrict_rightmost_neuron_blocks(True) marocco.neuron_placement.minimize_number_of_sending_repeaters(False) marocco.backend = PyMarocco.None marocco.calib_backend = PyMarocco.XML marocco.calib_path = calib_dir marocco.param_trafo.use_big_capacitors = False marocco.persist = os.path.join(output_dir, "marocco.xml.gz") marocco.wafer_cfg = os.path.join(output_dir, "wafer_cfg.bin") marocco.default_wafer = wafer # FIXME: remove? marocco.param_trafo.alpha_v = 1000.0 marocco.param_trafo.shift_v = 0.0 pynn.setup(marocco=marocco) synaptic_input = {} for input_type, input_params in params["synaptic_input"].iteritems(): if not utils.get_nested(input_params, "enabled", default=True): logger.info( "skipping disabled {!r} synaptic input".format(input_type)) continue spike_times = utils.get_nested( input_params, "spike_times", default=None) if spike_times: start = spike_times["start"] stop = spike_times["stop"] step = spike_times["step"] spike_times = np.arange(start, stop, step) input_pop_model = pynn.SpikeSourceArray input_pop_params = {"spike_times": spike_times} else: raise NotImplementedError( "unknown config for {!r} synaptic input".format(input_type)) logger.info( ("{!r} synaptic input will come from " "{} with parameters {!r}").format( input_type, input_pop_model.__name__, input_pop_params)) synaptic_input[input_type] = pynn.Population( 1, input_pop_model, input_pop_params) neuron_params = utils.get_nested(params, "neuron.parameters") neuron_model = getattr(pynn, utils.get_nested( params, "neuron.model", default="IF_cond_exp")) logger.info( "target population is {} neuron with parameters {!r}".format( neuron_model.__name__, neuron_params)) # Force marocco to give us a different neuron by inserting # `Neuron_Number - 1` dummy neurons. populations = [] for ii in range(0, skip_neurons + 1): populations.append(pynn.Population( 1, neuron_model, neuron_params)) marocco.manual_placement.on_hicann(populations[-1], hicann) target_pop = populations[-1] for input_type, input_pop in synaptic_input.iteritems(): multiplicity = utils.get_nested( params, "synaptic_input", input_type, "multiplicity", default=1) assert multiplicity >= 1 weight = utils.get_nested( params, "synaptic_input", input_type, "weight") con = pynn.AllToAllConnector(weights=weight) logger.info( ("connecting {!r} synaptic input " "to target population with weight {} " "via {} projections").format( input_type, weight, multiplicity)) for _ in xrange(multiplicity): pynn.Projection(input_pop, target_pop, con, target=input_type) pynn.run(params["duration"]) pynn.end() wafer_cfg = pysthal.Wafer() wafer_cfg.load(marocco.wafer_cfg) results = Marocco.from_file(marocco.persist) return (BioNeuron(target_pop[0]), results, wafer_cfg)