Skip to content

Commit 9099a1a

Browse files
willgebhardtrxng8ago109
authored
Compiled (#8)
* Start of rewrite * fix argument bugs for resolver * address Will's comment on line 26 * remove loop and params generator functionalities in command compilation. * add representation debugging strings * add more debugging strings * Fixed artifact bug in connection compiling * remove printing * add component to context functionality * add repr functionality * Compile changes - Pattern matches argument input for pure function remove order constraint - Pattern matches argument input from wrapped function to remove output_compartment specification - Added functionality to account for nested operations * Cleaned up aspects of the code * Made compilers Moved all the compilers to their own directory. * Missed parse call * Added save and load functionality * Actually loads custom folder * fixed small ordering error in command-compiler * Fixed formatting --------- Co-authored-by: Viet Nguyen <[email protected]> Co-authored-by: Alex Ororbia <[email protected]>
1 parent df804b8 commit 9099a1a

File tree

16 files changed

+826
-185
lines changed

16 files changed

+826
-185
lines changed

ngcsimlib/__init__.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
from . import utils
22
from . import controller
33
from . import commands
4-
from . import logger
54

65
import argparse, os, warnings, json
76
from types import SimpleNamespace
8-
from pathlib import Path
9-
from sys import argv
107
from importlib import import_module
118
from ngcsimlib.configManager import init_config, get_config
129

@@ -68,12 +65,4 @@ def configure():
6865
"additional information")
6966
return
7067

71-
7268
init_config(config_path)
73-
74-
75-
if not Path(argv[0]).name == "sphinx-build" or Path(argv[0]).name == "build.py":
76-
if "readthedocs" not in argv[0]: ## prevent readthedocs execution of preload
77-
configure()
78-
logger.init_logging()
79-
preload_modules()

ngcsimlib/bundle_rules.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

ngcsimlib/commands/command.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from abc import ABC, abstractmethod
2-
from ngcsimlib.utils import check_attributes
2+
from ngcsimlib.utils import check_attributes, get_current_context
3+
34

45

