sierra-research 1.3.11__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sierra/__init__.py +3 -3
- sierra/core/__init__.py +3 -3
- sierra/core/batchroot.py +223 -0
- sierra/core/cmdline.py +681 -1057
- sierra/core/compare.py +11 -0
- sierra/core/config.py +96 -88
- sierra/core/engine.py +306 -0
- sierra/core/execenv.py +380 -0
- sierra/core/expdef.py +11 -0
- sierra/core/experiment/__init__.py +1 -0
- sierra/core/experiment/bindings.py +150 -101
- sierra/core/experiment/definition.py +414 -245
- sierra/core/experiment/spec.py +83 -85
- sierra/core/exproot.py +44 -0
- sierra/core/generators/__init__.py +10 -0
- sierra/core/generators/experiment.py +528 -0
- sierra/core/generators/generator_factory.py +138 -137
- sierra/core/graphs/__init__.py +23 -0
- sierra/core/graphs/bcbridge.py +94 -0
- sierra/core/graphs/heatmap.py +245 -324
- sierra/core/graphs/pathset.py +27 -0
- sierra/core/graphs/schema.py +77 -0
- sierra/core/graphs/stacked_line.py +341 -0
- sierra/core/graphs/summary_line.py +506 -0
- sierra/core/logging.py +3 -2
- sierra/core/models/__init__.py +3 -1
- sierra/core/models/info.py +19 -0
- sierra/core/models/interface.py +52 -122
- sierra/core/pipeline/__init__.py +2 -5
- sierra/core/pipeline/pipeline.py +228 -126
- sierra/core/pipeline/stage1/__init__.py +10 -0
- sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
- sierra/core/pipeline/stage2/__init__.py +10 -0
- sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
- sierra/core/pipeline/stage2/runner.py +401 -0
- sierra/core/pipeline/stage3/__init__.py +12 -0
- sierra/core/pipeline/stage3/gather.py +321 -0
- sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
- sierra/core/pipeline/stage4/__init__.py +12 -2
- sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
- sierra/core/pipeline/stage5/__init__.py +12 -0
- sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
- sierra/core/pipeline/yaml.py +48 -0
- sierra/core/plugin.py +529 -62
- sierra/core/proc.py +11 -0
- sierra/core/prod.py +11 -0
- sierra/core/ros1/__init__.py +5 -1
- sierra/core/ros1/callbacks.py +22 -21
- sierra/core/ros1/cmdline.py +59 -88
- sierra/core/ros1/generators.py +159 -175
- sierra/core/ros1/variables/__init__.py +3 -0
- sierra/core/ros1/variables/exp_setup.py +122 -116
- sierra/core/startup.py +106 -76
- sierra/core/stat_kernels.py +4 -5
- sierra/core/storage.py +13 -32
- sierra/core/trampoline.py +30 -0
- sierra/core/types.py +116 -71
- sierra/core/utils.py +103 -106
- sierra/core/variables/__init__.py +1 -1
- sierra/core/variables/base_variable.py +12 -17
- sierra/core/variables/batch_criteria.py +387 -481
- sierra/core/variables/builtin.py +135 -0
- sierra/core/variables/exp_setup.py +19 -39
- sierra/core/variables/population_size.py +72 -76
- sierra/core/variables/variable_density.py +44 -68
- sierra/core/vector.py +1 -1
- sierra/main.py +256 -88
- sierra/plugins/__init__.py +119 -0
- sierra/plugins/compare/__init__.py +14 -0
- sierra/plugins/compare/graphs/__init__.py +19 -0
- sierra/plugins/compare/graphs/cmdline.py +120 -0
- sierra/plugins/compare/graphs/comparator.py +291 -0
- sierra/plugins/compare/graphs/inter_controller.py +531 -0
- sierra/plugins/compare/graphs/inter_scenario.py +297 -0
- sierra/plugins/compare/graphs/namecalc.py +53 -0
- sierra/plugins/compare/graphs/outputroot.py +73 -0
- sierra/plugins/compare/graphs/plugin.py +147 -0
- sierra/plugins/compare/graphs/preprocess.py +172 -0
- sierra/plugins/compare/graphs/schema.py +37 -0
- sierra/plugins/engine/__init__.py +14 -0
- sierra/plugins/engine/argos/__init__.py +18 -0
- sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
- sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
- sierra/plugins/engine/argos/generators/engine.py +394 -0
- sierra/plugins/engine/argos/plugin.py +393 -0
- sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
- sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
- sierra/plugins/engine/argos/variables/cameras.py +240 -0
- sierra/plugins/engine/argos/variables/constant_density.py +112 -0
- sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
- sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
- sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
- sierra/plugins/engine/argos/variables/population_size.py +115 -0
- sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
- sierra/plugins/engine/argos/variables/rendering.py +108 -0
- sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
- sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
- sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
- sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
- sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
- sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
- sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
- sierra/plugins/engine/ros1robot/__init__.py +18 -0
- sierra/plugins/engine/ros1robot/cmdline.py +159 -0
- sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
- sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
- sierra/plugins/engine/ros1robot/plugin.py +410 -0
- sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
- sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
- sierra/plugins/execenv/__init__.py +11 -0
- sierra/plugins/execenv/hpc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
- sierra/plugins/execenv/hpc/cmdline.py +137 -0
- sierra/plugins/execenv/hpc/local/__init__.py +18 -0
- sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
- sierra/plugins/execenv/hpc/local/plugin.py +145 -0
- sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
- sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
- sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
- sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
- sierra/plugins/execenv/prefectserver/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
- sierra/plugins/execenv/prefectserver/flow.py +66 -0
- sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
- sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
- sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
- sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
- sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
- sierra/plugins/expdef/__init__.py +14 -0
- sierra/plugins/expdef/json/__init__.py +14 -0
- sierra/plugins/expdef/json/plugin.py +504 -0
- sierra/plugins/expdef/xml/__init__.py +14 -0
- sierra/plugins/expdef/xml/plugin.py +386 -0
- sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
- sierra/plugins/proc/collate/__init__.py +15 -0
- sierra/plugins/proc/collate/cmdline.py +47 -0
- sierra/plugins/proc/collate/plugin.py +271 -0
- sierra/plugins/proc/compress/__init__.py +18 -0
- sierra/plugins/proc/compress/cmdline.py +47 -0
- sierra/plugins/proc/compress/plugin.py +123 -0
- sierra/plugins/proc/decompress/__init__.py +18 -0
- sierra/plugins/proc/decompress/plugin.py +96 -0
- sierra/plugins/proc/imagize/__init__.py +15 -0
- sierra/plugins/proc/imagize/cmdline.py +49 -0
- sierra/plugins/proc/imagize/plugin.py +270 -0
- sierra/plugins/proc/modelrunner/__init__.py +16 -0
- sierra/plugins/proc/modelrunner/plugin.py +250 -0
- sierra/plugins/proc/statistics/__init__.py +15 -0
- sierra/plugins/proc/statistics/cmdline.py +64 -0
- sierra/plugins/proc/statistics/plugin.py +390 -0
- sierra/plugins/{hpc → prod}/__init__.py +1 -0
- sierra/plugins/prod/graphs/__init__.py +18 -0
- sierra/plugins/prod/graphs/cmdline.py +269 -0
- sierra/plugins/prod/graphs/collate.py +279 -0
- sierra/plugins/prod/graphs/inter/__init__.py +13 -0
- sierra/plugins/prod/graphs/inter/generate.py +83 -0
- sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
- sierra/plugins/prod/graphs/inter/line.py +134 -0
- sierra/plugins/prod/graphs/intra/__init__.py +15 -0
- sierra/plugins/prod/graphs/intra/generate.py +202 -0
- sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
- sierra/plugins/prod/graphs/intra/line.py +114 -0
- sierra/plugins/prod/graphs/plugin.py +103 -0
- sierra/plugins/prod/graphs/targets.py +63 -0
- sierra/plugins/prod/render/__init__.py +18 -0
- sierra/plugins/prod/render/cmdline.py +72 -0
- sierra/plugins/prod/render/plugin.py +282 -0
- sierra/plugins/storage/__init__.py +5 -0
- sierra/plugins/storage/arrow/__init__.py +18 -0
- sierra/plugins/storage/arrow/plugin.py +38 -0
- sierra/plugins/storage/csv/__init__.py +9 -0
- sierra/plugins/storage/csv/plugin.py +12 -5
- sierra/version.py +3 -2
- sierra_research-1.5.0.dist-info/METADATA +238 -0
- sierra_research-1.5.0.dist-info/RECORD +186 -0
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
- sierra/core/experiment/xml.py +0 -454
- sierra/core/generators/controller_generator_parser.py +0 -34
- sierra/core/generators/exp_creator.py +0 -351
- sierra/core/generators/exp_generators.py +0 -142
- sierra/core/graphs/scatterplot2D.py +0 -109
- sierra/core/graphs/stacked_line_graph.py +0 -251
- sierra/core/graphs/stacked_surface_graph.py +0 -220
- sierra/core/graphs/summary_line_graph.py +0 -371
- sierra/core/hpc/cmdline.py +0 -142
- sierra/core/models/graphs.py +0 -87
- sierra/core/pipeline/stage2/exp_runner.py +0 -286
- sierra/core/pipeline/stage3/imagizer.py +0 -149
- sierra/core/pipeline/stage3/run_collator.py +0 -317
- sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
- sierra/core/pipeline/stage4/graph_collator.py +0 -320
- sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
- sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
- sierra/core/pipeline/stage4/model_runner.py +0 -168
- sierra/core/pipeline/stage4/rendering.py +0 -283
- sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
- sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
- sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
- sierra/core/platform.py +0 -493
- sierra/core/plugin_manager.py +0 -369
- sierra/core/root_dirpath_generator.py +0 -241
- sierra/plugins/hpc/adhoc/plugin.py +0 -125
- sierra/plugins/hpc/local/plugin.py +0 -81
- sierra/plugins/hpc/pbs/__init__.py +0 -9
- sierra/plugins/hpc/pbs/plugin.py +0 -126
- sierra/plugins/hpc/slurm/__init__.py +0 -9
- sierra/plugins/hpc/slurm/plugin.py +0 -130
- sierra/plugins/platform/__init__.py +0 -9
- sierra/plugins/platform/argos/__init__.py +0 -9
- sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
- sierra/plugins/platform/argos/plugin.py +0 -337
- sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
- sierra/plugins/platform/argos/variables/cameras.py +0 -243
- sierra/plugins/platform/argos/variables/constant_density.py +0 -136
- sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
- sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
- sierra/plugins/platform/argos/variables/population_size.py +0 -102
- sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
- sierra/plugins/platform/argos/variables/rendering.py +0 -104
- sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
- sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
- sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
- sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
- sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
- sierra/plugins/platform/ros1robot/__init__.py +0 -9
- sierra/plugins/platform/ros1robot/cmdline.py +0 -175
- sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
- sierra/plugins/platform/ros1robot/plugin.py +0 -373
- sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
- sierra/plugins/robot/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/plugin.py +0 -194
- sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
- sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
- sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
- sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
- sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
- sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
- sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
- sierra_research-1.3.11.dist-info/METADATA +0 -492
- sierra_research-1.3.11.dist-info/RECORD +0 -133
- sierra_research-1.3.11.dist-info/top_level.txt +0 -1
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -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"]
|