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.
Files changed (254) hide show
  1. sierra/__init__.py +3 -3
  2. sierra/core/__init__.py +3 -3
  3. sierra/core/batchroot.py +223 -0
  4. sierra/core/cmdline.py +681 -1057
  5. sierra/core/compare.py +11 -0
  6. sierra/core/config.py +96 -88
  7. sierra/core/engine.py +306 -0
  8. sierra/core/execenv.py +380 -0
  9. sierra/core/expdef.py +11 -0
  10. sierra/core/experiment/__init__.py +1 -0
  11. sierra/core/experiment/bindings.py +150 -101
  12. sierra/core/experiment/definition.py +414 -245
  13. sierra/core/experiment/spec.py +83 -85
  14. sierra/core/exproot.py +44 -0
  15. sierra/core/generators/__init__.py +10 -0
  16. sierra/core/generators/experiment.py +528 -0
  17. sierra/core/generators/generator_factory.py +138 -137
  18. sierra/core/graphs/__init__.py +23 -0
  19. sierra/core/graphs/bcbridge.py +94 -0
  20. sierra/core/graphs/heatmap.py +245 -324
  21. sierra/core/graphs/pathset.py +27 -0
  22. sierra/core/graphs/schema.py +77 -0
  23. sierra/core/graphs/stacked_line.py +341 -0
  24. sierra/core/graphs/summary_line.py +506 -0
  25. sierra/core/logging.py +3 -2
  26. sierra/core/models/__init__.py +3 -1
  27. sierra/core/models/info.py +19 -0
  28. sierra/core/models/interface.py +52 -122
  29. sierra/core/pipeline/__init__.py +2 -5
  30. sierra/core/pipeline/pipeline.py +228 -126
  31. sierra/core/pipeline/stage1/__init__.py +10 -0
  32. sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
  33. sierra/core/pipeline/stage2/__init__.py +10 -0
  34. sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
  35. sierra/core/pipeline/stage2/runner.py +401 -0
  36. sierra/core/pipeline/stage3/__init__.py +12 -0
  37. sierra/core/pipeline/stage3/gather.py +321 -0
  38. sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
  39. sierra/core/pipeline/stage4/__init__.py +12 -2
  40. sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
  41. sierra/core/pipeline/stage5/__init__.py +12 -0
  42. sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
  43. sierra/core/pipeline/yaml.py +48 -0
  44. sierra/core/plugin.py +529 -62
  45. sierra/core/proc.py +11 -0
  46. sierra/core/prod.py +11 -0
  47. sierra/core/ros1/__init__.py +5 -1
  48. sierra/core/ros1/callbacks.py +22 -21
  49. sierra/core/ros1/cmdline.py +59 -88
  50. sierra/core/ros1/generators.py +159 -175
  51. sierra/core/ros1/variables/__init__.py +3 -0
  52. sierra/core/ros1/variables/exp_setup.py +122 -116
  53. sierra/core/startup.py +106 -76
  54. sierra/core/stat_kernels.py +4 -5
  55. sierra/core/storage.py +13 -32
  56. sierra/core/trampoline.py +30 -0
  57. sierra/core/types.py +116 -71
  58. sierra/core/utils.py +103 -106
  59. sierra/core/variables/__init__.py +1 -1
  60. sierra/core/variables/base_variable.py +12 -17
  61. sierra/core/variables/batch_criteria.py +387 -481
  62. sierra/core/variables/builtin.py +135 -0
  63. sierra/core/variables/exp_setup.py +19 -39
  64. sierra/core/variables/population_size.py +72 -76
  65. sierra/core/variables/variable_density.py +44 -68
  66. sierra/core/vector.py +1 -1
  67. sierra/main.py +256 -88
  68. sierra/plugins/__init__.py +119 -0
  69. sierra/plugins/compare/__init__.py +14 -0
  70. sierra/plugins/compare/graphs/__init__.py +19 -0
  71. sierra/plugins/compare/graphs/cmdline.py +120 -0
  72. sierra/plugins/compare/graphs/comparator.py +291 -0
  73. sierra/plugins/compare/graphs/inter_controller.py +531 -0
  74. sierra/plugins/compare/graphs/inter_scenario.py +297 -0
  75. sierra/plugins/compare/graphs/namecalc.py +53 -0
  76. sierra/plugins/compare/graphs/outputroot.py +73 -0
  77. sierra/plugins/compare/graphs/plugin.py +147 -0
  78. sierra/plugins/compare/graphs/preprocess.py +172 -0
  79. sierra/plugins/compare/graphs/schema.py +37 -0
  80. sierra/plugins/engine/__init__.py +14 -0
  81. sierra/plugins/engine/argos/__init__.py +18 -0
  82. sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
  83. sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
  84. sierra/plugins/engine/argos/generators/engine.py +394 -0
  85. sierra/plugins/engine/argos/plugin.py +393 -0
  86. sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
  87. sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
  88. sierra/plugins/engine/argos/variables/cameras.py +240 -0
  89. sierra/plugins/engine/argos/variables/constant_density.py +112 -0
  90. sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
  91. sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
  92. sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
  93. sierra/plugins/engine/argos/variables/population_size.py +115 -0
  94. sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
  95. sierra/plugins/engine/argos/variables/rendering.py +108 -0
  96. sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
  97. sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
  98. sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
  99. sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
  100. sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
  101. sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
  102. sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
  103. sierra/plugins/engine/ros1robot/__init__.py +18 -0
  104. sierra/plugins/engine/ros1robot/cmdline.py +159 -0
  105. sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
  106. sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
  107. sierra/plugins/engine/ros1robot/plugin.py +410 -0
  108. sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
  109. sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
  110. sierra/plugins/execenv/__init__.py +11 -0
  111. sierra/plugins/execenv/hpc/__init__.py +18 -0
  112. sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
  113. sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
  114. sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
  115. sierra/plugins/execenv/hpc/cmdline.py +137 -0
  116. sierra/plugins/execenv/hpc/local/__init__.py +18 -0
  117. sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
  118. sierra/plugins/execenv/hpc/local/plugin.py +145 -0
  119. sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
  120. sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
  121. sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
  122. sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
  123. sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
  124. sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
  125. sierra/plugins/execenv/prefectserver/__init__.py +18 -0
  126. sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
  127. sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
  128. sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
  129. sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
  130. sierra/plugins/execenv/prefectserver/flow.py +66 -0
  131. sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
  132. sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
  133. sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
  134. sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
  135. sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
  136. sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
  137. sierra/plugins/expdef/__init__.py +14 -0
  138. sierra/plugins/expdef/json/__init__.py +14 -0
  139. sierra/plugins/expdef/json/plugin.py +504 -0
  140. sierra/plugins/expdef/xml/__init__.py +14 -0
  141. sierra/plugins/expdef/xml/plugin.py +386 -0
  142. sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
  143. sierra/plugins/proc/collate/__init__.py +15 -0
  144. sierra/plugins/proc/collate/cmdline.py +47 -0
  145. sierra/plugins/proc/collate/plugin.py +271 -0
  146. sierra/plugins/proc/compress/__init__.py +18 -0
  147. sierra/plugins/proc/compress/cmdline.py +47 -0
  148. sierra/plugins/proc/compress/plugin.py +123 -0
  149. sierra/plugins/proc/decompress/__init__.py +18 -0
  150. sierra/plugins/proc/decompress/plugin.py +96 -0
  151. sierra/plugins/proc/imagize/__init__.py +15 -0
  152. sierra/plugins/proc/imagize/cmdline.py +49 -0
  153. sierra/plugins/proc/imagize/plugin.py +270 -0
  154. sierra/plugins/proc/modelrunner/__init__.py +16 -0
  155. sierra/plugins/proc/modelrunner/plugin.py +250 -0
  156. sierra/plugins/proc/statistics/__init__.py +15 -0
  157. sierra/plugins/proc/statistics/cmdline.py +64 -0
  158. sierra/plugins/proc/statistics/plugin.py +390 -0
  159. sierra/plugins/{hpc → prod}/__init__.py +1 -0
  160. sierra/plugins/prod/graphs/__init__.py +18 -0
  161. sierra/plugins/prod/graphs/cmdline.py +269 -0
  162. sierra/plugins/prod/graphs/collate.py +279 -0
  163. sierra/plugins/prod/graphs/inter/__init__.py +13 -0
  164. sierra/plugins/prod/graphs/inter/generate.py +83 -0
  165. sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
  166. sierra/plugins/prod/graphs/inter/line.py +134 -0
  167. sierra/plugins/prod/graphs/intra/__init__.py +15 -0
  168. sierra/plugins/prod/graphs/intra/generate.py +202 -0
  169. sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
  170. sierra/plugins/prod/graphs/intra/line.py +114 -0
  171. sierra/plugins/prod/graphs/plugin.py +103 -0
  172. sierra/plugins/prod/graphs/targets.py +63 -0
  173. sierra/plugins/prod/render/__init__.py +18 -0
  174. sierra/plugins/prod/render/cmdline.py +72 -0
  175. sierra/plugins/prod/render/plugin.py +282 -0
  176. sierra/plugins/storage/__init__.py +5 -0
  177. sierra/plugins/storage/arrow/__init__.py +18 -0
  178. sierra/plugins/storage/arrow/plugin.py +38 -0
  179. sierra/plugins/storage/csv/__init__.py +9 -0
  180. sierra/plugins/storage/csv/plugin.py +12 -5
  181. sierra/version.py +3 -2
  182. sierra_research-1.5.0.dist-info/METADATA +238 -0
  183. sierra_research-1.5.0.dist-info/RECORD +186 -0
  184. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
  185. sierra/core/experiment/xml.py +0 -454
  186. sierra/core/generators/controller_generator_parser.py +0 -34
  187. sierra/core/generators/exp_creator.py +0 -351
  188. sierra/core/generators/exp_generators.py +0 -142
  189. sierra/core/graphs/scatterplot2D.py +0 -109
  190. sierra/core/graphs/stacked_line_graph.py +0 -251
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -371
  193. sierra/core/hpc/cmdline.py +0 -142
  194. sierra/core/models/graphs.py +0 -87
  195. sierra/core/pipeline/stage2/exp_runner.py +0 -286
  196. sierra/core/pipeline/stage3/imagizer.py +0 -149
  197. sierra/core/pipeline/stage3/run_collator.py +0 -317
  198. sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
  199. sierra/core/pipeline/stage4/graph_collator.py +0 -320
  200. sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
  201. sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
  202. sierra/core/pipeline/stage4/model_runner.py +0 -168
  203. sierra/core/pipeline/stage4/rendering.py +0 -283
  204. sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
  205. sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
  206. sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
  207. sierra/core/platform.py +0 -493
  208. sierra/core/plugin_manager.py +0 -369
  209. sierra/core/root_dirpath_generator.py +0 -241
  210. sierra/plugins/hpc/adhoc/plugin.py +0 -125
  211. sierra/plugins/hpc/local/plugin.py +0 -81
  212. sierra/plugins/hpc/pbs/__init__.py +0 -9
  213. sierra/plugins/hpc/pbs/plugin.py +0 -126
  214. sierra/plugins/hpc/slurm/__init__.py +0 -9
  215. sierra/plugins/hpc/slurm/plugin.py +0 -130
  216. sierra/plugins/platform/__init__.py +0 -9
  217. sierra/plugins/platform/argos/__init__.py +0 -9
  218. sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
  219. sierra/plugins/platform/argos/plugin.py +0 -337
  220. sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
  221. sierra/plugins/platform/argos/variables/cameras.py +0 -243
  222. sierra/plugins/platform/argos/variables/constant_density.py +0 -136
  223. sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
  224. sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
  225. sierra/plugins/platform/argos/variables/population_size.py +0 -102
  226. sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
  227. sierra/plugins/platform/argos/variables/rendering.py +0 -104
  228. sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
  229. sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
  230. sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
  231. sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
  232. sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
  233. sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
  234. sierra/plugins/platform/ros1robot/__init__.py +0 -9
  235. sierra/plugins/platform/ros1robot/cmdline.py +0 -175
  236. sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
  237. sierra/plugins/platform/ros1robot/plugin.py +0 -373
  238. sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
  239. sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
  240. sierra/plugins/robot/__init__.py +0 -9
  241. sierra/plugins/robot/turtlebot3/__init__.py +0 -9
  242. sierra/plugins/robot/turtlebot3/plugin.py +0 -194
  243. sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
  245. sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
  249. sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.11.dist-info/METADATA +0 -492
  251. sierra_research-1.3.11.dist-info/RECORD +0 -133
  252. sierra_research-1.3.11.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -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
- ]