sierra-research 1.3.6__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.6.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 -249
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -369
  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 -319
  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.6.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.6.data/data/share/man/man7/sierra-examples.7 +0 -488
  245. sierra_research-1.3.6.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.6.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.6.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.6.data/data/share/man/man7/sierra-usage.7 +0 -725
  249. sierra_research-1.3.6.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.6.dist-info/METADATA +0 -500
  251. sierra_research-1.3.6.dist-info/RECORD +0 -133
  252. sierra_research-1.3.6.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,286 +0,0 @@
1
- # Copyright 2018 London Lowmanstone, John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
- """Classes for executing experiments via the specified ``--exec-env``.
5
-
6
- """
7
-
8
- # Core packages
9
- import os
10
- import subprocess
11
- import time
12
- import sys
13
- import datetime
14
- import logging
15
- import pathlib
16
- import typing as tp
17
-
18
- # 3rd party packages
19
-
20
- # Project packages
21
- from sierra.core.variables import batch_criteria as bc
22
- from sierra.core import types, config, platform, utils
23
- import sierra.core.plugin_manager as pm
24
-
25
-
26
- class ExpShell():
27
- """Launch a shell which persists across experimental runs.
28
-
29
- Having a persistent shell is necessary so that running pre- and post-run
30
- shell commands have an effect on the actual commands to execute the run. If
31
- you set an environment variable before the simulator launches (for example),
32
- and then the shell containing that change exits, and the simulator launches
33
- in a new shell, then the configuration has no effect. Thus, a persistent
34
- shell.
35
-
36
- """
37
-
38
- def __init__(self, exec_strict: bool) -> None:
39
- self.env = os.environ.copy()
40
- self.logger = logging.getLogger(__name__)
41
- self.procs = [] # type: tp.List[subprocess.Popen]
42
- self.exec_strict = exec_strict
43
-
44
- def run_from_spec(self, spec: types.ShellCmdSpec) -> bool:
45
- self.logger.trace("Cmd: %s", spec.cmd) # type: ignore
46
-
47
- # We use a special marker at the end of the cmd's output to know when
48
- # the environment dump starts.
49
- if spec.env:
50
- spec.cmd += ' && echo ~~~~ENV_START~~~~ && env'
51
-
52
- proc = subprocess.Popen(spec.cmd,
53
- shell=spec.shell,
54
- stdout=subprocess.PIPE,
55
- stderr=subprocess.PIPE,
56
- env=self.env)
57
-
58
- if not spec.wait:
59
- self.procs.append(proc)
60
- return True
61
-
62
- # We use communicate(), not wait() to avoid issues with IO buffers
63
- # becoming full (i.e., you get deadlocks with wait() regularly).
64
- stdout_raw, stderr_raw = proc.communicate()
65
-
66
- # Update the environment for all commands
67
- if spec.env:
68
- self._update_env(stdout_raw)
69
-
70
- # Only show output if the process failed (i.e., did not return 0)
71
- if proc.returncode != 0:
72
- self.logger.error("Cmd '%s' failed!", spec.cmd)
73
- stdout_str = stdout_raw.decode("ascii")
74
- stderr_str = stderr_raw.decode("ascii")
75
-
76
- if spec.env:
77
- stdout_str = stdout_str.split("~~~~ENV_START~~~~", maxsplit=1)[0]
78
- stderr_str = stderr_str.split("~~~~ENV_START~~~~", maxsplit=1)[0]
79
-
80
- self.logger.error("Cmd stdout (last 10 lines): %s",
81
- '\n + ''\n'.join(stdout_str.split('\n')[-10:]))
82
- self.logger.error("Cmd stderr (last 10 lines): %s",
83
- '\n' + '\n'.join(stderr_str.split('\n')[-10:]))
84
-
85
- if self.exec_strict:
86
- raise RuntimeError(("Command failed and strict checking was "
87
- "requested"))
88
-
89
- return False
90
- else:
91
- return True
92
-
93
- def _update_env(self, stdout) -> None:
94
- record = False
95
- for e in stdout.decode('ascii').split("\n"):
96
- if record:
97
- candidate = e.strip().split('=')
98
- if len(candidate) != 2:
99
- continue
100
-
101
- key = candidate[0]
102
- value = candidate[1]
103
-
104
- if key not in self.env or self.env[key] != value:
105
- self.logger.debug("Update experiment environment: %s=%s",
106
- key,
107
- value)
108
- self.env[key] = value
109
- elif e.strip() == '~~~~ENV_START~~~~':
110
- record = True
111
-
112
-
113
- class BatchExpRunner:
114
- """Runs each :term:`Experiment` in :term:`Batch Experiment` in sequence.
115
-
116
- Attributes:
117
-
118
- batch_exp_root: Absolute path to the root directory for the batch
119
- experiment inputs (i.e. experiment directories are
120
- placed in here).
121
-
122
- batch_stat_root: Absolute path to the root directory for statistics
123
- which are computed in stage {3,4} (i.e. experiment
124
- directories are placed in here).
125
-
126
- batch_stat_exec_root: Absolute path to the root directory for statistics
127
- which are generated as experiments run during
128
- stage 2 (e.g., how long each experiment took).
129
-
130
- cmdopts: Dictionary of parsed cmdline options.
131
-
132
- criteria: Batch criteria for the experiment.
133
-
134
- exec_exp_range: The subset of experiments in the batch to run (can be
135
- None to run all experiments in the batch).
136
-
137
- """
138
-
139
- def __init__(self,
140
- cmdopts: types.Cmdopts,
141
- criteria: bc.BatchCriteria) -> None:
142
- self.cmdopts = cmdopts
143
- self.criteria = criteria
144
-
145
- self.batch_exp_root = pathlib.Path(self.cmdopts['batch_input_root'])
146
- self.batch_stat_root = pathlib.Path(self.cmdopts['batch_stat_root'])
147
- self.batch_stat_exec_root = pathlib.Path(self.batch_stat_root / 'exec')
148
- self.batch_scratch_root = pathlib.Path(self.cmdopts['batch_scratch_root'])
149
- self.exec_exp_range = self.cmdopts['exp_range']
150
-
151
- self.logger = logging.getLogger(__name__)
152
-
153
- utils.dir_create_checked(self.batch_stat_exec_root, exist_ok=True)
154
- utils.dir_create_checked(self.batch_scratch_root, exist_ok=True)
155
-
156
- def __call__(self) -> None:
157
- """
158
- Execute experiments in the batch according to configuration.
159
-
160
- """
161
- self.logger.info("Platform='%s' exec_env='%s'",
162
- self.cmdopts['platform'],
163
- self.cmdopts['exec_env'])
164
-
165
- module = pm.pipeline.get_plugin_module(self.cmdopts['platform'])
166
-
167
- # Output some useful information before running
168
- if hasattr(module, 'pre_exp_diagnostics'):
169
- module.pre_exp_diagnostics(self.cmdopts, self.logger)
170
-
171
- exp_all = [self.batch_exp_root / d
172
- for d in self.criteria.gen_exp_names(self.cmdopts)]
173
-
174
- exp_to_run = utils.exp_range_calc(self.cmdopts,
175
- self.batch_exp_root,
176
- self.criteria)
177
-
178
- # Verify environment is OK before running anything
179
- if hasattr(platform, 'ExecEnvChecker'):
180
- self.logger.debug("Checking execution environment")
181
- platform.ExecEnvChecker(self.cmdopts)()
182
- else:
183
- self.logger.debug("Skip execution environment checking--not needed")
184
-
185
- # Calculate path for to file for logging execution times
186
- now = datetime.datetime.now()
187
- exec_times_fpath = self.batch_stat_exec_root / now.strftime("%Y-%m-%e-%H:%M")
188
-
189
- # Start a new process for the experiment shell so pre-run commands have
190
- # an effect (if they set environment variables, etc.).
191
- shell = ExpShell(self.cmdopts['exec_strict'])
192
-
193
- # Run the experiment!
194
- for exp in exp_to_run:
195
- exp_num = exp_all.index(exp)
196
-
197
- # Run cmds for platform-specific things to setup the experiment
198
- # (e.g., start daemons) if needed.
199
- generator = platform.ExpShellCmdsGenerator(self.cmdopts,
200
- exp_num)
201
- for spec in generator.pre_exp_cmds():
202
- shell.run_from_spec(spec)
203
-
204
- runner = ExpRunner(self.cmdopts,
205
- exec_times_fpath,
206
- generator,
207
- shell)
208
- runner(exp, exp_num)
209
-
210
- # Run cmds to cleanup platform-specific things now that the experiment
211
- # is done (if needed).
212
- for spec in generator.post_exp_cmds():
213
- shell.run_from_spec(spec)
214
-
215
-
216
- class ExpRunner:
217
- """
218
- Execute each :term:`Experimental Run` in an :term:`Experiment`.
219
-
220
- In parallel if the selected execution environment supports it, otherwise
221
- sequentially.
222
-
223
- """
224
-
225
- def __init__(self,
226
- cmdopts: types.Cmdopts,
227
- exec_times_fpath: pathlib.Path,
228
- generator: platform.ExpShellCmdsGenerator,
229
- shell: ExpShell) -> None:
230
-
231
- self.exec_times_fpath = exec_times_fpath
232
- self.shell = shell
233
- self.generator = generator
234
- self.cmdopts = cmdopts
235
- self.logger = logging.getLogger(__name__)
236
-
237
- def __call__(self,
238
- exp_input_root: pathlib.Path,
239
- exp_num: int) -> None:
240
- """Execute experimental runs for a single experiment.
241
- """
242
-
243
- self.logger.info("Running exp%s in '%s'",
244
- exp_num,
245
- exp_input_root)
246
- sys.stdout.flush()
247
-
248
- wd = exp_input_root.relative_to(pathlib.Path().home())
249
- start = time.time()
250
-
251
- scratch_root = self.cmdopts['batch_scratch_root'] / exp_input_root.name
252
- utils.dir_create_checked(scratch_root, exist_ok=True)
253
-
254
- assert self.cmdopts['exec_jobs_per_node'] is not None, \
255
- "# parallel jobs can't be None"
256
-
257
- exec_opts = {
258
- 'exp_input_root': str(exp_input_root),
259
- 'work_dir': str(wd),
260
- 'scratch_dir': str(scratch_root),
261
- 'cmdfile_stem_path': str(exp_input_root / config.kGNUParallel['cmdfile_stem']),
262
- 'cmdfile_ext': config.kGNUParallel['cmdfile_ext'],
263
- 'exec_resume': self.cmdopts['exec_resume'],
264
- 'n_jobs': self.cmdopts['exec_jobs_per_node'],
265
- 'nodefile': self.cmdopts['nodefile']
266
- }
267
- for spec in self.generator.exec_exp_cmds(exec_opts):
268
- if not self.shell.run_from_spec(spec):
269
- self.logger.error("Check outputs in %s for full details",
270
- exec_opts['scratch_dir'])
271
-
272
- elapsed = int(time.time() - start)
273
- sec = datetime.timedelta(seconds=elapsed)
274
- self.logger.info('Exp%s elapsed time: %s', exp_num, sec)
275
-
276
- with utils.utf8open(self.exec_times_fpath, 'a') as f:
277
- f.write('exp' + str(exp_num) + ': ' + str(sec) + '\n')
278
-
279
-
280
- __api__ = [
281
- 'BatchExpRunner',
282
- 'ExpRunner',
283
- 'ExpShell'
284
-
285
-
286
- ]
@@ -1,149 +0,0 @@
1
- # Copyright 2019 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
-
5
- """Classes for creating image files from ``.mean`` files for experiments.
6
-
7
- See :ref:`ln-sierra-usage-rendering` for usage documentation.
8
-
9
- """
10
-
11
- # Core packages
12
- import multiprocessing as mp
13
- import queue
14
- import logging
15
- import pathlib
16
-
17
- # 3rd party packages
18
- import psutil
19
-
20
- # Project packages
21
- from sierra.core.graphs.heatmap import Heatmap
22
- import sierra.core.variables.batch_criteria as bc
23
- from sierra.core import types, config, utils
24
-
25
-
26
- class BatchExpParallelImagizer:
27
- """Generate images for each :term:`Experiment` in the :term:`Batch Experiment`.
28
-
29
- Ideally this is done in parallel across experiments, but this can be changed
30
- to serial if memory on the SIERRA host machine is limited via
31
- ``--processing-serial``.
32
-
33
- """
34
-
35
- def __init__(self,
36
- main_config: types.YAMLDict,
37
- cmdopts: types.Cmdopts) -> None:
38
- self.main_config = main_config
39
- self.cmdopts = cmdopts
40
-
41
- def __call__(self,
42
- HM_config: types.YAMLDict,
43
- criteria: bc.IConcreteBatchCriteria) -> None:
44
- exp_to_imagize = utils.exp_range_calc(self.cmdopts,
45
- self.cmdopts['batch_output_root'],
46
- criteria)
47
-
48
- q = mp.JoinableQueue() # type: mp.JoinableQueue
49
-
50
- for exp in exp_to_imagize:
51
- leaf = exp.name
52
- exp_stat_root = pathlib.Path(self.cmdopts['batch_stat_root']) / leaf
53
- exp_imagize_root = pathlib.Path(
54
- self.cmdopts['batch_imagize_root']) / leaf
55
- self._enqueue_for_exp(exp_stat_root, exp_imagize_root, q)
56
-
57
- if self.cmdopts['processing_serial']:
58
- parallelism = 1
59
- else:
60
- parallelism = psutil.cpu_count()
61
-
62
- for _ in range(0, parallelism):
63
- p = mp.Process(target=BatchExpParallelImagizer._thread_worker,
64
- args=(q, HM_config))
65
- p.start()
66
-
67
- q.join()
68
-
69
- def _enqueue_for_exp(self,
70
- exp_stat_root: pathlib.Path,
71
- exp_imagize_root: pathlib.Path,
72
- q: mp.JoinableQueue) -> None:
73
- for candidate in exp_stat_root.iterdir():
74
- if candidate.is_dir():
75
- imagize_output_root = exp_imagize_root / candidate.name
76
- imagize_opts = {
77
- 'input_root': exp_stat_root,
78
- 'graph_stem': candidate.name,
79
- 'output_root': imagize_output_root
80
- }
81
-
82
- utils.dir_create_checked(imagize_output_root, exist_ok=True)
83
- q.put(imagize_opts)
84
-
85
- @staticmethod
86
- def _thread_worker(q: mp.Queue, HM_config: types.YAMLDict) -> None:
87
- while True:
88
- # Wait for 3 seconds after the queue is empty before bailing
89
- try:
90
- imagize_opts = q.get(True, 3)
91
- ExpImagizer()(HM_config, imagize_opts)
92
- q.task_done()
93
- except queue.Empty:
94
- break
95
-
96
-
97
- class ExpImagizer:
98
- """Create images from the averaged ``.mean`` files from an experiment.
99
-
100
- If no ``.mean`` files suitable for averaging are found, nothing is done. See
101
- :ref:`ln-sierra-usage-rendering` for per-platform descriptions of what
102
- "suitable" means.
103
-
104
- Arguments:
105
-
106
- HM_config: Parsed YAML configuration for heatmaps.
107
-
108
- imagize_opts: Dictionary of imagizing options.
109
-
110
- """
111
-
112
- def __init__(self) -> None:
113
- self.logger = logging.getLogger(__name__)
114
-
115
- def __call__(self,
116
- HM_config: types.YAMLDict,
117
- imagize_opts: dict) -> None:
118
- path = imagize_opts['input_root'] / imagize_opts['graph_stem']
119
-
120
- self.logger.info("Imagizing CSVs in %s...", str(path))
121
-
122
- for csv in path.iterdir():
123
- # For each category of heatmaps we are generating
124
- match = None
125
- for category in HM_config:
126
- # For each graph in each category
127
- for graph in HM_config[category]['graphs']:
128
- if graph['src_stem'] == imagize_opts['graph_stem']:
129
- match = graph
130
-
131
- if match is not None:
132
- ipath = csv.with_suffix(config.kStats['mean'].exts['mean'])
133
- opath = imagize_opts['output_root'] / (csv.name + config.kImageExt)
134
- Heatmap(input_fpath=ipath,
135
- output_fpath=opath,
136
- title=match['title'],
137
- xlabel='X',
138
- ylabel='Y').generate()
139
-
140
- else:
141
- self.logger.warning(("No match for graph with src_stem='%s' "
142
- "found in configuration"),
143
- imagize_opts['graph_stem'])
144
-
145
-
146
- __api__ = [
147
- 'BatchExpParallelImagizer',
148
- 'ExpImagizer'
149
- ]