sierra-research 1.3.11__py3-none-any.whl → 1.5.0__py3-none-any.whl
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.
- sierra/__init__.py +3 -3
- sierra/core/__init__.py +3 -3
- sierra/core/batchroot.py +223 -0
- sierra/core/cmdline.py +681 -1057
- sierra/core/compare.py +11 -0
- sierra/core/config.py +96 -88
- sierra/core/engine.py +306 -0
- sierra/core/execenv.py +380 -0
- sierra/core/expdef.py +11 -0
- sierra/core/experiment/__init__.py +1 -0
- sierra/core/experiment/bindings.py +150 -101
- sierra/core/experiment/definition.py +414 -245
- sierra/core/experiment/spec.py +83 -85
- sierra/core/exproot.py +44 -0
- sierra/core/generators/__init__.py +10 -0
- sierra/core/generators/experiment.py +528 -0
- sierra/core/generators/generator_factory.py +138 -137
- sierra/core/graphs/__init__.py +23 -0
- sierra/core/graphs/bcbridge.py +94 -0
- sierra/core/graphs/heatmap.py +245 -324
- sierra/core/graphs/pathset.py +27 -0
- sierra/core/graphs/schema.py +77 -0
- sierra/core/graphs/stacked_line.py +341 -0
- sierra/core/graphs/summary_line.py +506 -0
- sierra/core/logging.py +3 -2
- sierra/core/models/__init__.py +3 -1
- sierra/core/models/info.py +19 -0
- sierra/core/models/interface.py +52 -122
- sierra/core/pipeline/__init__.py +2 -5
- sierra/core/pipeline/pipeline.py +228 -126
- sierra/core/pipeline/stage1/__init__.py +10 -0
- sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
- sierra/core/pipeline/stage2/__init__.py +10 -0
- sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
- sierra/core/pipeline/stage2/runner.py +401 -0
- sierra/core/pipeline/stage3/__init__.py +12 -0
- sierra/core/pipeline/stage3/gather.py +321 -0
- sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
- sierra/core/pipeline/stage4/__init__.py +12 -2
- sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
- sierra/core/pipeline/stage5/__init__.py +12 -0
- sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
- sierra/core/pipeline/yaml.py +48 -0
- sierra/core/plugin.py +529 -62
- sierra/core/proc.py +11 -0
- sierra/core/prod.py +11 -0
- sierra/core/ros1/__init__.py +5 -1
- sierra/core/ros1/callbacks.py +22 -21
- sierra/core/ros1/cmdline.py +59 -88
- sierra/core/ros1/generators.py +159 -175
- sierra/core/ros1/variables/__init__.py +3 -0
- sierra/core/ros1/variables/exp_setup.py +122 -116
- sierra/core/startup.py +106 -76
- sierra/core/stat_kernels.py +4 -5
- sierra/core/storage.py +13 -32
- sierra/core/trampoline.py +30 -0
- sierra/core/types.py +116 -71
- sierra/core/utils.py +103 -106
- sierra/core/variables/__init__.py +1 -1
- sierra/core/variables/base_variable.py +12 -17
- sierra/core/variables/batch_criteria.py +387 -481
- sierra/core/variables/builtin.py +135 -0
- sierra/core/variables/exp_setup.py +19 -39
- sierra/core/variables/population_size.py +72 -76
- sierra/core/variables/variable_density.py +44 -68
- sierra/core/vector.py +1 -1
- sierra/main.py +256 -88
- sierra/plugins/__init__.py +119 -0
- sierra/plugins/compare/__init__.py +14 -0
- sierra/plugins/compare/graphs/__init__.py +19 -0
- sierra/plugins/compare/graphs/cmdline.py +120 -0
- sierra/plugins/compare/graphs/comparator.py +291 -0
- sierra/plugins/compare/graphs/inter_controller.py +531 -0
- sierra/plugins/compare/graphs/inter_scenario.py +297 -0
- sierra/plugins/compare/graphs/namecalc.py +53 -0
- sierra/plugins/compare/graphs/outputroot.py +73 -0
- sierra/plugins/compare/graphs/plugin.py +147 -0
- sierra/plugins/compare/graphs/preprocess.py +172 -0
- sierra/plugins/compare/graphs/schema.py +37 -0
- sierra/plugins/engine/__init__.py +14 -0
- sierra/plugins/engine/argos/__init__.py +18 -0
- sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
- sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
- sierra/plugins/engine/argos/generators/engine.py +394 -0
- sierra/plugins/engine/argos/plugin.py +393 -0
- sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
- sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
- sierra/plugins/engine/argos/variables/cameras.py +240 -0
- sierra/plugins/engine/argos/variables/constant_density.py +112 -0
- sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
- sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
- sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
- sierra/plugins/engine/argos/variables/population_size.py +115 -0
- sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
- sierra/plugins/engine/argos/variables/rendering.py +108 -0
- sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
- sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
- sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
- sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
- sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
- sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
- sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
- sierra/plugins/engine/ros1robot/__init__.py +18 -0
- sierra/plugins/engine/ros1robot/cmdline.py +159 -0
- sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
- sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
- sierra/plugins/engine/ros1robot/plugin.py +410 -0
- sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
- sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
- sierra/plugins/execenv/__init__.py +11 -0
- sierra/plugins/execenv/hpc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
- sierra/plugins/execenv/hpc/cmdline.py +137 -0
- sierra/plugins/execenv/hpc/local/__init__.py +18 -0
- sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
- sierra/plugins/execenv/hpc/local/plugin.py +145 -0
- sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
- sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
- sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
- sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
- sierra/plugins/execenv/prefectserver/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
- sierra/plugins/execenv/prefectserver/flow.py +66 -0
- sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
- sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
- sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
- sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
- sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
- sierra/plugins/expdef/__init__.py +14 -0
- sierra/plugins/expdef/json/__init__.py +14 -0
- sierra/plugins/expdef/json/plugin.py +504 -0
- sierra/plugins/expdef/xml/__init__.py +14 -0
- sierra/plugins/expdef/xml/plugin.py +386 -0
- sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
- sierra/plugins/proc/collate/__init__.py +15 -0
- sierra/plugins/proc/collate/cmdline.py +47 -0
- sierra/plugins/proc/collate/plugin.py +271 -0
- sierra/plugins/proc/compress/__init__.py +18 -0
- sierra/plugins/proc/compress/cmdline.py +47 -0
- sierra/plugins/proc/compress/plugin.py +123 -0
- sierra/plugins/proc/decompress/__init__.py +18 -0
- sierra/plugins/proc/decompress/plugin.py +96 -0
- sierra/plugins/proc/imagize/__init__.py +15 -0
- sierra/plugins/proc/imagize/cmdline.py +49 -0
- sierra/plugins/proc/imagize/plugin.py +270 -0
- sierra/plugins/proc/modelrunner/__init__.py +16 -0
- sierra/plugins/proc/modelrunner/plugin.py +250 -0
- sierra/plugins/proc/statistics/__init__.py +15 -0
- sierra/plugins/proc/statistics/cmdline.py +64 -0
- sierra/plugins/proc/statistics/plugin.py +390 -0
- sierra/plugins/{hpc → prod}/__init__.py +1 -0
- sierra/plugins/prod/graphs/__init__.py +18 -0
- sierra/plugins/prod/graphs/cmdline.py +269 -0
- sierra/plugins/prod/graphs/collate.py +279 -0
- sierra/plugins/prod/graphs/inter/__init__.py +13 -0
- sierra/plugins/prod/graphs/inter/generate.py +83 -0
- sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
- sierra/plugins/prod/graphs/inter/line.py +134 -0
- sierra/plugins/prod/graphs/intra/__init__.py +15 -0
- sierra/plugins/prod/graphs/intra/generate.py +202 -0
- sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
- sierra/plugins/prod/graphs/intra/line.py +114 -0
- sierra/plugins/prod/graphs/plugin.py +103 -0
- sierra/plugins/prod/graphs/targets.py +63 -0
- sierra/plugins/prod/render/__init__.py +18 -0
- sierra/plugins/prod/render/cmdline.py +72 -0
- sierra/plugins/prod/render/plugin.py +282 -0
- sierra/plugins/storage/__init__.py +5 -0
- sierra/plugins/storage/arrow/__init__.py +18 -0
- sierra/plugins/storage/arrow/plugin.py +38 -0
- sierra/plugins/storage/csv/__init__.py +9 -0
- sierra/plugins/storage/csv/plugin.py +12 -5
- sierra/version.py +3 -2
- sierra_research-1.5.0.dist-info/METADATA +238 -0
- sierra_research-1.5.0.dist-info/RECORD +186 -0
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
- sierra/core/experiment/xml.py +0 -454
- sierra/core/generators/controller_generator_parser.py +0 -34
- sierra/core/generators/exp_creator.py +0 -351
- sierra/core/generators/exp_generators.py +0 -142
- sierra/core/graphs/scatterplot2D.py +0 -109
- sierra/core/graphs/stacked_line_graph.py +0 -251
- sierra/core/graphs/stacked_surface_graph.py +0 -220
- sierra/core/graphs/summary_line_graph.py +0 -371
- sierra/core/hpc/cmdline.py +0 -142
- sierra/core/models/graphs.py +0 -87
- sierra/core/pipeline/stage2/exp_runner.py +0 -286
- sierra/core/pipeline/stage3/imagizer.py +0 -149
- sierra/core/pipeline/stage3/run_collator.py +0 -317
- sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
- sierra/core/pipeline/stage4/graph_collator.py +0 -320
- sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
- sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
- sierra/core/pipeline/stage4/model_runner.py +0 -168
- sierra/core/pipeline/stage4/rendering.py +0 -283
- sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
- sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
- sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
- sierra/core/platform.py +0 -493
- sierra/core/plugin_manager.py +0 -369
- sierra/core/root_dirpath_generator.py +0 -241
- sierra/plugins/hpc/adhoc/plugin.py +0 -125
- sierra/plugins/hpc/local/plugin.py +0 -81
- sierra/plugins/hpc/pbs/__init__.py +0 -9
- sierra/plugins/hpc/pbs/plugin.py +0 -126
- sierra/plugins/hpc/slurm/__init__.py +0 -9
- sierra/plugins/hpc/slurm/plugin.py +0 -130
- sierra/plugins/platform/__init__.py +0 -9
- sierra/plugins/platform/argos/__init__.py +0 -9
- sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
- sierra/plugins/platform/argos/plugin.py +0 -337
- sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
- sierra/plugins/platform/argos/variables/cameras.py +0 -243
- sierra/plugins/platform/argos/variables/constant_density.py +0 -136
- sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
- sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
- sierra/plugins/platform/argos/variables/population_size.py +0 -102
- sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
- sierra/plugins/platform/argos/variables/rendering.py +0 -104
- sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
- sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
- sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
- sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
- sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
- sierra/plugins/platform/ros1robot/__init__.py +0 -9
- sierra/plugins/platform/ros1robot/cmdline.py +0 -175
- sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
- sierra/plugins/platform/ros1robot/plugin.py +0 -373
- sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
- sierra/plugins/robot/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/plugin.py +0 -194
- sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
- sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
- sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
- sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
- sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
- sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
- sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
- sierra_research-1.3.11.dist-info/METADATA +0 -492
- sierra_research-1.3.11.dist-info/RECORD +0 -133
- sierra_research-1.3.11.dist-info/top_level.txt +0 -1
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
sierra/core/plugin_manager.py
DELETED
@@ -1,369 +0,0 @@
|
|
1
|
-
# Copyright 2020 John Harwell, All rights reserved.
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
"""Simple plugin managers to make SIERRA OPEN/CLOSED.
|
5
|
-
|
6
|
-
"""
|
7
|
-
# Core packages
|
8
|
-
import importlib.util
|
9
|
-
import importlib
|
10
|
-
import os
|
11
|
-
import typing as tp
|
12
|
-
import sys
|
13
|
-
import logging
|
14
|
-
import pathlib
|
15
|
-
|
16
|
-
# 3rd party packages
|
17
|
-
import json
|
18
|
-
|
19
|
-
# Project packages
|
20
|
-
from sierra.core import types, utils
|
21
|
-
|
22
|
-
|
23
|
-
class BasePluginManager():
|
24
|
-
"""
|
25
|
-
Base class for common functionality.
|
26
|
-
"""
|
27
|
-
|
28
|
-
def __init__(self) -> None:
|
29
|
-
self.logger = logging.getLogger(__name__)
|
30
|
-
self.loaded = {} # type: tp.Dict[str, tp.Dict]
|
31
|
-
|
32
|
-
def available_plugins(self):
|
33
|
-
raise NotImplementedError
|
34
|
-
|
35
|
-
def load_plugin(self, name: str) -> None:
|
36
|
-
"""Load a plugin module.
|
37
|
-
|
38
|
-
"""
|
39
|
-
plugins = self.available_plugins()
|
40
|
-
if name not in plugins:
|
41
|
-
self.logger.fatal("Cannot locate plugin '%s'", name)
|
42
|
-
self.logger.fatal('Loaded plugins: %s\n',
|
43
|
-
json.dumps(self.loaded,
|
44
|
-
default=lambda x: '<ModuleSpec>',
|
45
|
-
indent=4))
|
46
|
-
raise Exception(f"Cannot locate plugin '{name}'")
|
47
|
-
|
48
|
-
if plugins[name]['type'] == 'pipeline':
|
49
|
-
parent_scope = pathlib.Path(plugins[name]['parent_dir']).name
|
50
|
-
scoped_name = f'{parent_scope}.{name}'
|
51
|
-
|
52
|
-
if name not in self.loaded:
|
53
|
-
module = importlib.util.module_from_spec(plugins[name]['spec'])
|
54
|
-
|
55
|
-
plugins[name]['spec'].loader.exec_module(module)
|
56
|
-
self.loaded[scoped_name] = {
|
57
|
-
'spec': plugins[name]['spec'],
|
58
|
-
'parent_dir': plugins[name]['parent_dir'],
|
59
|
-
'module': module
|
60
|
-
}
|
61
|
-
self.logger.debug("Loaded pipeline plugin '%s' from '%s'",
|
62
|
-
scoped_name,
|
63
|
-
plugins[name]['parent_dir'])
|
64
|
-
else:
|
65
|
-
self.logger.warning("Pipeline plugin '%s' already loaded", name)
|
66
|
-
elif plugins[name]['type'] == 'project':
|
67
|
-
# Projects are addressed directly without scoping. Only one project
|
68
|
-
# is loaded at a time, so this should be fine.
|
69
|
-
scoped_name = name
|
70
|
-
if name not in self.loaded:
|
71
|
-
self.loaded[scoped_name] = {
|
72
|
-
'spec': plugins[name]['spec'],
|
73
|
-
'parent_dir': plugins[name]['parent_dir'],
|
74
|
-
}
|
75
|
-
self.logger.debug("Loaded project plugin '%s' from '%s'",
|
76
|
-
scoped_name,
|
77
|
-
plugins[name]['parent_dir'])
|
78
|
-
else:
|
79
|
-
self.logger.warning("Project plugin '%s' already loaded", name)
|
80
|
-
|
81
|
-
def get_plugin(self, name: str) -> dict:
|
82
|
-
try:
|
83
|
-
return self.loaded[name]
|
84
|
-
except KeyError:
|
85
|
-
self.logger.fatal("No such plugin '%s'", name)
|
86
|
-
self.logger.fatal('Loaded plugins: %s\n',
|
87
|
-
json.dumps(self.loaded,
|
88
|
-
default=lambda x: '<ModuleSpec>',
|
89
|
-
indent=4))
|
90
|
-
raise
|
91
|
-
|
92
|
-
def get_plugin_module(self, name: str) -> types.ModuleType:
|
93
|
-
try:
|
94
|
-
return self.loaded[name]['module']
|
95
|
-
except KeyError:
|
96
|
-
self.logger.fatal("No such plugin '%s'", name)
|
97
|
-
self.logger.fatal('Loaded plugins: %s\n',
|
98
|
-
json.dumps(self.loaded,
|
99
|
-
default=lambda x: '<ModuleSpec>',
|
100
|
-
indent=4))
|
101
|
-
raise
|
102
|
-
|
103
|
-
def has_plugin(self, name: str) -> bool:
|
104
|
-
return name in self.loaded
|
105
|
-
|
106
|
-
|
107
|
-
class FilePluginManager(BasePluginManager):
|
108
|
-
"""Plugins are ``.py`` files within a root plugin directory.
|
109
|
-
|
110
|
-
Intended for use with :term:`models <Model>`.
|
111
|
-
|
112
|
-
"""
|
113
|
-
|
114
|
-
def __init__(self) -> None:
|
115
|
-
super().__init__()
|
116
|
-
self.search_root = None # type: tp.Optional[pathlib.Path]
|
117
|
-
|
118
|
-
def initialize(self, project: str, search_root: pathlib.Path) -> None:
|
119
|
-
self.search_root = search_root
|
120
|
-
|
121
|
-
def available_plugins(self) -> tp.Dict[str, tp.Dict]:
|
122
|
-
"""Get the available plugins in the configured plugin root.
|
123
|
-
|
124
|
-
"""
|
125
|
-
plugins = {}
|
126
|
-
assert self.search_root is not None, \
|
127
|
-
"FilePluginManager not initialized!"
|
128
|
-
|
129
|
-
for candidate in self.search_root.iterdir():
|
130
|
-
if candidate.is_file() and '.py' in candidate.name:
|
131
|
-
name = candidate.stem
|
132
|
-
spec = importlib.util.spec_from_file_location(name, candidate)
|
133
|
-
plugins[name] = {
|
134
|
-
'spec': spec,
|
135
|
-
'parent_dir': self.search_root,
|
136
|
-
'type': 'pipeline'
|
137
|
-
}
|
138
|
-
return plugins
|
139
|
-
|
140
|
-
|
141
|
-
class DirectoryPluginManager(BasePluginManager):
|
142
|
-
"""Plugins are `directories` found in a root plugin directory.
|
143
|
-
|
144
|
-
Intended for use with :term:`Pipeline plugins <plugin>`.
|
145
|
-
|
146
|
-
"""
|
147
|
-
|
148
|
-
def __init__(self, search_root: pathlib.Path) -> None:
|
149
|
-
super().__init__()
|
150
|
-
self.search_root = search_root
|
151
|
-
self.main_module = 'plugin'
|
152
|
-
|
153
|
-
def initialize(self, project: str) -> None:
|
154
|
-
pass
|
155
|
-
|
156
|
-
def available_plugins(self):
|
157
|
-
"""
|
158
|
-
Find all pipeline plugins in all directories within the search root.
|
159
|
-
"""
|
160
|
-
plugins = {}
|
161
|
-
try:
|
162
|
-
for location in self.search_root.iterdir():
|
163
|
-
plugin = location / (self.main_module + '.py')
|
164
|
-
|
165
|
-
if location.is_dir() and plugin in location.iterdir():
|
166
|
-
spec = importlib.util.spec_from_file_location(location.name,
|
167
|
-
plugin)
|
168
|
-
plugins[location.name] = {
|
169
|
-
'parent_dir': self.search_root,
|
170
|
-
'spec': spec,
|
171
|
-
'type': 'pipeline'
|
172
|
-
}
|
173
|
-
except FileNotFoundError:
|
174
|
-
pass
|
175
|
-
|
176
|
-
return plugins
|
177
|
-
|
178
|
-
|
179
|
-
class ProjectPluginManager(BasePluginManager):
|
180
|
-
"""Plugins are `directories` found in a root plugin directory.
|
181
|
-
|
182
|
-
Intended for use with :term:`Project plugins <plugin>`.
|
183
|
-
|
184
|
-
"""
|
185
|
-
|
186
|
-
def __init__(self, search_root: pathlib.Path, project: str) -> None:
|
187
|
-
super().__init__()
|
188
|
-
|
189
|
-
self.search_root = search_root
|
190
|
-
self.project = project
|
191
|
-
|
192
|
-
def initialize(self, project: str) -> None:
|
193
|
-
# Update PYTHONPATH with the directory containing the project so imports
|
194
|
-
# of the form 'import project.module' work.
|
195
|
-
#
|
196
|
-
# 2021/07/19: If you put the entries at the end of sys.path it
|
197
|
-
# doesn't work for some reason...
|
198
|
-
sys.path = [str(self.search_root)] + sys.path[0:]
|
199
|
-
|
200
|
-
def available_plugins(self):
|
201
|
-
"""
|
202
|
-
Find all pipeline plugins in all directories within the search root.
|
203
|
-
"""
|
204
|
-
plugins = {}
|
205
|
-
try:
|
206
|
-
for location in self.search_root.iterdir():
|
207
|
-
if self.project in location.name:
|
208
|
-
plugins[location.name] = {
|
209
|
-
'parent_dir': self.search_root,
|
210
|
-
'spec': None,
|
211
|
-
'type': 'project'
|
212
|
-
}
|
213
|
-
|
214
|
-
except FileNotFoundError:
|
215
|
-
pass
|
216
|
-
|
217
|
-
return plugins
|
218
|
-
|
219
|
-
|
220
|
-
class CompositePluginManager(BasePluginManager):
|
221
|
-
def __init__(self) -> None:
|
222
|
-
super().__init__()
|
223
|
-
self.components = [] # type: tp.List[tp.Union[DirectoryPluginManager,ProjectPluginManager]]
|
224
|
-
|
225
|
-
def initialize(self,
|
226
|
-
project: str,
|
227
|
-
search_path: tp.List[pathlib.Path]) -> None:
|
228
|
-
self.logger.debug("Initializing with plugin search path %s",
|
229
|
-
[str(p) for p in search_path])
|
230
|
-
for d in search_path:
|
231
|
-
project_path = d / project
|
232
|
-
|
233
|
-
if utils.path_exists(project_path):
|
234
|
-
project_plugin = ProjectPluginManager(d, project)
|
235
|
-
self.components.append(project_plugin)
|
236
|
-
else:
|
237
|
-
pipeline_plugin = DirectoryPluginManager(d)
|
238
|
-
self.components.append(pipeline_plugin)
|
239
|
-
|
240
|
-
for c in self.components:
|
241
|
-
c.initialize(project)
|
242
|
-
|
243
|
-
def available_plugins(self):
|
244
|
-
plugins = {}
|
245
|
-
|
246
|
-
for c in self.components:
|
247
|
-
plugins.update(c.available_plugins())
|
248
|
-
|
249
|
-
return plugins
|
250
|
-
|
251
|
-
|
252
|
-
# Singletons
|
253
|
-
pipeline = CompositePluginManager()
|
254
|
-
models = FilePluginManager()
|
255
|
-
|
256
|
-
|
257
|
-
def module_exists(name: str) -> bool:
|
258
|
-
"""
|
259
|
-
Check if a module exists before trying to import it.
|
260
|
-
"""
|
261
|
-
try:
|
262
|
-
_ = __import__(name)
|
263
|
-
except ImportError:
|
264
|
-
return False
|
265
|
-
else:
|
266
|
-
return True
|
267
|
-
|
268
|
-
|
269
|
-
def module_load(name: str) -> types.ModuleType:
|
270
|
-
"""
|
271
|
-
Import the specified module.
|
272
|
-
"""
|
273
|
-
return __import__(name, fromlist=["*"])
|
274
|
-
|
275
|
-
|
276
|
-
def bc_load(cmdopts: types.Cmdopts, category: str):
|
277
|
-
"""
|
278
|
-
Load the specified :term:`Batch Criteria`.
|
279
|
-
"""
|
280
|
-
path = f'variables.{category}'
|
281
|
-
return module_load_tiered(project=cmdopts['project'],
|
282
|
-
platform=cmdopts['platform'],
|
283
|
-
path=path)
|
284
|
-
|
285
|
-
|
286
|
-
def module_load_tiered(path: str,
|
287
|
-
project: tp.Optional[str] = None,
|
288
|
-
platform: tp.Optional[str] = None) -> types.ModuleType:
|
289
|
-
"""Attempt to load the specified python module with tiered precedence.
|
290
|
-
|
291
|
-
Generally, the precedence is project -> project submodule -> platform module
|
292
|
-
-> SIERRA core module, to allow users to override SIERRA core functionality
|
293
|
-
with ease. Specifically:
|
294
|
-
|
295
|
-
#. Check if the requested module is a project. If it is, return it.
|
296
|
-
|
297
|
-
#. Check if the requested module is a part of a project (i.e.,
|
298
|
-
``<project>.<path>`` exists). If it does, return it. This requires that
|
299
|
-
:envvar:`SIERRA_PLUGIN_PATH` to be set properly.
|
300
|
-
|
301
|
-
#. Check if the requested module is provided by the platform plugin (i.e.,
|
302
|
-
``sierra.platform.<platform>.<path>`` exists). If it does, return it.
|
303
|
-
|
304
|
-
#. Check if the requested module is part of the SIERRA core (i.e.,
|
305
|
-
``sierra.core.<path>`` exists). If it does, return it.
|
306
|
-
|
307
|
-
If no match was found using any of these, throw an error.
|
308
|
-
|
309
|
-
"""
|
310
|
-
# First, see if the requested module is a project
|
311
|
-
if module_exists(path):
|
312
|
-
logging.trace("Using project path '%s'", path) # type: ignore
|
313
|
-
return module_load(path)
|
314
|
-
|
315
|
-
# First, see if the requested module is part of the project plugin
|
316
|
-
if project is not None:
|
317
|
-
component_path = f'{project}.{path}'
|
318
|
-
if module_exists(component_path):
|
319
|
-
logging.trace("Using project component path '%s'", # type: ignore
|
320
|
-
component_path)
|
321
|
-
return module_load(component_path)
|
322
|
-
else:
|
323
|
-
logging.trace("Project component path '%s' does not exist", # type: ignore
|
324
|
-
component_path)
|
325
|
-
|
326
|
-
# If that didn't work, check the platform plugin
|
327
|
-
if platform is not None:
|
328
|
-
# We manually add 'sierra.plugins' here, rather than adding the
|
329
|
-
# necessary directory to PYTHONPATH so that we don't accidentally get
|
330
|
-
# the files from other non-platform plugins with the same name as the
|
331
|
-
# platform plugin file we are interested in getting picked.
|
332
|
-
platform_path = f'sierra.plugins.{platform}.{path}'
|
333
|
-
if module_exists(platform_path):
|
334
|
-
logging.trace("Using platform component path '%s'", # type: ignore
|
335
|
-
platform_path)
|
336
|
-
return module_load(platform_path)
|
337
|
-
else:
|
338
|
-
logging.trace("Platform component path '%s' does not exist", # type: ignore
|
339
|
-
platform_path)
|
340
|
-
|
341
|
-
# If that didn't work, then check the SIERRA core
|
342
|
-
core_path = f'sierra.core.{path}'
|
343
|
-
if module_exists(core_path):
|
344
|
-
logging.trace("Using SIERRA core path '%s'", # type: ignore
|
345
|
-
core_path)
|
346
|
-
return module_load(core_path)
|
347
|
-
else:
|
348
|
-
logging.trace("SIERRA core path '%s' does not exist", # type: ignore
|
349
|
-
core_path)
|
350
|
-
|
351
|
-
# Module does not exist
|
352
|
-
error = (f"project: '{project}' "
|
353
|
-
f"platform: '{platform}' "
|
354
|
-
f"path: '{path}' "
|
355
|
-
f"sys.path: {sys.path}")
|
356
|
-
raise ImportError(error)
|
357
|
-
|
358
|
-
|
359
|
-
__api__ = [
|
360
|
-
'BasePluginManager',
|
361
|
-
'FilePluginManager',
|
362
|
-
'DirectoryPluginManager',
|
363
|
-
'ProjectPluginManager',
|
364
|
-
'CompositePluginManager',
|
365
|
-
'module_exists',
|
366
|
-
'module_load',
|
367
|
-
'bc_load',
|
368
|
-
'module_load_tiered'
|
369
|
-
]
|
@@ -1,241 +0,0 @@
|
|
1
|
-
# Copyright 2018 John Harwell, All rights reserved.
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""Functions for generating root directory paths for a batch experiment.
|
6
|
-
|
7
|
-
- The batch experiment root. ALL files (inputs and outputs) are written to this
|
8
|
-
directory, which will be under ``--sierra-root``. Named using a combination of
|
9
|
-
``--scenario`` (block distribution + arena dimensions) and
|
10
|
-
``--batch-criteria`` in order to guarantee uniqueness among batch roots
|
11
|
-
anytime the batch criteria or scenario change.
|
12
|
-
|
13
|
-
- The batch input root. All input files will be generated under this root
|
14
|
-
directory. Named ``<batch experiment root>/exp-inputs``.
|
15
|
-
|
16
|
-
- The batch output root. All output files will accrue under this root
|
17
|
-
directory. Each experiment will get their own directory in this root for its
|
18
|
-
outputs to accrue into. Named ``<batch experiment root>/exp-outputs``.
|
19
|
-
|
20
|
-
- The batch graph root. All generated graphs will acrrue under this root
|
21
|
-
directory. Each experiment will get their own directory in this root for their
|
22
|
-
graphs to accrue into. Named ``<batch experiment root>/graphs``.
|
23
|
-
|
24
|
-
- The batch model root. All model outputs will accrue under this root
|
25
|
-
directory. Each experiment will get their own directory in this root for their
|
26
|
-
model outputs to accrue into. Named ``<batch experiment root>/models``.
|
27
|
-
|
28
|
-
- The batch statistics root. All statistics generated during stage 3 will accrue
|
29
|
-
under this root directory. Each experiment will get their own directory in
|
30
|
-
this root for their statistics. Named
|
31
|
-
``<batch experiment root>/statistics``.
|
32
|
-
|
33
|
-
- The batch imagizing root. All images generated during stage 3 will accrue
|
34
|
-
under this root directory. Each experiment will get their own directory in
|
35
|
-
this root for their images. Named
|
36
|
-
``<batch experiment root>/images``.
|
37
|
-
|
38
|
-
- The batch video root. All videos rendered during stage 4 will accrue
|
39
|
-
under this root directory. Each experiment will get their own directory in
|
40
|
-
this root for their videos. Named
|
41
|
-
``<batch experiment root>/videos``.
|
42
|
-
|
43
|
-
- The batch scratch root. All GNU parallel outputs, ``--exec-env`` artifacts
|
44
|
-
will appear under here. Each experiment will get their own directory in this
|
45
|
-
root for their own scratch. This root is separate from experiment inputs to
|
46
|
-
make checking for segfaults, tar-ing experiments, etc. easier. Named ``<batch
|
47
|
-
experiment root>/scratch``.
|
48
|
-
|
49
|
-
"""
|
50
|
-
# Core packages
|
51
|
-
import os
|
52
|
-
import typing as tp
|
53
|
-
import logging
|
54
|
-
import argparse
|
55
|
-
import pathlib
|
56
|
-
|
57
|
-
# 3rd party packages
|
58
|
-
|
59
|
-
# Project packages
|
60
|
-
|
61
|
-
|
62
|
-
def from_cmdline(args: argparse.Namespace) -> tp.Dict[str, pathlib.Path]:
|
63
|
-
"""Generate directory paths directly from cmdline arguments.
|
64
|
-
|
65
|
-
"""
|
66
|
-
template = pathlib.Path(args.template_input_file)
|
67
|
-
|
68
|
-
# Remove all '-' from the template input file stem so we know the only '-'
|
69
|
-
# that are in it are ones that we put there.
|
70
|
-
template_stem = template.stem.replace('-', '')
|
71
|
-
|
72
|
-
batch_leaf = gen_batch_leaf(args.batch_criteria,
|
73
|
-
str(template_stem),
|
74
|
-
args.scenario)
|
75
|
-
|
76
|
-
return regen_from_exp(args.sierra_root,
|
77
|
-
args.project,
|
78
|
-
batch_leaf,
|
79
|
-
args.controller)
|
80
|
-
|
81
|
-
|
82
|
-
def parse_batch_leaf(root: str) -> tp.Tuple[str, str, tp.List[str]]:
|
83
|
-
"""Parse a batch root (dirpath leaf).
|
84
|
-
|
85
|
-
Parsed into (template input file basename, scenario, batch criteria list)
|
86
|
-
string components as they would have been specified on the cmdline.
|
87
|
-
|
88
|
-
"""
|
89
|
-
template_stem = ''.join(root.split('-')[0])
|
90
|
-
scenario_and_bc = root.split('-')[1].split('+')
|
91
|
-
scenario = scenario_and_bc[0]
|
92
|
-
bc = scenario_and_bc[1:] # type: tp.Union[tp.List[str],str]
|
93
|
-
|
94
|
-
if not isinstance(bc, list): # Univariate batch criteria
|
95
|
-
bc = [bc]
|
96
|
-
|
97
|
-
return (template_stem, scenario, bc)
|
98
|
-
|
99
|
-
|
100
|
-
def gen_batch_leaf(criteria: tp.List[str],
|
101
|
-
template_stem: str,
|
102
|
-
scenario: str) -> str:
|
103
|
-
leaf = template_stem + '-' + scenario + '+' + '+'.join(criteria)
|
104
|
-
logging.debug("Generated batch leaf %s", leaf)
|
105
|
-
|
106
|
-
return leaf
|
107
|
-
|
108
|
-
|
109
|
-
def regen_from_exp(sierra_rpath: str,
|
110
|
-
project: str,
|
111
|
-
batch_leaf: str,
|
112
|
-
controller: str) -> tp.Dict[str, pathlib.Path]:
|
113
|
-
"""Regenerate directory paths from a previously created batch experiment.
|
114
|
-
|
115
|
-
Arguments:
|
116
|
-
|
117
|
-
sierra_rpath: The path to the root directory where SIERRA should store
|
118
|
-
everything.
|
119
|
-
|
120
|
-
project: The name of the project plugin used.
|
121
|
-
|
122
|
-
criteria: List of strings from the cmdline specification of the batch
|
123
|
-
criteria.
|
124
|
-
|
125
|
-
batch_root: The name of the directory that will be the root of the batch
|
126
|
-
experiment (not including its parent).
|
127
|
-
|
128
|
-
controller: The name of the controller used.
|
129
|
-
|
130
|
-
"""
|
131
|
-
template_stem, scenario, bc = parse_batch_leaf(batch_leaf)
|
132
|
-
|
133
|
-
root = gen_batch_root(sierra_rpath,
|
134
|
-
project,
|
135
|
-
bc,
|
136
|
-
scenario,
|
137
|
-
controller,
|
138
|
-
template_stem)
|
139
|
-
logging.info('Generated batch root %s', root)
|
140
|
-
return {
|
141
|
-
'batch_root': root,
|
142
|
-
'batch_input_root': _gen_input_root(root),
|
143
|
-
'batch_output_root': _gen_output_root(root),
|
144
|
-
'batch_graph_root': _gen_graph_root(root),
|
145
|
-
'batch_model_root': _gen_model_root(root),
|
146
|
-
'batch_stat_root': _gen_statistics_root(root),
|
147
|
-
'batch_imagize_root': _gen_imagize_root(root),
|
148
|
-
'batch_video_root': _gen_video_root(root),
|
149
|
-
'batch_stat_collate_root': _gen_stat_collate_root(root),
|
150
|
-
'batch_graph_collate_root': _gen_graph_collate_root(root),
|
151
|
-
'batch_scratch_root': _gen_scratch_root(root)
|
152
|
-
}
|
153
|
-
|
154
|
-
|
155
|
-
def gen_batch_root(root: str,
|
156
|
-
project: str,
|
157
|
-
criteria: tp.List[str],
|
158
|
-
scenario: str,
|
159
|
-
controller: str,
|
160
|
-
template_stem: str) -> pathlib.Path:
|
161
|
-
"""Generate the directory path for the batch root directory.
|
162
|
-
|
163
|
-
The directory path depends on all of the input arguments to this function,
|
164
|
-
and if ANY of the arguments change, so will the generated path.
|
165
|
-
|
166
|
-
Batch root is:
|
167
|
-
<sierra_root>/<project>/<template_basename>-<scenario>+<criteria0>+<criteria1>
|
168
|
-
|
169
|
-
Arguments:
|
170
|
-
|
171
|
-
root: The path to the root directory where SIERRA should store
|
172
|
-
everything.
|
173
|
-
|
174
|
-
project: The name of the project plugin used.
|
175
|
-
|
176
|
-
criteria: List of strings from the cmdline specification of the batch
|
177
|
-
criteria.
|
178
|
-
|
179
|
-
scenario: The cmdline specification of ``--scenario``
|
180
|
-
|
181
|
-
batch_root: The name of the directory that will be the root of the batch
|
182
|
-
experiment (not including its parent).
|
183
|
-
|
184
|
-
controller: The name of the controller used.
|
185
|
-
|
186
|
-
"""
|
187
|
-
batch_leaf = gen_batch_leaf(criteria, template_stem, scenario)
|
188
|
-
|
189
|
-
# Don't reslove() the path--that makes symlinked dirs under $HOME through
|
190
|
-
# errors which are fatal from pathlib's POV, but actually harmless.
|
191
|
-
sierra_root = pathlib.Path(root)
|
192
|
-
|
193
|
-
return sierra_root / project / controller / batch_leaf
|
194
|
-
|
195
|
-
|
196
|
-
def _gen_output_root(root: pathlib.Path) -> pathlib.Path:
|
197
|
-
return root / "exp-outputs"
|
198
|
-
|
199
|
-
|
200
|
-
def _gen_input_root(root: pathlib.Path) -> pathlib.Path:
|
201
|
-
return root / "exp-inputs"
|
202
|
-
|
203
|
-
|
204
|
-
def _gen_graph_root(root: pathlib.Path) -> pathlib.Path:
|
205
|
-
return root / "graphs"
|
206
|
-
|
207
|
-
|
208
|
-
def _gen_model_root(root: pathlib.Path) -> pathlib.Path:
|
209
|
-
return root / "models"
|
210
|
-
|
211
|
-
|
212
|
-
def _gen_statistics_root(root: pathlib.Path) -> pathlib.Path:
|
213
|
-
return root / "statistics"
|
214
|
-
|
215
|
-
|
216
|
-
def _gen_scratch_root(root: pathlib.Path) -> pathlib.Path:
|
217
|
-
return root / "scratch"
|
218
|
-
|
219
|
-
|
220
|
-
def _gen_imagize_root(root: pathlib.Path) -> pathlib.Path:
|
221
|
-
return root / "imagize"
|
222
|
-
|
223
|
-
|
224
|
-
def _gen_video_root(root: pathlib.Path) -> pathlib.Path:
|
225
|
-
return root / "videos"
|
226
|
-
|
227
|
-
|
228
|
-
def _gen_stat_collate_root(root: pathlib.Path) -> pathlib.Path:
|
229
|
-
return root / "statistics" / "collated"
|
230
|
-
|
231
|
-
|
232
|
-
def _gen_graph_collate_root(root: pathlib.Path) -> pathlib.Path:
|
233
|
-
return root / "graphs" / "collated"
|
234
|
-
|
235
|
-
|
236
|
-
__api__ = [
|
237
|
-
'from_cmdline',
|
238
|
-
'regen_from_exp',
|
239
|
-
'parse_batch_leaf',
|
240
|
-
'gen_batch_root'
|
241
|
-
]
|