Skip to content

Commit 222932f

Browse files
author
Alexander Ororbia
committed
modded docs to include v3 foundations
1 parent 74def15 commit 222932f

File tree

13 files changed

+397
-347
lines changed

13 files changed

+397
-347
lines changed

docs/tutorials/foundations.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
In this set of tutorials/walkthroughs, we go through some of the core elements and mechanisms underlying NGC-Learn in order understand how its simulation scheme (and the nodes-and-cables system) works and to help in writing your own custom elements.
44

55
The foundational walkthroughs are organized as follows:
6-
1. <b>[Using Model Contexts](../tutorials/foundations/contexts.md)</b>: This lesson goes the fundamentals of the primary simulation construct you need to set up models, the (simulation) context.
7-
2. <b>[Understanding Commands](../tutorials/foundations/commands.md)</b>: This lesson will walk you through the basics of a command -- an essential part of building a simulation controller in ngc-learn and ngcsimlib -- and offer some useful points for designing new ones.
6+
1. <b>[Using Model Contexts](../tutorials/foundations/context.md)</b>: This lesson goes the fundamentals of the primary simulation construct you need to set up models, the (simulation) context.
7+
2. <b>[Understanding Processes](../tutorials/foundations/processes.md)</b>: This lesson will walk you through the basics of a command -- an essential part of building a simulation controller in ngc-learn and ngcsimlib -- and offer some useful points for designing new ones.
8+
<!--
89
3. <b>[Operations](../tutorials/foundations/operations.md)</b>: Here, the basics of bundle rules, a commonly-used mechanism for crafting complex biophysical systems, will be presented.
10+
-->

docs/tutorials/foundations/commands.md

