def test_write_progress_to_file(tmpdir): """Tests the WriteProgressToFile progress bar type""" def check_file(filename, startstring): with open(filename, "r") as fh: data = fh.read() assert data.startswith(startstring) filename = str(tmpdir.join("test_write_progress_file.txt")) progress = Progress(name_during="myprog", max_steps=2) bar = WriteProgressToFile(filename) with progress: bar.update(progress) check_file(filename, "0%, ETA") progress.step() bar.update(progress) check_file(filename, "50%, ETA") progress.step() bar.update(progress) check_file(filename, "100%, ETA") bar.update(progress) check_file(filename, "myprog finished in")
def build_network(model, network, progress=None): """Builds a `.Network` object into a model. The network builder does this by mapping each high-level object to its associated signals and operators one-by-one, in the following order: 1. Ensembles, nodes, neurons 2. Subnetworks (recursively) 3. Connections, learning rules 4. Probes Before calling any of the individual objects' build functions, random number seeds are assigned to objects that did not have a seed explicitly set by the user. Whether the seed was assigned manually or automatically is tracked, and the decoder cache is only used when the seed is assigned manually. Parameters ---------- model : Model The model to build into. network : Network The network to build. progress : Progress, optional Object used to track the build progress. Note that this will only affect top-level networks. Notes ----- Sets ``model.params[network]`` to ``None``. """ if model.toplevel is None: model.toplevel = network seed_network(network, seeds=model.seeds, seeded=model.seeded) if progress is not None: # number of sub-objects, plus 1 to account for this network progress.max_steps = len(network.all_objects) + 1 def build_callback(obj): if isinstance(obj, tuple(network.objects)): progress.step() model.build_callback = build_callback if progress is None: progress = Progress() # dummy progress # Set config old_config = model.config model.config = network.config # If this is the toplevel network, enter the decoder cache context = model.decoder_cache if model.toplevel is network else nullcontext( ) with context, progress: logger.debug("Network step 1: Building ensembles and nodes") for obj in network.ensembles + network.nodes: model.build(obj) logger.debug("Network step 2: Building subnetworks") for subnetwork in network.networks: model.build(subnetwork) logger.debug("Network step 3: Building connections") for conn in network.connections: # NB: we do these in the order in which they're defined, and build # the learning rule in the connection builder. Because learning # rules are attached to connections, the connection that contains # the learning rule (and the learning rule) are always built # *before* a connection that attaches to that learning rule. # Therefore, we don't have to worry about connection ordering here. # TODO: Except perhaps if the connection being learned # is in a subnetwork? model.build(conn) logger.debug("Network step 4: Building probes") for probe in network.probes: model.build(probe) if context is model.decoder_cache: model.decoder_cache.shrink() if model.toplevel is network: progress.step() model.build_callback = None # Unset config model.config = old_config model.params[network] = None
def build_network(model, network, progress=None): """Builds a `.Network` object into a model. The network builder does this by mapping each high-level object to its associated signals and operators one-by-one, in the following order: 1. Ensembles, nodes, neurons 2. Subnetworks (recursively) 3. Connections, learning rules 4. Probes Before calling any of the individual objects' build functions, random number seeds are assigned to objects that did not have a seed explicitly set by the user. Whether the seed was assigned manually or automatically is tracked, and the decoder cache is only used when the seed is assigned manually. Parameters ---------- model : Model The model to build into. network : Network The network to build. progress : Progress, optional Object used to track the build progress. Note that this will only affect top-level networks. Notes ----- Sets ``model.params[network]`` to ``None``. """ def get_seed(obj, rng): # Generate a seed no matter what, so that setting a seed or not on # one object doesn't affect the seeds of other objects. seed = rng.randint(npext.maxint) return (seed if not hasattr(obj, 'seed') or obj.seed is None else obj.seed) if model.toplevel is None: model.toplevel = network model.seeds[network] = get_seed(network, np.random) model.seeded[network] = getattr(network, 'seed', None) is not None max_steps = len(network.all_objects) + 1 # +1 for top level network if progress is not None: progress.max_steps = max_steps def build_callback(obj): if isinstance(obj, tuple(network.objects)): progress.step() model.build_callback = build_callback if progress is None: progress = Progress() # dummy progress # Set config old_config = model.config model.config = network.config # assign seeds to children rng = np.random.RandomState(model.seeds[network]) # Put probes last so that they don't influence other seeds sorted_types = (Connection, Ensemble, Network, Node, Probe) assert all(tp in sorted_types for tp in network.objects) for obj_type in sorted_types: for obj in network.objects[obj_type]: model.seeded[obj] = (model.seeded[network] or getattr(obj, 'seed', None) is not None) model.seeds[obj] = get_seed(obj, rng) # If this is the toplevel network, enter the decoder cache context = (model.decoder_cache if model.toplevel is network else nullcontext()) with context, progress: logger.debug("Network step 1: Building ensembles and nodes") for obj in network.ensembles + network.nodes: model.build(obj) logger.debug("Network step 2: Building subnetworks") for subnetwork in network.networks: model.build(subnetwork) logger.debug("Network step 3: Building connections") for conn in network.connections: # NB: we do these in the order in which they're defined, and build # the learning rule in the connection builder. Because learning # rules are attached to connections, the connection that contains # the learning rule (and the learning rule) are always built # *before* a connection that attaches to that learning rule. # Therefore, we don't have to worry about connection ordering here. # TODO: Except perhaps if the connection being learned # is in a subnetwork? model.build(conn) logger.debug("Network step 4: Building probes") for probe in network.probes: model.build(probe) if context is model.decoder_cache: model.decoder_cache.shrink() if model.toplevel is network: progress.step() model.build_callback = None # Unset config model.config = old_config model.params[network] = None