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
@@ -0,0 +1,18 @@
1
+ # Copyright 2021 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for the PBS execution environment.
6
+
7
+ See :ref:`plugins/execenv/hpc/pbs`.
8
+ """
9
+
10
+ # Core packages
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+
16
+
17
+ def sierra_plugin_type() -> str:
18
+ return "pipeline"
@@ -0,0 +1,30 @@
1
+ #
2
+ # Copyright 2025 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+ """Command line definitions for the :ref:`plugins/execenv/hpc/PBS`."""
7
+
8
+ # Core packages
9
+ import typing as tp
10
+ import argparse
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+ from sierra.plugins.execenv import hpc
16
+ from sierra.core import types
17
+ from sierra.plugins import PluginCmdline
18
+
19
+
20
+ def build(
21
+ parents: tp.List[argparse.ArgumentParser], stages: tp.List[int]
22
+ ) -> PluginCmdline:
23
+ """
24
+ Get a cmdline parser supporting the ``hpc.pbs`` execution environment.
25
+ """
26
+ return hpc.cmdline.HPCCmdline(parents, stages)
27
+
28
+
29
+ def to_cmdopts(args: argparse.Namespace) -> types.Cmdopts:
30
+ return hpc.cmdline.to_cmdopts(args)
@@ -0,0 +1,121 @@
1
+ # Copyright 2020 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ HPC plugin for running SIERRA on HPC clusters using the TORQUE-PBS scheduler.
6
+ """
7
+
8
+ # Core packages
9
+ import os
10
+ import typing as tp
11
+ import argparse
12
+ import shutil
13
+ import pathlib
14
+
15
+ # 3rd party packages
16
+ import implements
17
+
18
+ # Project packages
19
+ from sierra.core import types
20
+ from sierra.core.experiment import bindings
21
+
22
+
23
+ def cmdline_postparse_configure(args: argparse.Namespace) -> argparse.Namespace:
24
+ """
25
+ Configure SIERRA for PBS HPC.
26
+
27
+ Uses the following environment variables (if any of them are not defined an
28
+ assertion will be triggered):
29
+
30
+ - :envvar:`PBS_NUM_PPN`
31
+
32
+ - :envvar:`PBS_NODEFILE`
33
+
34
+ - :envvar:`PBS_JOBID`
35
+ """
36
+
37
+ keys = ["PBS_NUM_PPN", "PBS_NODEFILE", "PBS_JOBID"]
38
+
39
+ for k in keys:
40
+ assert k in os.environ, f"Non-PBS environment detected: '{k}' not found"
41
+
42
+ assert (
43
+ args.exec_jobs_per_node is not None
44
+ ), "--exec-jobs-per-node is required (can't be computed from PBS)"
45
+
46
+ assert not args.engine_vc, "Engine visual capture not supported on PBS"
47
+
48
+ return args
49
+
50
+
51
+ @implements.implements(bindings.IExpShellCmdsGenerator)
52
+ class ExpShellCmdsGenerator:
53
+ """Generate the cmd to invoke GNU Parallel on PBS HPC."""
54
+
55
+ def __init__(self, cmdopts: types.Cmdopts, exp_num: int) -> None:
56
+ self.cmdopts = cmdopts
57
+
58
+ def pre_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
59
+ shell = shutil.which("bash")
60
+
61
+ return [
62
+ # Since parallel doesn't export any envvars to child processes by
63
+ # default, we add some common ones.
64
+ types.ShellCmdSpec(
65
+ cmd='export PARALLEL="${PARALLEL} --env LD_LIBRARY_PATH"',
66
+ shell=True,
67
+ wait=True,
68
+ env=True,
69
+ ),
70
+ # Make sure GNU parallel uses the right shell, because it seems to
71
+ # defaults to /bin/sh since all cmds are run in a python shell which
72
+ # does not have $SHELL set.
73
+ types.ShellCmdSpec(
74
+ cmd=f"export PARALLEL_SHELL={shell}", shell=True, wait=True, env=True
75
+ ),
76
+ ]
77
+
78
+ def post_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
79
+ return []
80
+
81
+ def exec_exp_cmds(self, exec_opts: types.StrDict) -> tp.List[types.ShellCmdSpec]:
82
+ resume = ""
83
+ jobid = os.environ["PBS_JOBID"]
84
+ nodelist = pathlib.Path(exec_opts["exp_input_root"], f"{jobid}-nodelist.txt")
85
+
86
+ resume = ""
87
+ # This can't be --resume, because then GNU parallel looks at the results
88
+ # directory, and if there is stuff in it, (apparently) assumes that the
89
+ # job finished...
90
+ if exec_opts["exec_resume"]:
91
+ resume = "--resume-failed"
92
+
93
+ unique_nodes = types.ShellCmdSpec(
94
+ cmd=f"sort -u $PBS_NODEFILE > {nodelist}", shell=True, wait=True
95
+ )
96
+
97
+ parallel = (
98
+ "parallel {2} "
99
+ "--jobs {1} "
100
+ "--results {4} "
101
+ "--joblog {3} "
102
+ "--sshloginfile {0} "
103
+ '--workdir {4} < "{5}"'
104
+ )
105
+
106
+ log = pathlib.Path(exec_opts["exp_scratch_root"], "parallel.log")
107
+ parallel = parallel.format(
108
+ nodelist,
109
+ exec_opts["n_jobs"],
110
+ resume,
111
+ log,
112
+ exec_opts["exp_scratch_root"],
113
+ exec_opts["cmdfile_stem_path"] + exec_opts["cmdfile_ext"],
114
+ )
115
+
116
+ parallel_spec = types.ShellCmdSpec(cmd=parallel, shell=True, wait=True)
117
+
118
+ return [unique_nodes, parallel_spec]
119
+
120
+
121
+ __all__ = ["cmdline_postparse_configure"]
@@ -0,0 +1,18 @@
1
+ # Copyright 2021 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for the SLURM execution environment.
6
+
7
+ See :ref:`plugins/execenv/hpc/slurm`.
8
+ """
9
+
10
+ # Core packages
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+
16
+
17
+ def sierra_plugin_type() -> str:
18
+ return "pipeline"
@@ -0,0 +1,30 @@
1
+ #
2
+ # Copyright 2025 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+ """Command line definitions for the :ref:`plugins/execenv/hpc/PBS`."""
7
+
8
+ # Core packages
9
+ import typing as tp
10
+ import argparse
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+ from sierra.plugins.execenv import hpc
16
+ from sierra.core import types
17
+ from sierra.plugins import PluginCmdline
18
+
19
+
20
+ def build(
21
+ parents: tp.List[argparse.ArgumentParser], stages: tp.List[int]
22
+ ) -> PluginCmdline:
23
+ """
24
+ Get a cmdline parser supporting the ``hpc.slurm`` execution environment.
25
+ """
26
+ return hpc.cmdline.HPCCmdline(parents, stages)
27
+
28
+
29
+ def to_cmdopts(args: argparse.Namespace) -> types.Cmdopts:
30
+ return hpc.cmdline.to_cmdopts(args)
@@ -0,0 +1,133 @@
1
+ # Copyright 2020 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ HPC plugin for running SIERRA on HPC clusters using the SLURM scheduler.
6
+ """
7
+
8
+ # Core packages
9
+ import typing as tp
10
+ import argparse
11
+ import shutil
12
+ import pathlib
13
+ import os
14
+
15
+ # 3rd party packages
16
+ import implements
17
+
18
+ # Project packages
19
+ from sierra.core import types
20
+ from sierra.core.experiment import bindings
21
+
22
+
23
+ def cmdline_postparse_configure(args: argparse.Namespace) -> argparse.Namespace:
24
+ """
25
+ Configure SIERRA for SLURM HPC.
26
+
27
+ Uses the following environment variables (if any of them are not defined an
28
+ assertion will be triggered):
29
+
30
+ - :envvar:`SLURM_CPUS_PER_TASK`
31
+
32
+ - :envvar:`SLURM_TASKS_PER_NODE`
33
+
34
+ - :envvar:`SLURM_JOB_NODELIST`
35
+
36
+ - :envvar:`SLURM_JOB_ID`
37
+
38
+ """
39
+
40
+ keys = [
41
+ "SLURM_CPUS_PER_TASK",
42
+ "SLURM_TASKS_PER_NODE",
43
+ "SLURM_JOB_NODELIST",
44
+ "SLURM_JOB_ID",
45
+ ]
46
+
47
+ for k in keys:
48
+ assert k in os.environ, f"Non-SLURM environment detected: '{k}' not found"
49
+
50
+ assert not args.engine_vc, "Engine visual capture not supported on SLURM"
51
+
52
+ # SLURM_TASKS_PER_NODE can be set to things like '1(x32),3', indicating
53
+ # that not all nodes will run the same # of tasks. SIERRA expects all
54
+ # nodes to have the same # tasks allocated to each (i.e., a homogeneous
55
+ # allocation), so we check for this.
56
+ assert (
57
+ "," not in os.environ["SLURM_TASKS_PER_NODE"]
58
+ ), "SLURM_TASKS_PER_NODE not homogeneous"
59
+
60
+ return args
61
+
62
+
63
+ @implements.implements(bindings.IExpShellCmdsGenerator)
64
+ class ExpShellCmdsGenerator:
65
+ """Generate the cmd to correctly invoke GNU Parallel on SLURM HPC."""
66
+
67
+ def __init__(self, cmdopts: types.Cmdopts, exp_num: int) -> None:
68
+ self.cmdopts = cmdopts
69
+
70
+ def pre_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
71
+ shell = shutil.which("bash")
72
+
73
+ return [
74
+ # Since parallel doesn't export any envvars to child processes by
75
+ # default, we add some common ones.
76
+ types.ShellCmdSpec(
77
+ cmd='export PARALLEL="${PARALLEL} --env LD_LIBRARY_PATH"',
78
+ shell=True,
79
+ wait=True,
80
+ env=True,
81
+ ),
82
+ # Make sure GNU parallel uses the right shell, because it seems to
83
+ # defaults to /bin/sh since all cmds are run in a python shell which
84
+ # does not have $SHELL set.
85
+ types.ShellCmdSpec(
86
+ cmd=f"export PARALLEL_SHELL={shell}", shell=True, wait=True, env=True
87
+ ),
88
+ ]
89
+
90
+ def post_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
91
+ return []
92
+
93
+ def exec_exp_cmds(self, exec_opts: types.StrDict) -> tp.List[types.ShellCmdSpec]:
94
+ jobid = os.environ["SLURM_JOB_ID"]
95
+ nodelist = pathlib.Path(exec_opts["exp_input_root"], f"{jobid}-nodelist.txt")
96
+
97
+ resume = ""
98
+ # This can't be --resume, because then GNU parallel looks at the results
99
+ # directory, and if there is stuff in it, (apparently) assumes that the
100
+ # job finished...
101
+ if exec_opts["exec_resume"]:
102
+ resume = "--resume-failed"
103
+
104
+ unique_nodes = types.ShellCmdSpec(
105
+ cmd=f"scontrol show hostnames $SLURM_JOB_NODELIST > {nodelist}",
106
+ shell=True,
107
+ wait=True,
108
+ )
109
+
110
+ parallel = (
111
+ "parallel {2} "
112
+ "--jobs {1} "
113
+ "--results {4} "
114
+ "--joblog {3} "
115
+ "--sshloginfile {0} "
116
+ '--workdir {4} < "{5}"'
117
+ )
118
+
119
+ log = pathlib.Path(exec_opts["exp_scratch_root"], "parallel.log")
120
+ parallel = parallel.format(
121
+ nodelist,
122
+ exec_opts["n_jobs"],
123
+ resume,
124
+ log,
125
+ exec_opts["exp_scratch_root"],
126
+ exec_opts["cmdfile_stem_path"] + exec_opts["cmdfile_ext"],
127
+ )
128
+ parallel_spec = types.ShellCmdSpec(cmd=parallel, shell=True, wait=True)
129
+
130
+ return [unique_nodes, parallel_spec]
131
+
132
+
133
+ __all__ = ["cmdline_postparse_configure", "ExpShellCmdsGenerator"]
@@ -0,0 +1,18 @@
1
+ # Copyright 2025 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for plugins related to prefect execution environments.
6
+
7
+ Driven by ``--execenv``.
8
+ """
9
+
10
+ # Core packages
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+ from . import cmdline
16
+
17
+
18
+ __all__ = ["cmdline"]
@@ -0,0 +1,66 @@
1
+ # Copyright 2020 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Common cmdline classes for the various :term:`Prefect` plugins.
6
+ """
7
+
8
+ # Core packages
9
+ import argparse
10
+ import typing as tp
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+ from sierra.core import types
16
+ from sierra.plugins.execenv import hpc
17
+
18
+
19
+ class PrefectCmdline(hpc.cmdline.HPCCmdline):
20
+ """
21
+ Define the common :term:`Prefect` cmdline.
22
+
23
+ This class decorates the HPC cmdline with some additional options; it
24
+ *mostly* makes sense to consider HPC as a more general form of execution
25
+ environment and prefect a specialization of it. Mostly.
26
+ """
27
+
28
+ def __init__(
29
+ self, parents: tp.List[argparse.ArgumentParser], stages: tp.List[int]
30
+ ) -> None:
31
+ super().__init__(parents, stages)
32
+
33
+ def init_stage2(self) -> None:
34
+ """Add Prefect cmdline options."""
35
+ super().init_stage2()
36
+
37
+ self.stage2.add_argument(
38
+ "--work-pool",
39
+ default="sierra-pool",
40
+ help="""
41
+ Name of the prefect worker pool to use.
42
+ """
43
+ + self.stage_usage_doc([2]),
44
+ )
45
+ self.stage2.add_argument(
46
+ "--work-queue",
47
+ default="sierra-queue",
48
+ help="""
49
+ Name of the prefect work queue to use.
50
+ """
51
+ + self.stage_usage_doc([2]),
52
+ )
53
+
54
+
55
+ def to_cmdopts(args: argparse.Namespace) -> types.Cmdopts:
56
+ """Update cmdopts dictionary with the prefect-specific cmdline options."""
57
+ opts = hpc.cmdline.to_cmdopts(args)
58
+ updates = {
59
+ "work_pool": args.work_pool,
60
+ "work_queue": args.work_queue,
61
+ }
62
+ opts |= updates
63
+ return opts
64
+
65
+
66
+ __all__ = ["to_cmdopts"]
@@ -0,0 +1,18 @@
1
+ # Copyright 2021 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for the :term:`Prefect` remote execution environment.
6
+
7
+ See :ref:`plugins/execenv/prefectserver/dockerremote`.
8
+ """
9
+
10
+ # Core packages
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+
16
+
17
+ def sierra_plugin_type() -> str:
18
+ return "pipeline"
@@ -0,0 +1,66 @@
1
+ #
2
+ # Copyright 2025 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+
7
+ # Core packages
8
+ import typing as tp
9
+ import argparse
10
+
11
+ # 3rd party packages
12
+
13
+ # Project packages
14
+ from sierra.plugins.execenv import prefectserver
15
+ from sierra.core import types
16
+ from sierra.plugins import PluginCmdline
17
+
18
+
19
+ def build(
20
+ parents: tp.List[argparse.ArgumentParser], stages: tp.List[int]
21
+ ) -> PluginCmdline:
22
+ """
23
+ Get a cmdline for the ``prefectserver.dockerremote`` execution environment.
24
+ """
25
+ cmdline = prefectserver.cmdline.PrefectCmdline(parents, stages)
26
+
27
+ cmdline.stage2.add_argument(
28
+ "--docker-extra-mounts",
29
+ nargs="+",
30
+ help="""
31
+ Add extra mounts in the usual docker format, space separated.
32
+ """
33
+ + cmdline.stage_usage_doc([2]),
34
+ )
35
+ cmdline.stage2.add_argument(
36
+ "--docker-image",
37
+ help="""
38
+ Path to the docker image to use.
39
+ """
40
+ + cmdline.stage_usage_doc([2]),
41
+ )
42
+ cmdline.stage2.add_argument(
43
+ "--docker-is-host-user",
44
+ action="store_true",
45
+ default=False,
46
+ help="""
47
+ Direct prefect -> docker to run things as the host user within
48
+ docker containers. Said user obviously has to exist in the
49
+ container for this to work.
50
+ """
51
+ + cmdline.stage_usage_doc([2]),
52
+ )
53
+ return cmdline
54
+
55
+
56
+ def to_cmdopts(args: argparse.Namespace) -> types.Cmdopts:
57
+ opts = prefectserver.cmdline.to_cmdopts(args)
58
+ updates = {
59
+ # stage 2
60
+ "docker_extra_mounts": args.docker_extra_mounts,
61
+ "docker_image": args.docker_image,
62
+ "docker_is_host_user": args.docker_is_host_user,
63
+ }
64
+ opts |= updates
65
+
66
+ return opts
@@ -0,0 +1,132 @@
1
+ # Copyright 2020 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ HPC plugin for running SIERRA on HPC clusters using the SLURM scheduler.
6
+ """
7
+
8
+ # Core packages
9
+ import typing as tp
10
+ import argparse
11
+ import pathlib
12
+ import os
13
+
14
+ # 3rd party packages
15
+ import implements
16
+ import json
17
+
18
+ # Project packages
19
+ from sierra.core import types
20
+ from sierra.core.experiment import bindings
21
+
22
+
23
+ @implements.implements(bindings.IBatchShellCmdsGenerator)
24
+ class BatchShellCmdsGenerator:
25
+ """
26
+ Generate commands to invoke :term:`Prefect` for remote computing using docker.
27
+ """
28
+
29
+ def __init__(self, cmdopts: types.Cmdopts) -> None:
30
+ self.cmdopts = cmdopts
31
+ self.api_url = os.environ["PREFECT_API_URL"]
32
+
33
+ def pre_batch_cmds(self) -> tp.List[types.ShellCmdSpec]:
34
+ flow_path = pathlib.Path(__file__).parent / "../flow.py"
35
+ no_prompt = "PREFECT_CLI_PROMPT=false"
36
+
37
+ # --sierra-root is always mounted; users can specify whatever other dirs
38
+ # from the host system are needed in the container to actually run
39
+ # things. We mount all extra dirs read/write because we can't know what
40
+ # the engine will be using them for. For --sierra-root, the scratch dir
41
+ # under there gets written, so rw is appropriate is well.
42
+ volumes = ["{0}:{0}:rw".format(self.cmdopts["sierra_root"])] + [
43
+ f"{m}:rw" for m in self.cmdopts["docker_extra_mounts"]
44
+ ]
45
+ job_vars = {
46
+ "image": self.cmdopts["docker_image"],
47
+ # Only pull the image if it doesn't exist locally
48
+ "image_pull_policy": "IfNotPresent",
49
+ "volumes": volumes,
50
+ }
51
+
52
+ # Run as your user, to avoid issues with files in mounted volumes
53
+ # being owned by root when the container exits.
54
+ if self.cmdopts["docker_is_host_user"]:
55
+ job_vars["user"] = f"{os.getuid()}:{os.getgid()}"
56
+
57
+ ret = [
58
+ # Make sure that the image has prefect installed and accessible.
59
+ types.ShellCmdSpec(
60
+ cmd="which prefect",
61
+ shell=True,
62
+ wait=True,
63
+ ),
64
+ types.ShellCmdSpec(
65
+ cmd="prefect config set PREFECT_API_URL={0}".format(self.api_url),
66
+ shell=True,
67
+ wait=True,
68
+ ),
69
+ ]
70
+
71
+ build = (
72
+ "{0} prefect deploy {1}:sierra "
73
+ "--name sierra/dockerremote "
74
+ "--job-variable '{2}' "
75
+ "--pool {3} "
76
+ "--work-queue {4}"
77
+ ).format(
78
+ no_prompt,
79
+ flow_path,
80
+ json.dumps(job_vars),
81
+ self.cmdopts["work_pool"],
82
+ self.cmdopts["work_queue"],
83
+ )
84
+ ret.append(
85
+ types.ShellCmdSpec(
86
+ cmd=build,
87
+ shell=True,
88
+ wait=True,
89
+ ),
90
+ )
91
+ return ret
92
+
93
+ def exec_batch_cmds(self, exec_opts: types.StrDict) -> tp.List[types.ShellCmdSpec]:
94
+ # The needed flow is already present on the server as a deployment, so
95
+ # we can just run it directly as many times as we want. You don't need
96
+ # to set the queue/pool--it is inferred from the flow you are running.
97
+ flow_cmd = (
98
+ "prefect deployment run sierra/dockerremote "
99
+ '--params=\'{{"input_root": "{0}","scratch_root": "{1}"}}\' --watch'
100
+ )
101
+ # Since this execenv is batch level, so are the outputs and scratch
102
+ # dirs.
103
+ flow = flow_cmd.format(exec_opts["batch_root"], exec_opts["batch_scratch_root"])
104
+ spec = types.ShellCmdSpec(cmd=flow, shell=True, wait=True)
105
+
106
+ return [spec]
107
+
108
+ def post_batch_cmds(self) -> tp.List[types.ShellCmdSpec]:
109
+ return []
110
+
111
+
112
+ def cmdline_postparse_configure(args: argparse.Namespace) -> argparse.Namespace:
113
+ """
114
+ Configure SIERRA to use :term:`Prefect` to run remotely using docker.
115
+
116
+ Uses the following environment variables (if any of them are not defined an
117
+ assertion will be triggered):
118
+
119
+ - :envvar:`PREFECT_API_URL`
120
+ """
121
+
122
+ keys = [
123
+ "PREFECT_API_URL",
124
+ ]
125
+
126
+ for k in keys:
127
+ assert k in os.environ, f"Non-Prefect environment detected: '{k}' not found"
128
+
129
+ return args
130
+
131
+
132
+ __all__ = ["cmdline_postparse_configure", "BatchShellCmdsGenerator"]