Skip to content

Commit d03fc10

Browse files
committed
Merge branch 'transition' into dev
2 parents 51439d2 + ad610db commit d03fc10

File tree

16 files changed

+269
-118
lines changed

16 files changed

+269
-118
lines changed

ngcsimlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from . import controller
33
from . import commands
44

5+
56
import argparse, os, json
67
from types import SimpleNamespace
78
from importlib import import_module

ngcsimlib/compilers/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
from .command_compiler import compile_command, dynamic_compile, wrap_command
2-
from .component_compiler import compile as compile_component
3-
from .op_compiler import compile as compile_op
1+
from .legacy_compiler.command_compiler import compile_command, dynamic_compile
2+
from .utils import wrap_command, compose

ngcsimlib/compilers/legacy_compiler/__init__.py

Whitespace-only changes.

ngcsimlib/compilers/command_compiler.py renamed to ngcsimlib/compilers/legacy_compiler/command_compiler.py

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@
3838
passed in at run time.
3939
4040
"""
41-
from ngcsimlib.compilers.component_compiler import parse as parse_component, \
41+
from ngcsimlib.compilers.legacy_compiler.component_compiler import parse as parse_component, \
4242
compile as compile_component
43-
from ngcsimlib.compilers.op_compiler import parse as parse_connection
43+
from ngcsimlib.compilers.legacy_compiler.op_compiler import parse as parse_connection
4444
from ngcsimlib.utils import Get_Compartment_Batch, Set_Compartment_Batch
4545
from ngcsimlib.logger import critical
4646

@@ -61,8 +61,7 @@ def _compile(compile_key, components):
6161
| resolve the outputs of the compiled function
6262
6363
Args:
64-
compile_key: The key that is being compiled (mapped to each function
65-
that has the @resolver decorator above it)
64+
compile_key: The key for the transition that is being compiled
6665
6766
components: The list of components to compile for this function
6867
@@ -71,15 +70,15 @@ def _compile(compile_key, components):
7170
"""
7271
assert compile_key is not None
7372
## for each component, get compartments, get output compartments
74-
resolvers = {}
73+
transitions = {}
7574
for c_name, component in components.items():
76-
resolvers[c_name] = parse_component(component, compile_key)
75+
transitions[c_name] = parse_component(component, compile_key)
7776

7877
needed_args = []
7978
needed_comps = []
8079

8180
for c_name, component in components.items():
82-
_, outs, args, params, comps = resolvers[c_name]
81+
_, outs, args, params, comps = transitions[c_name]
8382
for a in args:
8483
if a not in needed_args:
8584
needed_args.append(a)
@@ -98,7 +97,7 @@ def _compile(compile_key, components):
9897

9998
exc_order = []
10099
for c_name, component in components.items():
101-
exc_order.extend(compile_component(component, resolvers[c_name]))
100+
exc_order.extend(compile_component(component, transitions[c_name]))
102101

103102
def compiled(compartment_values=None, **kwargs):
104103
if compartment_values is None:
@@ -158,22 +157,3 @@ def dynamic_compile(*components, compile_key=None):
158157
return _compile(compile_key, {c.name: c for c in components})
159158

160159

161-
def wrap_command(command):
162-
"""
163-
Wraps the provided command to provide the state of all compartments as input
164-
and saves the returned state to all compartments after running. Designed to
165-
be used with compiled commands
166-
167-
Args:
168-
command: the command to wrap
169-
170-
Returns:
171-
the output of the command after it's been executed
172-
"""
173-
174-
def _wrapped(**kwargs):
175-
vals = command(Get_Compartment_Batch(), **kwargs)
176-
Set_Compartment_Batch(vals)
177-
return vals
178-
179-
return _wrapped