Lines changed: 0 additions & 137 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Compartments
2+
3+
Within NGC-Sim-Lib, the global state serves as the backbone of any given model.
4+
This global state is essentially the culmination of all of the dynamic or changing parts of the model itself. Each
5+
value that builds this state is stored within a special "container" that helps track these changes over time -- this
6+
is referred to as a `Compartment`.
7+
8+
## Practical Information
9+
10+
Practically, when working with compartments, there are a few simple things to keep in mind despite the fact that most
11+
of NGC-Sim-Lib's primary operation is behind-the-scenes bookkeeping. The two main points to note are:
12+
1. Each compartment holds a value and, thus, setting a compartment with `myCompartment = newValue` will not function as
13+
intended since this will overwrite the Python object, i.e., the compartment with `newValue`. Instead, it is
14+
important to make use of the `.set()` method to update the value stored inside a compartment so
15+
`myCompartment = newValue` becomes `myCompartment.set(newValue)`.
16+
2. In order to retrieve a value from a compartment, use `myCompartment.get()`. These methods of getting and setting
17+
data inside a compartment are important to use when both working with and designing a multi-compartment component
18+
(i.e., `Component`).
19+
20+
## Technical Information
21+
22+
The follow sections are devoted to explication of more technical information regarding how a compartment functions
23+
with in the broader scope of NGC-Sim-Lib and, furthermore, to explain how to leverage this information.
24+
25+
### How Data is Stored (Within a Model Context)
26+
27+
The data stored inside of a compartment is not actually physically stored within a compartment. Instead, it is stored
28+
inside of the global state and each compartment effectively holds the path or `key` to the right spot in the global
29+
state, allowing it to pull out a specific piece of information. As such, it is technically possible to manipulate the
30+
value of a compartment without actually touching the compartment object itself within any given component. By default,
31+
compartments have in-built safeguards in order to prevent this from happening accidentally; however, directly addressing
32+
the compartment within the global state directly has no such safeguards.
33+
34+
### What is "Targeting"?
35+
36+
As discussed in the model building section, there is notion of "wiring" together different compartments of different
37+
components -- this is at the core of NGC-Learn's and NGC-Sim-Lib's "nodes-and-cables system". These wires are created
38+
through the concept of "targeting,", which is, in essence, just the updating of the path stored within a compartment
39+
using the path of a different compartment. This means that, if the targeted compartment goes to retrieve the value
40+
stored within it, it will actually retrieve the value of a different compartment (as dictated by the target). When a
41+
compartment is in this state -- where it is targeting another compartment -- it is set to read-only, which only means that
42+
it cannot modify a different compartment.
43+
44+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Compiling
2+
3+
The term "compiling" for NGC-Sim-Lib refers to automatic step that happens
4+
inside of a context that produces a transformed method for all of its
5+
components. This step is the most complicated part of the library and, in
6+
general, does not need to be touched or interacted with. Nevertheless, this
7+
section will cover most of the steps that the NGC-Sim-Lib compilation process
8+
does at a high level. This section contains advanced technical/developer-level
9+
information: there is an expectation that the reader has an understanding of
10+
Python abstract syntax trees (ASTs), Python namespaces, and how to
11+
dynamically compile Python code and execute it.
12+
13+
## The Decorator
14+
15+
In NGC-Sim-Lib, there is a decorator marked as `@compilable` which is used to
16+
add a flag to methods that the user wants to compile. On its own, this will not
17+
do anything; however, this decorator lets the parser distinguish between methods
18+
that should be compiled and methods that should be ignored.
19+
20+
## The Step-by-Step NGC-Sim-Lib Parsing Process
21+
22+
The process starts by telling the parser to compile a specific object.
23+
24+
### Step 1: Compile Children
25+
26+
The first step to compile any object is to make sure that all of the
27+
"compilable" objects of the top level object are compiled. As a
28+
result, NGC-Sim-Lib will loop through all of the whole object and will compile
29+
each part that it finds that is flagged as compilable (via the decorators
30+
mentioned above) and is, furthermore, an instance of a class.
31+
32+
### Step 2: Extract Methods to Compile
33+
34+
While the parser is looping through all of the parts of the top-level object, it
35+
is also extracting the methods on/embedded to the object that are flagged as
36+
compilable (with the decorator above). NGC-Sim-Lib stores them for later;
37+
however, this lets the parser only loop over the object once.
38+
39+
### Step 3: Parse Each Method
40+
41+
As each method is its own entry-point into the transformer, this step will run
42+
for each method in the top-level object.
43+
44+
### Step 3a: Set up a Transformer
45+
46+
This step sets up a `ContextTransformer`, which further makes use of a
47+
`ast.NodeTransformer`, and will convert methods from class methods (with the use
48+
of `self`), as well as other methods that need to be removed / ignored, into
49+
their more context-friendly counterparts.
50+
51+
### Step 3b: Transform the Function
52+
53+
There are quite a few pieces of common Python that need to be transformed. This
54+
step happens with the overall goal of replacing all object-focused parts with a
55+
more global view. This means that a compartment's `.get` and `.set` calls are
56+
replaced with direct setting and getting from the global state, based on the
57+
compartment's target. This also means that all temporally constant values --
58+
such as `batch_size` -- are moved into the globals space for that specific file
59+
and ultimately replaced with the naming convention of `object_path_constant`.
60+
One more key step that is performed is to ensure that there is no branching in
61+
the code. Specifically, if there is a branch, i.e., an if-statement, NGC-Sim-Lib
62+
will evaluate it and only keep the branch it will traverse down. This means that
63+
there cannot be any branch logic based on inputs or computed values (this is a
64+
common restriction for just-in-time compiling).
65+
66+
### Step 3c: Parse Sub-Methods
67+
68+
Since it is possible to have other class methods that are not marked as
69+
entry-points for compilation but still need to be compiled, as step 3b happens,
70+
NGC-Sim-Lib tracks all of the sub-methods required. Notably, this step goes
71+
through and repeats steps 3a and 3b for each of the (sub-)methods with a naming
72+
convention similar to the temporally constant values for each method.
73+
74+
### Step 3d: Compile the Abstract Syntax Tree (AST)
75+
76+
Once we have all of the namespace and globals needed to execute the
77+
properly-transformed method, the method is compiled with Python and finally
78+
executed.
79+
80+
### Step 3e: Binding
81+
82+
The final step per method is to bind each to their original method; this
83+
replaces each method with an object which, when called, will act like the
84+
normal, uncompiled version but has the addition of the `.compiled` attribute.
85+
This attribute contains all of the compiled information to be used later (for
86+
model / system simulation). This crucially allows for the end user to
87+
call `myComponent.myMethod.compiled()` and have it run. The exact type for
88+
a `compiled` value can be found
89+
in `ngcsimlib._src.parser.utils:CompiledMethod`.
90+
91+
### Step 4: Finishing Up / Final Processing
92+
93+
Some objects, such as the processes, entail additional steps to modify
94+
themselves or their compiled methods in order to align themselves with needed
95+
functionality. However, this operation/functionality is found within each
96+
class's expanded `compile` method and should be referred to by looking at those
97+
methods specifically.
98+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Components
2+
3+
Living one step above compartments in the NGC-Learn dynamical systems hierachy rests the component.
4+
A component (`ngcsimlib.Component`) holds a collection of both temporally constant values as well as dynamic (time-evolving)
5+
compartments. In addition, they are the core place where logic governing the dynamics of a system are
6+
defined. Generally, components serve as the building blocks that are to be reused multiple times
7+
when constructing a complete model of a dynmical system.
8+
9+
## Temporally Constant versus Dynamic Compartments
10+
11+
One important distinction that needs to be highlighted within a component is the
12+
difference between a temporally constant value and a dynamic (time-varying) compartment.
13+
Compartments themselves house values that change over time and, generally, they will have the
14+
type `ngcsimlib.Compartment`; note that compartments are to be used to track the internal values
15+
of a component. These internal values can be ones such inputs, decaying values, counters, etc.
16+
The second kind of values found within a component are known as temporally constant values; these
17+
are values (e.g., hyper-parameters, structural parameters, etc.) that will remain fixed
18+
within constructed model dynamical system. These types of values tend to include common configuration
19+
and meta-parameter settings, such as matrix shapes and coefficients.
20+
21+
## Defining Compilable Methods
22+
23+
Inside of a component, it is expected that there will be methods defined that govern the
24+
temporal dynamics of the system component. These compilable methods are decorated
25+
with `@compilable` and are defined like any other regular (Python) method. Within a compilable
26+
method, there will be access to `self`, which means that, to reference a compartment's
27+
value, one must write out such a call as: `self.myCompartment.get()`. The only requirement is
28+
that any method that is decorated <b>cannot</b> have a return value; values should be stored
29+
inside their respective compartments (by making an appeal to their respective set routine, i.e.,
30+
`self.myCompartment.set(value)`). In an external (compilation) step, outside of the developer's
31+
definition of a component, an NGC-Sim-Lib transformer will change/convert all of these (decorated)
32+
methods into ones that function with the rest of the NGC-Sim-Lib back-end.

0 commit comments

Comments
 (0)