56
class Command(ABC):
@@ -11,6 +12,18 @@ class Command(ABC):
1112
attributes are present on each component. Note that this step does not
1213
ensure types or values, just that they do or do not exist.
1314
"""
15+
16+
"""
17+
The Compile key is the name of the resolver the compile function will look for
18+
when compiling this command. If unset the compile will fail.
19+
"""
20+
compile_key = None
21+
22+
def __new__(cls, components=None, command_name=None, *args, **kwargs):
23+
if get_current_context() is not None:
24+
get_current_context().register_command(cls.__name__, *args, components=components, command_name=command_name, **kwargs)
25+
return super().__new__(cls)
26+
1427
def __init__(self, components=None, command_name=None, required_calls=None):
1528
"""
1629
Required calls on Components: ['name']
@@ -22,13 +35,20 @@ def __init__(self, components=None, command_name=None, required_calls=None):
2235
2336
command_name: the name of the command on the controller
2437
"""
38+
2539
self.name = str(command_name)
40+
2641
self.components = {}
2742
required_calls = ['name'] if required_calls is None else required_calls + ['name']
2843
for comp in components:
2944
if check_attributes(comp, required_calls, fatal=True):
3045
self.components[comp.name] = comp
3146

47+
48+
get_current_context().add_command(self)
49+
50+
3251
@abstractmethod
3352
def __call__(self, *args, **kwargs):
3453
pass
54+

ngcsimlib/compartment.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from ngcsimlib.operations import BaseOp, overwrite
2+
from ngcsimlib.utils import Set_Compartment_Batch, get_current_path
3+
import uuid
4+
5+
6+
class Compartment:
7+
@classmethod
8+
def is_compartment(cls, obj):
9+
return hasattr(obj, "_is_compartment")
10+
11+
def __init__(self, initial_value=None, static=False):
12+
13+
self._is_compartment = True
14+
self.__add_connection = None
15+
self._static = static
16+
self.value = initial_value
17+
self._uid = uuid.uuid4()
18+
self.name = None
19+
self.path = None
20+
21+
def _setup(self, current_component, key):
22+
self.__add_connection = current_component.add_connection
23+
self.name = current_component.name + "/" + key
24+
self.path = get_current_path() + "/" + self.name
25+
Set_Compartment_Batch({str(self.path): self})
26+
27+
def set(self, value):
28+
if not self._static:
29+
self.value = value
30+
else:
31+
raise RuntimeError("Can not assign value to static compartment")
32+
33+
def clamp(self, value):
34+
self.set(value)
35+
36+
def __repr__(self):
37+
return f"[{self.name}]"
38+
39+
def __str__(self):
40+
return str(self.value)
41+
42+
def __lshift__(self, other) -> None:
43+
if isinstance(other, BaseOp):
44+
other.set_destination(self)
45+
self.__add_connection(other)
46+
else:
47+
op = overwrite(other)
48+
op.set_destination(self)
49+
self.__add_connection(op)

ngcsimlib/compilers/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .command_compiler import compile as compile_command, dynamic_compile, wrap_command
2+
from .component_compiler import compile as compile_component
3+
from .op_compiler import compile as compile_op
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from ngcsimlib.compilers.component_compiler import parse as parse_component, compile as compile_component
2+
from ngcsimlib.compilers.op_compiler import parse as parse_connection
3+
from ngcsimlib.utils import Get_Compartment_Batch, Set_Compartment_Batch
4+
5+
6+
def _compile(compile_key, components):
7+
assert compile_key is not None
8+
## for each component, get compartments, get output compartments
9+
resolvers = {}
10+
for c_name, component in components.items():
11+
resolvers[c_name] = parse_component(component, compile_key)
12+
13+
needed_args = []
14+
needed_comps = []
15+
16+
for c_name, component in components.items():
17+
_, outs, args, params, comps = resolvers[c_name]
18+
for _, a in args:
19+
if a not in needed_args:
20+
needed_args.append(a)
21+
22+
for connection in component.connections:
23+
inputs, outputs = parse_connection(connection)
24+
ncs = [str(i) for i in inputs]
25+
for nc in ncs:
26+
if nc not in needed_comps:
27+
needed_comps.append(nc)
28+
29+
for _, comp in comps:
30+
path = str(component.__dict__[comp].path)
31+
if path not in needed_comps:
32+
needed_comps.append(path)
33+
arg_order = needed_args + needed_comps
34+
exc_order = []
35+
for c_name, component in components.items():
36+
exc_order.extend(compile_component(component, resolvers[c_name], arg_order))
37+
38+
def compiled(compartment_values, *cargs):
39+
for exc, outs, name in exc_order:
40+
_comps = [compartment_values[key] for key in needed_comps]
41+
vals = exc(*cargs, *_comps)
42+
if len(outs) == 1:
43+
compartment_values[outs[0]] = vals
44+
elif len(outs) > 1:
45+
for v, t in zip(vals, outs):
46+
compartment_values[t] = v
47+
return compartment_values
48+
49+
return compiled, needed_args
50+
51+
52+
def compile(command):
53+
return _compile(command.compile_key, command.components)
54+
55+
56+
def dynamic_compile(*components, compile_key=None):
57+
assert compile_key is not None
58+
return _compile(compile_key, {c.name: c for c in components})
59+
60+
61+
def wrap_command(command):
62+
def _wrapped(*args):
63+
vals = command(Get_Compartment_Batch(), *args)
64+
Set_Compartment_Batch(vals)
65+
return vals
66+
67+
return _wrapped
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from ngcsimlib.compilers.op_compiler import compile as op_compile
2+
3+
from ngcsimlib.utils import get_resolver
4+
from ngcsimlib.compartment import Compartment
5+
6+
7+
def parse(component, compile_key):
8+
(pure_fn, output_compartments), (args, parameters, compartments, parse_varnames) = \
9+
get_resolver(component.__class__.__name__, compile_key)
10+
11+
if parse_varnames:
12+
args = []
13+
parameters = []
14+
compartments = []
15+
varnames = pure_fn.__func__.__code__.co_varnames[:pure_fn.__func__.__code__.co_argcount]
16+
17+
for idx, n in enumerate(varnames):
18+
if n not in component.__dict__.keys():
19+
args.append((idx, n))
20+
elif Compartment.is_compartment(component.__dict__[n]):
21+
compartments.append((idx, n))
22+
else:
23+
parameters.append((idx, n))
24+
25+
if output_compartments is None:
26+
output_compartments = compartments[:]
27+
28+
return (pure_fn, output_compartments, args, parameters, compartments)
29+
30+
31+
def compile(component, resolver, arg_order):
32+
exc_order = []
33+
pure_fn, outs, _args, params, comps = resolver
34+
35+
### Op resolve
36+
for connection in component.connections:
37+
exc_order.append(op_compile(connection, arg_order))
38+
39+
### Component resolve
40+
comp_ids = [str(component.__dict__[comp].path) for _, comp in comps]
41+
out_ids = [str(component.__dict__[comp].path) for comp in outs]
42+
43+
funParams = [component.__dict__[narg] for _, narg in (list(params))]
44+
45+
arg_locs = [loc for loc, _ in _args]
46+
param_locs = [loc for loc, _ in params]
47+
comp_locs = [loc for loc, _ in comps]
48+
49+
def compiled(*args):
50+
funArgs = [args[arg_order.index(narg)] for _, narg in (list(_args))]
51+
funComps = [args[arg_order.index(narg)] for narg in comp_ids]
52+
53+
_arg_loc = 0
54+
_param_loc = 0
55+
_comps_loc = 0
56+
57+
fargs = []
58+
for i in range(len(arg_locs) + len(param_locs) + len(comp_locs)):
59+
if i in arg_locs:
60+
fargs.append(funArgs[_arg_loc])
61+
_arg_loc += 1
62+
elif i in param_locs:
63+
fargs.append(funParams[_param_loc])
64+
_param_loc += 1
65+
else:
66+
fargs.append(funComps[_comps_loc])
67+
_comps_loc += 1
68+
69+
return pure_fn(*fargs)
70+
71+
exc_order.append((compiled, out_ids, component.name))
72+
return exc_order

ngcsimlib/compilers/op_compiler.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from ngcsimlib.operations import BaseOp
2+
3+
4+
def parse(op):
5+
assert op.is_compilable
6+
inputs = []
7+
for s in op.sources:
8+
if isinstance(s, BaseOp):
9+
needed_inputs, dest = parse(s)
10+
assert dest is None
11+
for inp in needed_inputs:
12+
if inp not in inputs:
13+
inputs.append(inp)
14+
else:
15+
inputs.append(s.path)
16+
17+
return inputs, op.destination.name if op.destination is not None else None
18+
19+
20+
def compile(op, arg_order):
21+
exc_order = []
22+
ops = []
23+
24+
for idx, s in enumerate(op.sources):
25+
if isinstance(s, BaseOp):
26+
exc_order.append(compile(s, arg_order))
27+
ops.append(idx)
28+
29+
output = op.destination.path if op.destination is not None else None
30+
31+
iids = []
32+
for s in op.sources:
33+
if isinstance(s, BaseOp):
34+
pass
35+
else:
36+
iids.append(str(s.path))
37+
38+
def _op_compiled(*args):
39+
computed_values = [cmd(*args) for cmd, _, _ in exc_order]
40+
compartment_args = [args[arg_order.index(narg)] for narg in iids]
41+
42+
_val_loc = 0
43+
_arg_loc = 0
44+
45+
_args = []
46+
for i in range(len(op.sources)):
47+
if i in ops:
48+
_args.append(computed_values[_val_loc])
49+
_val_loc += 1
50+
else:
51+
_args.append(compartment_args[_arg_loc])
52+
_arg_loc += 1
53+
54+
return op.operation(*_args)
55+
56+
return (_op_compiled, [str(output)], "op")

0 commit comments

Comments
 (0)