ngcsimlib/compilers/component_compiler.py renamed to ngcsimlib/compilers/legacy_compiler/component_compiler.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
the same pattern used by the command compiler.
1616
1717
"""
18-
from ngcsimlib.compilers.op_compiler import compile as op_compile
19-
from ngcsimlib.utils import get_resolver
18+
from ngcsimlib.compilers.legacy_compiler.op_compiler import compile as op_compile
19+
from ngcsimlib.utils import get_transition
2020
from ngcsimlib.compartment import Compartment
2121
from ngcsimlib.logger import critical
2222

@@ -40,20 +40,25 @@ def parse(component, compile_key):
4040
if component.__class__.__dict__.get("auto_resolve", True):
4141
(pure_fn, output_compartments), (
4242
args, parameters, compartments, parse_varnames) = \
43-
get_resolver(component.__class__, compile_key)
43+
get_transition(component.__class__, compile_key)
4444
else:
4545
build_method = component.__class__.__dict__.get(f"build_{compile_key}", None)
4646
if build_method is None:
47-
critical(f"Component {component.name} if flagged to not use resolvers but "
47+
critical(f"Component {component.name} if flagged to not use a stored transition but "
4848
f"does not have a build_{compile_key} method")
4949
return build_method(component)
5050

5151
if parse_varnames:
5252
args = []
5353
parameters = []
5454
compartments = []
55-
varnames = pure_fn.__func__.__code__.co_varnames[
56-
:pure_fn.__func__.__code__.co_argcount]
55+
try:
56+
func = pure_fn.__func__
57+
except:
58+
func = pure_fn
59+
60+
varnames = func.__code__.co_varnames[
61+
:func.__code__.co_argcount]
5762

5863
for name in varnames:
5964
if name not in component.__dict__.keys():
@@ -77,20 +82,20 @@ def parse(component, compile_key):
7782
return (pure_fn, output_compartments, args, parameters, compartments)
7883

7984

80-
def compile(component, resolver):
85+
def compile(component, transition):
8186
"""
8287
compiles down the component to a single pure method
8388
8489
Args:
8590
component: the component to compile
8691
87-
resolver: the parsed output of the component
92+
transition: the parsed output of the component
8893
8994
Returns:
9095
the compiled method
9196
"""
9297
exc_order = []
93-
pure_fn, outs, _args, params, comps = resolver
98+
pure_fn, outs, _args, params, comps = transition
9499

95100
### Op resolve
96101
for connection in component.connections:
@@ -104,11 +109,16 @@ def compile(component, resolver):
104109

105110
comp_key_key = [(narg.split('/')[-1], narg) for narg in comp_ids]
106111

112+
try:
113+
func = pure_fn.__func__
114+
except:
115+
func = pure_fn
116+
107117
def compiled(**kwargs):
108118
funArgs = {narg: kwargs.get(narg) for narg in _args}
109119
funComps = {knarg: kwargs.get(narg) for knarg, narg in comp_key_key}
110120

111-
return pure_fn.__func__(**funParams, **funArgs, **funComps)
121+
return func(**funParams, **funArgs, **funComps)
112122

113123
exc_order.append((compiled, out_ids, component.name, comp_ids))
114124
return exc_order

ngcsimlib/compilers/op_compiler.py renamed to ngcsimlib/compilers/legacy_compiler/op_compiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
The second one is the compile method which returns the execution order for
1111
the compile operation. It is important to know that all operation should have
1212
an `is_compilable` flag set to true if they are compilable. Some operations
13-
such as the `add` operation are not compilable as their resolve method
13+
such as the `add` operation are not compilable as their transition method
1414
contains execution logic that will not be captured by the compiled command.
1515
"""
1616
from ngcsimlib.operations.baseOp import BaseOp

