ngcsimlib 0.2b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ # This file contains an official list of authors of this framework.
2
+
3
+ # Names should be added to this file as:
4
+ # Name or Organization <email address>
5
+ # The email address is not required for organizations.
6
+
7
+ Core Team
8
+ William Gebhardt <wdg1351@rit.edu>
9
+ Alexander Ororbia <ago@cs.rit.edu>
10
+
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023, The Neural Adaptive Computing Laboratory
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.1
2
+ Name: ngcsimlib
3
+ Version: 0.2b0
4
+ Summary: Simulation software backend for ngc-learn.
5
+ Author-email: William Gebhardt <wdg1351@rit.edu>, Alexander Ororbia <ago@cs.rit.edu>
6
+ License: BSD-3-Clause License
7
+ Project-URL: Homepage, https://github.com/NACLab/ngc-sim-lib
8
+ Project-URL: Lab Page, https://www.cs.rit.edu/~ago/nac_lab.html
9
+ Keywords: python,complex-systems,simulation
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ License-File: AUTHORS
14
+
15
+ [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11-blue.svg)](https://www.python.org/downloads)[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
16
+ [![DOI](https://zenodo.org/badge/734040498.svg)](https://zenodo.org/doi/10.5281/zenodo.10888210)
17
+
18
+ # NGC-Sim-Lib: Support Library for NGC-Learn
19
+
20
+ <b>ngc-sim-lib</b> is the support library and central dependency for
21
+ <i><a href="https://github.com/NACLab/ngc-learn/">ngc-learn</a></i>, a library
22
+ designed for computational neuroscience and cognitive neuroscience research.
23
+ While ngc-learn contains the JAX-implemented routines and any supporting C
24
+ code, ngc-sim-lib is a pure Python package, primarily meant for providing the
25
+ machinery, routines, and utilities that facilitate the general (abstract)
26
+ simulation of complex adaptive systems made up of dynamical components. For
27
+ information, including anything related to usage instructions and details,
28
+ please refer to the ngc-learn README:
29
+ https://github.com/NACLab/ngc-learn/.
30
+
31
+ This package is distributed under the 3-Clause BSD license. It is currently
32
+ maintained by the
33
+ <a href="https://www.cs.rit.edu/~ago/nac_lab.html">Neural Adaptive Computing
34
+ (NAC) laboratory</a>.
35
+
36
+ ## <b>Installation:</b>
37
+
38
+ <i>Setup:</i> Ensure that you have installed the following base dependencies in
39
+ your system. Note that this library was developed and tested on
40
+ Ubuntu 22.04.3 LTS. ngc-sim-lib requires: `Python (>=3.10)`.
41
+
42
+ Once you have ensured that the appropriate Python is installed, you can then
43
+ have the <code>ngclib</code> package installed on your system using the
44
+ following bash command:
45
+ <pre>
46
+ $ pip install .
47
+ </pre>
48
+ or, if you are doing development, then do an editable install via:
49
+ <pre>
50
+ $ pip install --editable . # OR pip install -e .
51
+ </pre>
52
+
53
+ **Version:**<br>
54
+ 0.2.0 <!-- -Alpha -->
55
+
56
+ Authors:
57
+ William Gebhardt, Alexander G. Ororbia II<br>
58
+ Neural Adaptive Computing (NAC) Laboratory<br>
59
+ Rochester Institute of Technology, Department of Computer Science
60
+
61
+ ## <b>Copyright:</b>
62
+
63
+ Copyright (C) 2023 The Neural Adaptive Computing Laboratory - All Rights Reserved<br>
64
+ You may use, distribute and modify this code under the
65
+ terms of the BSD 3-clause license.
66
+
67
+ You should have received a copy of the BSD 3-clause license with
68
+ this software.<br>
69
+ If not, please [email us](mailto:ago@cs.rit.edu)
@@ -0,0 +1,55 @@
1
+ [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11-blue.svg)](https://www.python.org/downloads)[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
2
+ [![DOI](https://zenodo.org/badge/734040498.svg)](https://zenodo.org/doi/10.5281/zenodo.10888210)
3
+
4
+ # NGC-Sim-Lib: Support Library for NGC-Learn
5
+
6
+ <b>ngc-sim-lib</b> is the support library and central dependency for
7
+ <i><a href="https://github.com/NACLab/ngc-learn/">ngc-learn</a></i>, a library
8
+ designed for computational neuroscience and cognitive neuroscience research.
9
+ While ngc-learn contains the JAX-implemented routines and any supporting C
10
+ code, ngc-sim-lib is a pure Python package, primarily meant for providing the
11
+ machinery, routines, and utilities that facilitate the general (abstract)
12
+ simulation of complex adaptive systems made up of dynamical components. For
13
+ information, including anything related to usage instructions and details,
14
+ please refer to the ngc-learn README:
15
+ https://github.com/NACLab/ngc-learn/.
16
+
17
+ This package is distributed under the 3-Clause BSD license. It is currently
18
+ maintained by the
19
+ <a href="https://www.cs.rit.edu/~ago/nac_lab.html">Neural Adaptive Computing
20
+ (NAC) laboratory</a>.
21
+
22
+ ## <b>Installation:</b>
23
+
24
+ <i>Setup:</i> Ensure that you have installed the following base dependencies in
25
+ your system. Note that this library was developed and tested on
26
+ Ubuntu 22.04.3 LTS. ngc-sim-lib requires: `Python (>=3.10)`.
27
+
28
+ Once you have ensured that the appropriate Python is installed, you can then
29
+ have the <code>ngclib</code> package installed on your system using the
30
+ following bash command:
31
+ <pre>
32
+ $ pip install .
33
+ </pre>
34
+ or, if you are doing development, then do an editable install via:
35
+ <pre>
36
+ $ pip install --editable . # OR pip install -e .
37
+ </pre>
38
+
39
+ **Version:**<br>
40
+ 0.2.0 <!-- -Alpha -->
41
+
42
+ Authors:
43
+ William Gebhardt, Alexander G. Ororbia II<br>
44
+ Neural Adaptive Computing (NAC) Laboratory<br>
45
+ Rochester Institute of Technology, Department of Computer Science
46
+
47
+ ## <b>Copyright:</b>
48
+
49
+ Copyright (C) 2023 The Neural Adaptive Computing Laboratory - All Rights Reserved<br>
50
+ You may use, distribute and modify this code under the
51
+ terms of the BSD 3-clause license.
52
+
53
+ You should have received a copy of the BSD 3-clause license with
54
+ this software.<br>
55
+ If not, please [email us](mailto:ago@cs.rit.edu)
@@ -0,0 +1,50 @@
1
+ from . import utils
2
+ from . import controller
3
+ from . import commands
4
+
5
+ import argparse, os, warnings, json
6
+ from types import SimpleNamespace
7
+ from pathlib import Path
8
+ from sys import argv
9
+ from importlib import import_module
10
+
11
+ from pkg_resources import get_distribution
12
+
13
+ __version__ = get_distribution('ngcsimlib').version ## set software version
14
+
15
+ ###### Preload Modules
16
+ def preload():
17
+ parser = argparse.ArgumentParser(description='Build and run a model using ngclearn')
18
+ parser.add_argument("--modules", type=str, help='location of modules.json file')
19
+
20
+ args = parser.parse_args()
21
+ try:
22
+ module_path = args.modules
23
+ except:
24
+ module_path = None
25
+
26
+ if module_path is None:
27
+ module_path = "json_files/modules.json"
28
+
29
+ if not os.path.isfile(module_path):
30
+ warnings.warn("Missing file to preload modules from. Attempted to locate file at \"" + str(module_path) + "\"" )
31
+ return
32
+
33
+ with open(module_path, 'r') as file:
34
+ modules = json.load(file, object_hook=lambda d: SimpleNamespace(**d))
35
+
36
+ for module in modules:
37
+ mod = import_module(module.absolute_path)
38
+ utils._Loaded_Modules[module.absolute_path] = mod
39
+
40
+ for attribute in module.attributes:
41
+ atr = getattr(mod, attribute.name)
42
+ utils._Loaded_Attributes[attribute.name] = atr
43
+
44
+ utils._Loaded_Attributes[".".join([module.absolute_path, attribute.name])] = atr
45
+ if hasattr(attribute, "keywords"):
46
+ for keyword in attribute.keywords:
47
+ utils._Loaded_Attributes[keyword] = atr
48
+
49
+ if not Path(argv[0]).name == "sphinx-build" or Path(argv[0]).name == "build.py":
50
+ preload()
@@ -0,0 +1,64 @@
1
+ """
2
+ Contains all the built-in bundle rules as well as the default one for an unbundled
3
+ cable. Bundle(s) usage is that it is to be added to a component's bundle rules
4
+ (Note: the overwrite rule is the default rule).
5
+
6
+
7
+ Template for bundle rules. The name of the bundle rule should be meaningful to what it does. All bundle rules will
8
+ be called with the same three inputs: component, value, and destination_compartment. These are not passed by keyword but
9
+ they will always be in the same order. The component is the component that the bundle has as a destination (target).
10
+ The value is the signal that goes into (or comes along to) the connected bundle. The destination_compartment is
11
+ the compartment that the bundle is connected to. Overall, the general usage of bundle rules is to modify the
12
+ behavior of an input to a compartment; generally, they should NOT modify any other aspect of the target
13
+ component aside from the destination compartment and, as a warning, should not try to reference compartments by
14
+ name as this will possibly result in runtime errors given that the required compartments for the bundle rule(s)
15
+ might not exist.
16
+
17
+ General bundle rule specification:
18
+
19
+ def BUNDLE_RULE_NAME(component, value, destination_compartment):
20
+ ## Logic for processing transmitted value
21
+ ## Syntax for referencing destination compartment -> component.compartments[destination_compartment]
22
+
23
+ """
24
+ def overwrite(component, value, destination_compartment):
25
+ """
26
+ The overwrite bundle rule routine.
27
+
28
+ Args:
29
+ component: target component node that this bundle rule will operate on
30
+
31
+ value: the value to insert into a compartment within the target component
32
+
33
+ destination_compartment: compartment within component to place a value w/in
34
+ """
35
+ component.compartments[destination_compartment] = value
36
+
37
+
38
+ def additive(component, value, destination_compartment):
39
+ """
40
+ The additive/addition bundle rule routine.
41
+
42
+ Args:
43
+ component: target component node that this bundle rule will operate on
44
+
45
+ value: the value to add to current state of compartment w/in target component
46
+
47
+ destination_compartment: compartment within component to add a value to
48
+ """
49
+ component.compartments[destination_compartment] += value
50
+
51
+
52
+ def append(component, value, destination_compartment):
53
+ """
54
+ The append/aggregation bundle rule routine. This is primarily useful if
55
+ the compartment is a list of a values/objects (an appendable list construct).
56
+
57
+ Args:
58
+ component: target component node that this bundle rule will operate on
59
+
60
+ value: the value to append to current state of compartment w/in target component
61
+
62
+ destination_compartment: compartment within component to append to
63
+ """
64
+ component.compartments[destination_compartment].append(value)
@@ -0,0 +1,11 @@
1
+ from .command import Command
2
+ from .advanceState import AdvanceState
3
+ from .clamp import Clamp
4
+ from .evolve import Evolve
5
+ from .reset import Reset
6
+ from .track import Track
7
+ from .save import Save
8
+ from .compound import Compound
9
+ from .snapshot import Snapshot
10
+ from .multiclamp import Multiclamp
11
+
@@ -0,0 +1,25 @@
1
+ from ngcsimlib.commands import Command
2
+
3
+
4
+ class AdvanceState(Command):
5
+ """
6
+ As the general form, all models built in ngclearn are state machines and this
7
+ command is designed to advance the state of all of the components passed into
8
+ the command. Prior to advancing the state of each component, this will call the
9
+ `gather` method of that component.
10
+ """
11
+ def __init__(self, components=None, command_name=None, **kwargs):
12
+ """
13
+ Required calls on Components: ['advance_state', 'gather', 'name']
14
+
15
+ Args:
16
+ components: the list of components to advance the state of
17
+ command_name: the name of the command on the controller
18
+ """
19
+ super().__init__(components=components, command_name=command_name,
20
+ required_calls=['advance_state', 'gather'])
21
+
22
+ def __call__(self, **kwargs):
23
+ for component in self.components:
24
+ self.components[component].gather()
25
+ self.components[component].advance_state(**kwargs)
@@ -0,0 +1,58 @@
1
+ from ngcsimlib.commands.command import Command
2
+ from ngcsimlib.utils import extract_args
3
+
4
+
5
+ class Clamp(Command):
6
+ """
7
+ All components in ngclearn have compartments where they store information
8
+ pertaining to their internal state that can be read into or out of by
9
+ commands. The Clamp command is the primary way to manually set the value of
10
+ a compartment on a set of components. The Clamp command requires a
11
+ compartment that a value can be passed into and be clamped to,
12
+ as well as a `clamp_name` used to locate the value when called.
13
+ """
14
+
15
+ def __init__(self, components=None, compartment=None, clamp_name=None,
16
+ command_name=None, **kwargs):
17
+ """
18
+ Required calls on Components: ['clamp', 'name']
19
+
20
+ Args:
21
+ components: a list of components to call clamp on
22
+
23
+ compartment: the compartment being clamped to
24
+
25
+ clamp_name: a keyword to bind the input for this command do
26
+
27
+ command_name: the name of the command on the controller
28
+
29
+ """
30
+ super().__init__(components=components, command_name=command_name,
31
+ required_calls=['clamp'])
32
+ if compartment is None:
33
+ raise RuntimeError(
34
+ self.name + " requires a \'compartment\' to clamp to for construction")
35
+ if clamp_name is None:
36
+ raise RuntimeError(
37
+ self.name + " requires a \'clamp_name\' to bind to for construction")
38
+
39
+ self.clamp_name = clamp_name
40
+ self.compartment = compartment
41
+
42
+ for component in self.components:
43
+ if self.compartment not in self.components[component].compartments.keys():
44
+ raise RuntimeError(self.name + " is attempting to "
45
+ "initialize clamp to "
46
+ "non-existent compartment.")
47
+
48
+ def __call__(self, *args, **kwargs):
49
+ try:
50
+ vals = extract_args([self.clamp_name], *args, **kwargs)
51
+ except RuntimeError:
52
+ raise RuntimeError(self.name + ", " + str(
53
+ self.clamp_name) + " is missing from keyword arguments or a positional "
54
+ "arguments can be provided")
55
+
56
+ for component in self.components:
57
+ self.components[component].clamp(self.compartment, vals[self.clamp_name])
58
+
@@ -0,0 +1,34 @@
1
+ from abc import ABC, abstractmethod
2
+ from ngcsimlib.utils import check_attributes
3
+
4
+
5
+ class Command(ABC):
6
+ """
7
+ The base class for all commands found in ngcsimlib. At its core, a command is
8
+ essentially a method to be called by the controller that affects the
9
+ components in a simulated complex system / model in some way. When a command
10
+ is made, a preprocessing step is run to verify that all of the needed
11
+ attributes are present on each component. Note that this step does not
12
+ ensure types or values, just that they do or do not exist.
13
+ """
14
+ def __init__(self, components=None, command_name=None, required_calls=None):
15
+ """
16
+ Required calls on Components: ['name']
17
+
18
+ Args:
19
+ components: a list of components to run the command on
20
+
21
+ required_calls: a list of required attributes for all components
22
+
23
+ command_name: the name of the command on the controller
24
+ """
25
+ self.name = str(command_name)
26
+ self.components = {}
27
+ required_calls = ['name'] if required_calls is None else required_calls + ['name']
28
+ for comp in components:
29
+ if check_attributes(comp, required_calls, fatal=True):
30
+ self.components[comp.name] = comp
31
+
32
+ @abstractmethod
33
+ def __call__(self, *args, **kwargs):
34
+ pass
@@ -0,0 +1,39 @@
1
+ from ngcsimlib.commands import Command
2
+ from ngcsimlib.utils import check_attributes
3
+ import warnings
4
+
5
+ class Compound(Command):
6
+ """
7
+ There is sometimes a need by controllers to be able to call a set of commands
8
+ in series without writing custom command(s) for each combination. The
9
+ compound node/command is used to fill this need. A compound command set is
10
+ very similar to the cycle found inside/within a controller / simulation object.
11
+ """
12
+ def __init__(self, components=None, command_name=None, command_list=None,
13
+ controller=None, **kwargs):
14
+ """
15
+ Constructs a compound command construct.
16
+
17
+ Args:
18
+ components: a list of components, this will go unused by default
19
+
20
+ command_name: the name of the compound command
21
+
22
+ command_list: a list of all commands to be called
23
+
24
+ controller: the controller that will be calling these commands
25
+ """
26
+ super().__init__(components=components, command_name=command_name)
27
+ if controller is None:
28
+ raise RuntimeError("The controller is needed to build a compound command (This should be passed in by default)")
29
+ if command_list is None or len(command_list) == 0:
30
+ warnings.warn("The command list for command " + self.name + " is None or empty")
31
+
32
+ self.command_list = command_list
33
+ self.controller = controller
34
+
35
+ check_attributes(self.controller, self.command_list, fatal=True)
36
+
37
+ def __call__(self, *args, **kwargs):
38
+ for command in self.command_list:
39
+ self.controller.runCommand(command, *args, **kwargs)
@@ -0,0 +1,41 @@
1
+ from ngcsimlib.commands import Command
2
+ from ngcsimlib.utils import extract_args
3
+
4
+ class Evolve(Command):
5
+ """
6
+ In many models, there is a need to have either a backward pass or a separate
7
+ method to update some particular internal state (value), e.g., a "learning"
8
+ or evolutionary change that is not related to central compartment states.
9
+ In general, this can be mapped to a call of `evolve`. Like with
10
+ `advanceState`, this will call the gather method prior to calling the
11
+ `evolve` function of every component.
12
+
13
+ """
14
+ def __init__(self, components=None, frozen_flag=None, command_name=None,
15
+ **kwargs):
16
+ """
17
+ Required calls on Components: ['evolve', 'gather', 'name']
18
+
19
+ Args:
20
+ components: the list of components to evolve
21
+
22
+ frozen_flag: the keyword for the flag to freeze this evolve step
23
+
24
+ command_name: the name of the command on the controller
25
+ """
26
+ super().__init__(components=components, command_name=command_name,
27
+ required_calls=['evolve'])
28
+
29
+ self.frozen_flag = frozen_flag
30
+
31
+ def __call__(self, *args, **kwargs):
32
+ vals = {}
33
+ try:
34
+ vals = extract_args([self.frozen_flag], *args, **kwargs)
35
+ except RuntimeError:
36
+ vals[self.frozen_flag] = False
37
+
38
+ if not vals[self.frozen_flag]:
39
+ for component in self.components:
40
+ self.components[component].gather()
41
+ self.components[component].evolve(**kwargs)
@@ -0,0 +1,42 @@
1
+ from ngcsimlib.commands.command import Command
2
+ from ngcsimlib.utils import extract_args, check_attributes
3
+
4
+
5
+ class Multiclamp(Command):
6
+ """
7
+ There are times when a model will have many clamp calls as there might be a
8
+ need to clamp many different values to a model at the same time. As a
9
+ solution to this, ngcsimlib provides the `multiclamp` command. This command is
10
+ used to set a wide range of values to all compartments with the same name
11
+ across all provided compartments.
12
+ """
13
+
14
+ def __init__(self, components=None, clamp_name=None, command_name=None,
15
+ **kwargs):
16
+ """
17
+ Required calls on Components: ['clamp', 'name']
18
+ Args:
19
+ components: a list of components to call clamp on
20
+
21
+ clamp_name: a keyword to bind the input for this command do
22
+
23
+ command_name: the name of the command on the controller
24
+ """
25
+ super().__init__(components=components, command_name=command_name,
26
+ required_calls=['clamp'])
27
+ if clamp_name is None:
28
+ raise RuntimeError(self.name + " requires a \'clamp_name\' to bind to for construction")
29
+
30
+ self.clamp_name = clamp_name
31
+
32
+ def __call__(self, *args, **kwargs):
33
+ try:
34
+ vals = extract_args([self.clamp_name], *args, **kwargs)
35
+ except RuntimeError:
36
+ raise RuntimeError(self.name + ", " + str(self.clamp_name) + " is missing from keyword arguments or a "
37
+ "positional arguments can be provided")
38
+
39
+ for compartment, value in vals[self.clamp_name].items():
40
+ for component in self.components:
41
+ if check_attributes(component, compartment, fatal=False):
42
+ self.components[component].clamp(compartment, value)
@@ -0,0 +1,40 @@
1
+ from ngcsimlib.commands import Command
2
+ from ngcsimlib.utils import extract_args
3
+ import warnings
4
+
5
+ class Reset(Command):
6
+ """
7
+ In every model/system, there is a need to reset components back to some
8
+ intial state value(s). As such, many components that maintain a state have a
9
+ reset method implemented within them. The reset command will go through
10
+ the list of components and trigger the reset within each of them.
11
+ """
12
+ def __init__(self, components=None, reset_name=None, command_name=None,
13
+ **kwargs):
14
+ """
15
+ Required calls on Components: ['reset', 'name']
16
+
17
+ Args:
18
+ components: a list of components to reset
19
+
20
+ reset_name: the keyword for the flag on if the reset should happen
21
+
22
+ command_name: the name of the command on the controller
23
+ """
24
+ super().__init__(components=components, command_name=command_name,
25
+ required_calls=['reset'])
26
+ if reset_name is None:
27
+ raise RuntimeError(self.name + " requires a \'reset_name\' to bind to for construction")
28
+ self.reset_name = reset_name
29
+
30
+ def __call__(self, *args, **kwargs):
31
+ try:
32
+ vals = extract_args([self.reset_name], *args, **kwargs)
33
+ except RuntimeError:
34
+ warnings.warn(self.name + ", " + str(self.reset_name) + " is missing from keyword arguments and no "
35
+ "positional arguments were provided", stacklevel=6)
36
+ return
37
+
38
+ if vals[self.reset_name]:
39
+ for component in self.components:
40
+ self.components[component].reset()
@@ -0,0 +1,46 @@
1
+ from ngcsimlib.commands import Command
2
+ from ngcsimlib.utils import extract_args
3
+ import warnings
4
+
5
+ class Save(Command):
6
+ """
7
+ When training models, there is often a need to snapshot the model and save
8
+ it to disk. The base controller in ngcsimlib is able to save all of the
9
+ commands, components, connections, and steps to a file in order to rebuild
10
+ the model at a later time. However, there is a good chance that the model
11
+ will contain components that have parts that need saving beyond the parameters
12
+ passed in to initialize the component. ngcsimlib solves this by providing a
13
+ save command; this command will call a custom save method on all components
14
+ provided to the command. This custom save method will be responsible for all
15
+ custom values to be saved and determining where to save them inside of a
16
+ provided directory.
17
+ """
18
+ def __init__(self, components=None, directory_flag=None, command_name=None,
19
+ **kwargs):
20
+ """
21
+ Required calls on Components: ['save', 'name']
22
+
23
+ Args:
24
+ components: a list of components to call the save function on
25
+
26
+ directory_flag: keyword for flag for the directory to save to
27
+
28
+ command_name: the name of the command on the controller
29
+ """
30
+ super().__init__(components=components, command_name=command_name,
31
+ required_calls=['save'])
32
+ if directory_flag is None:
33
+ raise RuntimeError(self.name + " requires a \'directory_flag\' to bind to for construction")
34
+ self.directory_flag = directory_flag
35
+
36
+ def __call__(self, *args, **kwargs):
37
+ try:
38
+ vals = extract_args([self.directory_flag], *args, **kwargs)
39
+ except RuntimeError:
40
+ warnings.warn(self.name + ", " + str(self.directory_flag) + " is missing from keyword arguments and no "
41
+ "positional arguments were provided", stacklevel=6)
42
+ return
43
+
44
+ if vals[self.directory_flag]:
45
+ for component in self.components:
46
+ self.components[component].save(vals[self.directory_flag])
@@ -0,0 +1,39 @@
1
+ from ngcsimlib.commands import Command
2
+
3
+ class Snapshot(Command):
4
+ """
5
+ Sometimes when running through a model, there is a need to extract a value
6
+ from a compartment to the run loop. As such, ngcsimlib provides the snapshot
7
+ command. This command will extract a given attribute from all components
8
+ provided to the command. This command returns a single value if only one
9
+ component is given, otherwise it will return a list where each value
10
+ corresponds to the position of the component in the components list.
11
+
12
+ This command is regularly used for debugging/graph production code that
13
+ exists outside of the model. It would be incorrect to clamp the output of
14
+ this command into another component, if that is the intended goal, please
15
+ see `connect` in the controller.
16
+ """
17
+ def __init__(self, components=None, attribute=None, command_name=None,
18
+ **kwargs):
19
+ """
20
+ Required calls on Components: ['name'], and the passed-in attribute
21
+
22
+ Args:
23
+ components: the component extract the values of
24
+
25
+ attribute: a single attribute to return
26
+
27
+ command_name: the name of the command on the controller
28
+ """
29
+ super().__init__(components=components, command_name=command_name,
30
+ required_calls=[attribute])
31
+ self.attribute = attribute
32
+
33
+
34
+ def __call__(self, *args, **kwargs):
35
+ vals = []
36
+ for component in self.components:
37
+ vals.append(getattr(self.components[component], self.attribute))
38
+
39
+ return vals if len(vals) > 1 else vals[0]