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())
Example #3
0
    def test_popview_combinations(self, view_number):
        # tests all possible combinations of mask lengths for different number of PopulationViews
        import pylogging
        from pymarocco import PyMarocco, Defects
        from pymarocco.results import Marocco
        pop_size = 5
        hicanns = [C.HICANNOnWafer(Enum(180 + view)) for view in range(view_number)]
        # generate possible mask lengths for Population Views
        pool = tuple(i for i in range(1, pop_size - view_number + 2))
        # generate all possible mask lengths for each PopulationView for a given total number of neurons
        # [[lengths_of_Popviews],number_of_used_neurons]
        view_lengths = [([], 0)]
        for _ in range(view_number):
            view_lengths = [(x+[y], csum+y) for x, csum in view_lengths for y in pool if csum <= pop_size - y]
        neurons = list(range(pop_size))
        for length in view_lengths:
            marocco = PyMarocco()
            marocco.backend = PyMarocco.Without
            marocco.persist = "results.bin"
            marocco.defects.backend = Defects.Backend.Without
            neuron_size = 4
            marocco.neuron_placement.default_neuron_size(neuron_size)
            pynn.setup(marocco=marocco)

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

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

            for view in range(view_number):
                for nrn in pop_views[view]:
                    placement_item, = results.placement.find(nrn)
                    logical_neuron = placement_item.logical_neuron()
                    for denmem in logical_neuron:
                        self.assertEqual(hicanns[view], denmem.toHICANNOnWafer())
Example #4
0
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_())
Example #5
0
    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)
Example #8
0
 def load_results(self):
     self.assertTrue(os.path.exists(self.marocco.persist))
     return Marocco.from_file(self.marocco.persist)
Example #9
0
    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
Example #10
0
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)