ngcsimlib/compilers/process.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from ngcsimlib.compilers.utils import compose
2+
from ngcsimlib.compilers.process_compiler.component_compiler import compile as compile_component
3+
from ngcsimlib.logger import warn
4+
from functools import wraps
5+
from ngcsimlib.utils import add_component_transition, add_transition_meta
6+
7+
class Process(object):
8+
def __init__(self):
9+
self._method = None
10+
11+
@property
12+
def pure(self):
13+
return self._method
14+
15+
def __rshift__(self, other):
16+
return self.transition(other)
17+
18+
def transition(self, transition_call):
19+
new_step = compile_component(transition_call)
20+
self._method = compose(self._method, new_step)
21+
return self
22+
23+
def execute(self, current_state, **kwargs):
24+
if self._method is None:
25+
warn("Attempting to execute a process with no transition steps")
26+
return
27+
return self.pure(current_state, **kwargs)
28+
29+
30+
def transition(output_compartments):
31+
def _wrapper(f):
32+
@wraps(f)
33+
def inner(*args, **kwargs):
34+
return f(*args, **kwargs)
35+
36+
inner.fargs = f.__func__.__code__.co_varnames[:f.__func__.__code__.co_argcount]
37+
inner.f = f
38+
inner.output_compartments = output_compartments
39+
40+
class_name = ".".join(f.__qualname__.split('.')[:-1])
41+
resolver_key = f.__qualname__.split('.')[-1]
42+
43+
add_component_transition(class_name, resolver_key,
44+
(f, output_compartments))
45+
46+
add_transition_meta(class_name, resolver_key,([], [], [], True))
47+
48+
return inner
49+
return _wrapper
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from ngcsimlib.compilers.process_compiler.op_compiler import compile as op_compile
2+
from ngcsimlib.compartment import Compartment
3+
from ngcsimlib.compilers.utils import compose
4+
5+
def compile(transition_method):
6+
composition = None
7+
component = transition_method.__self__
8+
9+
pure_fn = transition_method.f
10+
output = transition_method.output_compartments
11+
12+
varnames = transition_method.fargs
13+
14+
args = []
15+
compartments = []
16+
parameters = []
17+
18+
for name in varnames:
19+
if name not in component.__dict__.keys():
20+
args.append(name)
21+
elif Compartment.is_compartment(component.__dict__[name]):
22+
compartments.append(name)
23+
else:
24+
parameters.append(name)
25+
26+
for conn in component.connections:
27+
composition = compose(composition, op_compile(conn))
28+
29+
arg_methods = []
30+
for a in args:
31+
arg_methods.append((a, lambda current_state, **kwargs: kwargs.get(a, None)))
32+
33+
for p in parameters:
34+
arg_methods.append((p, lambda current_state, **kwargs: component.__dict__.get(p, None)))
35+
36+
for c in compartments:
37+
arg_methods.append((c, lambda current_state, **kwargs: current_state.get(component.__dict__[c].path, None)))
38+
39+
def compiled(current_state, **kwargs):
40+
kargvals = {key: m(current_state, **kwargs) for key, m in arg_methods}
41+
vals = pure_fn(**kargvals)
42+
if len(output) > 1:
43+
for v, o in zip(vals, output):
44+
current_state[component.__dict__[o].path] = v
45+
else:
46+
current_state[component.__dict__[output[0]].path] = vals
47+
return current_state
48+
49+
composition = compose(composition, compiled)
50+
51+
return composition
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from ngcsimlib.operations.baseOp import BaseOp
2+
3+
def compile(op):
4+
"""
5+
compiles the operation down to its execution order
6+
7+
Args:
8+
op: the operation to compile
9+
10+
Returns:
11+
the execution order needed to run this operation compiled
12+
"""
13+
arg_methods = []
14+
for s in op.sources:
15+
if isinstance(s, BaseOp):
16+
arg_methods.append(compile(s))
17+
else:
18+
arg_methods.append(lambda current_state, **kwargs: current_state[s.path])
19+
20+
def compiled(current_state, **kwargs):
21+
argvals = [m(current_state, **kwargs) for m in arg_methods]
22+
val = op.operation(*argvals)
23+
if op.destination is not None:
24+
current_state[op.destination.path] = val
25+
return current_state
26+
else:
27+
return val
28+
29+
return compiled

ngcsimlib/compilers/utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from ngcsimlib.utils.compartment import Get_Compartment_Batch, Set_Compartment_Batch
2+
3+
4+
def wrap_command(command):
5+
"""
6+
Wraps the provided command to provide the state of all compartments as input
7+
and saves the returned state to all compartments after running. Designed to
8+
be used with compiled commands
9+
10+
Args:
11+
command: the command to wrap
12+
13+
Returns:
14+
the output of the command after it's been executed
15+
"""
16+
17+
def _wrapped(**kwargs):
18+
vals = command(Get_Compartment_Batch(), **kwargs)
19+
Set_Compartment_Batch(vals)
20+
return vals
21+
22+
return _wrapped
23+
24+
25+
def compose(current_composition, next_method):
26+
if current_composition is None:
27+
return next_method
28+
29+
return lambda current_state, **kwargs: next_method(
30+
current_composition(current_state, **kwargs), **kwargs)

0 commit comments

Comments
 (0)