klej 0.0.1__tar.gz
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.
- klej-0.0.1/LICENSE +201 -0
- klej-0.0.1/MANIFEST.in +1 -0
- klej-0.0.1/NOTICE +2 -0
- klej-0.0.1/PKG-INFO +441 -0
- klej-0.0.1/README.md +412 -0
- klej-0.0.1/klej/__init__.py +1 -0
- klej-0.0.1/klej/__main__.py +551 -0
- klej-0.0.1/klej/config.py +274 -0
- klej-0.0.1/klej/runner.py +767 -0
- klej-0.0.1/klej/runner_cache.py +21 -0
- klej-0.0.1/klej/status.py +1263 -0
- klej-0.0.1/klej/workflow.py +765 -0
- klej-0.0.1/klej.egg-info/PKG-INFO +441 -0
- klej-0.0.1/klej.egg-info/SOURCES.txt +18 -0
- klej-0.0.1/klej.egg-info/dependency_links.txt +1 -0
- klej-0.0.1/klej.egg-info/entry_points.txt +2 -0
- klej-0.0.1/klej.egg-info/requires.txt +9 -0
- klej-0.0.1/klej.egg-info/top_level.txt +1 -0
- klej-0.0.1/pyproject.toml +67 -0
- klej-0.0.1/setup.cfg +4 -0
klej-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
klej-0.0.1/MANIFEST.in
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prune tests
|
klej-0.0.1/NOTICE
ADDED
klej-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: klej
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: The missing glue between DVC and Slurm
|
|
5
|
+
Author: Maciej Falkiewicz
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Documentation, https://github.com/macio232/klej#readme
|
|
8
|
+
Project-URL: Issues, https://github.com/macio232/klej/issues
|
|
9
|
+
Project-URL: Source, https://github.com/macio232/klej
|
|
10
|
+
Keywords: workflow,scheduling,slurm,hpc,dvc
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Natural Language :: English
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
License-File: NOTICE
|
|
21
|
+
Requires-Dist: dawgz==2.7.0
|
|
22
|
+
Requires-Dist: dvc==3.66.0
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: ruff>=0.16.6; extra == "dev"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=8.0.0; extra == "test"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# klej
|
|
31
|
+
|
|
32
|
+
`klej` is the missing glue between
|
|
33
|
+
[DVC](https://dvc.org/) and [Slurm](https://slurm.schedmd.com/slurm.html). It
|
|
34
|
+
turns selected DVC stages into a dependency-aware [DAWGZ](https://github.com/francois-rozet/dawgz) workflow and
|
|
35
|
+
executes each stage as a separate Slurm job.
|
|
36
|
+
|
|
37
|
+
The name means “glue” in Polish.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
`klej` requires Python 3.11 or newer.
|
|
42
|
+
|
|
43
|
+
Install the pre-alpha release from PyPI as an isolated command with
|
|
44
|
+
[uv](https://docs.astral.sh/uv/):
|
|
45
|
+
|
|
46
|
+
```console
|
|
47
|
+
uv tool install klej==0.0.1
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Alternatively, install it into the active Python environment with pip:
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
python -m pip install klej==0.0.1
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
To install manually from a source checkout, create a virtual environment and
|
|
57
|
+
install the local project:
|
|
58
|
+
|
|
59
|
+
```console
|
|
60
|
+
git clone https://github.com/macio232/klej.git
|
|
61
|
+
cd klej
|
|
62
|
+
python -m venv .venv
|
|
63
|
+
source .venv/bin/activate
|
|
64
|
+
python -m pip install .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This is an early release intended for evaluation and research workflows, not
|
|
68
|
+
production use.
|
|
69
|
+
|
|
70
|
+
## Project status and safety
|
|
71
|
+
|
|
72
|
+
`klej` is an early-stage research tool. It may contain bugs, and its commands,
|
|
73
|
+
configuration, and Python interfaces may change without backward
|
|
74
|
+
compatibility. Do not rely on it for production-critical workloads without
|
|
75
|
+
independent testing.
|
|
76
|
+
|
|
77
|
+
Submitting a pipeline can create many jobs that run in parallel and may
|
|
78
|
+
consume substantial cluster resources or incur significant cost. Review the
|
|
79
|
+
plan with `--dry-run`, understand your cluster's quotas and billing, and
|
|
80
|
+
monitor submitted jobs. You are responsible for the workloads and costs
|
|
81
|
+
created by your use of `klej`; use it at your own risk.
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
Run from a DVC repository:
|
|
86
|
+
|
|
87
|
+
```console
|
|
88
|
+
klej repro path/to/dvc.yaml --dry-run
|
|
89
|
+
klej repro path/to/dvc.yaml
|
|
90
|
+
klej repro [targets ...]
|
|
91
|
+
klej repro models/dvc.yaml:train --downstream
|
|
92
|
+
klej repro pipelines/ -R
|
|
93
|
+
klej status
|
|
94
|
+
klej status WORKFLOW_ID
|
|
95
|
+
klej status --failed
|
|
96
|
+
klej status --finished
|
|
97
|
+
klej logs WORKFLOW_ID JOB --tail 100 --follow
|
|
98
|
+
klej logs --clear WORKFLOW_ID
|
|
99
|
+
klej logs --clear-all --force
|
|
100
|
+
klej cancel WORKFLOW_ID --dry-run
|
|
101
|
+
klej lock status
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Targets default to `./dvc.yaml` and use the same forms as `dvc repro`: stage
|
|
105
|
+
names, `dvc.yaml` and `.dvc` paths, `path/dvc.yaml:stage`, foreach or matrix
|
|
106
|
+
expansions, glob patterns with `--glob`, and directories with `-R`. DVC
|
|
107
|
+
dependencies in other pipeline files are included automatically.
|
|
108
|
+
|
|
109
|
+
Regular, foreach, matrix-expanded, frozen, import, `.dvc`, and
|
|
110
|
+
checkpoint-marked stages are supported according to pinned DVC 3.66
|
|
111
|
+
`dvc repro` behavior. Experiment checkpoint snapshots and resume behavior are
|
|
112
|
+
not provided.
|
|
113
|
+
|
|
114
|
+
The supported DVC selection and execution flags are `-f/--force`,
|
|
115
|
+
`-i/--interactive`, `-s/--single-item`, `-p/--pipeline`,
|
|
116
|
+
`-P/--all-pipelines`, `-R/--recursive`, `--downstream`,
|
|
117
|
+
`--force-downstream`, `--allow-missing`, `--glob`, `--no-run-cache`,
|
|
118
|
+
`--ignore-errors`, `--no-commit`, `--dry`, and `-v/--verbose`. `--dry-run` is
|
|
119
|
+
an alias for `--dry`. `--pull` and `-q/--quiet` are not supported.
|
|
120
|
+
`-k/--keep-going` is unnecessary: klej always continues independent Slurm
|
|
121
|
+
branches while failed dependencies prevent their downstream jobs from
|
|
122
|
+
running. `--ignore-errors` changes those dependencies from Slurm `afterok` to
|
|
123
|
+
`afterany`; failures remain visible in workflow status.
|
|
124
|
+
|
|
125
|
+
`-v/--verbose` reports repository and target resolution, selected and skipped
|
|
126
|
+
stages, effective configuration files, profiles, dependencies, runner and
|
|
127
|
+
reservation identifiers, and submitted Slurm IDs. It also enables DVC debug
|
|
128
|
+
logging and klej cache/metadata/lock diagnostics in job logs. Resolved
|
|
129
|
+
environment values are not printed.
|
|
130
|
+
|
|
131
|
+
An explicit `--config` is one complete configuration used for every selected
|
|
132
|
+
pipeline. Otherwise, repository-root `klej.yaml` is the base and a
|
|
133
|
+
`klej.yaml` beside each pipeline may partially override it. Named `profiles`
|
|
134
|
+
and `stages` are merged; local `commit`, `klej`, `environment`, and
|
|
135
|
+
`wrapper` values replace the base values. With one explicit configuration,
|
|
136
|
+
identically named stages in different pipeline files necessarily use the same
|
|
137
|
+
profile mapping. Multi-pipeline runs create one cleanup job, so all effective
|
|
138
|
+
pipeline configurations must resolve to the same klej-operation profile and
|
|
139
|
+
environment. Align those settings or use `--config` when they differ.
|
|
140
|
+
|
|
141
|
+
`klej cancel` queries Slurm and cancels only jobs that are still cancellable.
|
|
142
|
+
Its output reports counts rather than printing one line per job.
|
|
143
|
+
|
|
144
|
+
Dry-run output reports projected logical and physical job totals for the whole
|
|
145
|
+
workflow, including commit and reservation-cleanup jobs. A normal stage is one
|
|
146
|
+
logical and physical job. A Slurm stage with multiple profiles remains one
|
|
147
|
+
logical job but produces one physical attempt per profile plus a success gate;
|
|
148
|
+
its stage detail shows that expansion explicitly. No Slurm arrays are used.
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
profiles:
|
|
152
|
+
cpu:
|
|
153
|
+
account: my-account
|
|
154
|
+
cpus: 4
|
|
155
|
+
mem: 16G
|
|
156
|
+
gpu:
|
|
157
|
+
account: my-account
|
|
158
|
+
gres: gpu:1
|
|
159
|
+
environment:
|
|
160
|
+
APPTAINER_NV: 1
|
|
161
|
+
|
|
162
|
+
stages:
|
|
163
|
+
prepare: cpu
|
|
164
|
+
# Competing Slurm requests for one logical execution.
|
|
165
|
+
train: [gpu, cpu]
|
|
166
|
+
|
|
167
|
+
commit: cpu
|
|
168
|
+
klej: cpu
|
|
169
|
+
|
|
170
|
+
environment:
|
|
171
|
+
APPTAINER_NV: 0
|
|
172
|
+
|
|
173
|
+
# The wrapper receives the runner command as one final argument.
|
|
174
|
+
wrapper: [./apptainer/run.sh]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
A stage may name one profile or an ordered, non-empty list of distinct
|
|
178
|
+
profiles. With two or more profiles on Slurm, klej submits one attempt per
|
|
179
|
+
profile; the first allocation to atomically claim the stage runs the wrapper
|
|
180
|
+
and payload. Other attempts exit with status 75 without entering either. The
|
|
181
|
+
claim is permanent, so a failing winner fails the logical stage and does not
|
|
182
|
+
fall back to another profile. At-most-once applies to entering the configured
|
|
183
|
+
wrapper and user payload, not to allocation: multiple Slurm allocations may
|
|
184
|
+
briefly start klej's coordinator. Correctness therefore requires a filesystem
|
|
185
|
+
shared by the submission host and every compute node, with atomic directory
|
|
186
|
+
creation and atomic file replacement. The local backend runs the stage once
|
|
187
|
+
with the first profile; scalar mappings and one-item lists retain the
|
|
188
|
+
single-job behavior.
|
|
189
|
+
|
|
190
|
+
Alternative attempts are submitted held. klej records every physical job ID
|
|
191
|
+
in the workflow plan and target reservation before releasing them. The
|
|
192
|
+
winning attempt best-effort cancels its siblings; reservation cleanup retries
|
|
193
|
+
active registered physical jobs other than itself, waits for Slurm's
|
|
194
|
+
configured `KillWait` plus five seconds after any cancellation, and confirms
|
|
195
|
+
they have left `squeue` before releasing the reservation. If the configuration
|
|
196
|
+
cannot be read, cleanup warns and uses Slurm's 30-second `KillWait` default. A
|
|
197
|
+
query or cancellation failure, or a job still present after the wait, fails
|
|
198
|
+
cleanup and retains the reservation for inspection and explicit lock
|
|
199
|
+
recovery. If submission or registration fails after `sbatch` may have run,
|
|
200
|
+
klej cancels all known jobs, including cleanup, and retains the target
|
|
201
|
+
reservation for explicit lock recovery. Once all physical IDs are registered,
|
|
202
|
+
a later submission failure cancels every other job but preserves cleanup so it
|
|
203
|
+
can release the reservation safely.
|
|
204
|
+
|
|
205
|
+
Version-2 workflow records are readable from their initial planned state, even
|
|
206
|
+
before any Slurm ID exists. Cancellation and submission recovery combine IDs
|
|
207
|
+
from the physical plan and the DAWGZ scheduler record so a partially persisted
|
|
208
|
+
submission does not leave a known job behind.
|
|
209
|
+
|
|
210
|
+
The opt-in
|
|
211
|
+
[`alternative-executors-smoke`](examples/alternative-executors-smoke)
|
|
212
|
+
example provides a low-cost real-cluster verification pipeline. It records
|
|
213
|
+
wrapper and payload entry for a successful race and an intentionally failing
|
|
214
|
+
winner, with commands for inspecting logical and physical status and logs.
|
|
215
|
+
Cluster policies and accounting differ, so review its profiles, quotas, and
|
|
216
|
+
costs before submitting it.
|
|
217
|
+
|
|
218
|
+
## Commit modes
|
|
219
|
+
|
|
220
|
+
By default, `klej repro` creates one commit job after all leaf compute jobs
|
|
221
|
+
finish. That job commits the selected `dvc.yaml` using the `commit` profile
|
|
222
|
+
from `klej.yaml`.
|
|
223
|
+
|
|
224
|
+
Three mutually exclusive flags provide alternative metadata placement:
|
|
225
|
+
|
|
226
|
+
* `--commit-per-stage` runs `dvc commit` for each stage target inside its
|
|
227
|
+
compute job. The commit therefore uses the stage's profile.
|
|
228
|
+
* `--separate-commit-jobs` creates a dedicated commit job after each compute
|
|
229
|
+
job. These jobs use the `commit` profile, and downstream computation waits
|
|
230
|
+
for the upstream commit job to finish.
|
|
231
|
+
* `--no-dvc-metadata` executes stages without updating DVC metadata or caches.
|
|
232
|
+
|
|
233
|
+
Independently, DVC-compatible `--no-commit` still updates `dvc.lock` but does
|
|
234
|
+
not cache outputs or create run-cache entries.
|
|
235
|
+
|
|
236
|
+
```console
|
|
237
|
+
# One final commit job (default)
|
|
238
|
+
klej repro path/to/dvc.yaml
|
|
239
|
+
|
|
240
|
+
# Commit each target in its compute job
|
|
241
|
+
klej repro path/to/dvc.yaml --commit-per-stage
|
|
242
|
+
|
|
243
|
+
# Commit each target in a separate job
|
|
244
|
+
klej repro path/to/dvc.yaml --separate-commit-jobs
|
|
245
|
+
|
|
246
|
+
# Update dvc.lock without caching outputs
|
|
247
|
+
klej repro path/to/dvc.yaml --no-commit
|
|
248
|
+
|
|
249
|
+
# Do not update DVC metadata
|
|
250
|
+
klej repro path/to/dvc.yaml --no-dvc-metadata
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
All commits are serialized through klej's repository-wide commit lock and
|
|
254
|
+
invoke `dvc commit --force`.
|
|
255
|
+
|
|
256
|
+
## Execution environment
|
|
257
|
+
|
|
258
|
+
klej installs an immutable, standalone compute runner under `.klej/runners/`
|
|
259
|
+
in the directory where the command is run and keeps shared coordination data
|
|
260
|
+
under `.klej/locks/` there. Add `.klej/` to the consumer repository's ignore
|
|
261
|
+
rules. The repository must be visible at the same path to submission and
|
|
262
|
+
compute nodes. Containers need Python and the pinned DVC version, but do not
|
|
263
|
+
need klej installed.
|
|
264
|
+
|
|
265
|
+
## Wrapper examples
|
|
266
|
+
|
|
267
|
+
Environment values can refer to submission-side variables as `$NAME` or
|
|
268
|
+
`${NAME}`. A profile's environment is applied after the global environment.
|
|
269
|
+
The wrapper runs from the DVC repository root and is used only with Slurm.
|
|
270
|
+
|
|
271
|
+
Set `wrapper` to an executable that prepares the compute-node environment and
|
|
272
|
+
runs its final argument as a shell command. For example, put one of the scripts
|
|
273
|
+
below in the repository and reference it from `klej.yaml`:
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
wrapper: [./wrappers/run.sh]
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Make the script executable with `chmod +x wrappers/run.sh`. The environment
|
|
280
|
+
must provide Python and the pinned DVC version.
|
|
281
|
+
|
|
282
|
+
An Apptainer wrapper can bind the repository at the same path inside the
|
|
283
|
+
container:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
#!/usr/bin/env bash
|
|
287
|
+
set -euo pipefail
|
|
288
|
+
|
|
289
|
+
readonly PROJECT_DIR="$(pwd -P)"
|
|
290
|
+
readonly IMAGE="${PROJECT_DIR}/containers/project.sif"
|
|
291
|
+
|
|
292
|
+
[[ -f "${IMAGE}" ]] || {
|
|
293
|
+
printf 'container image not found: %s\n' "${IMAGE}" >&2
|
|
294
|
+
exit 1
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
exec apptainer exec \
|
|
298
|
+
--bind "${PROJECT_DIR}:${PROJECT_DIR}" \
|
|
299
|
+
--pwd "${PROJECT_DIR}" \
|
|
300
|
+
"${IMAGE}" bash -c "$1"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
For a Conda environment:
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
#!/usr/bin/env bash
|
|
307
|
+
set -euo pipefail
|
|
308
|
+
|
|
309
|
+
exec conda run --no-capture-output -n my-environment bash -c "$1"
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
For a virtual environment stored in the repository:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
#!/usr/bin/env bash
|
|
316
|
+
set -euo pipefail
|
|
317
|
+
|
|
318
|
+
source .venv/bin/activate
|
|
319
|
+
exec bash -c "$1"
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
The equivalent wrapper using uv is:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
#!/usr/bin/env bash
|
|
326
|
+
set -euo pipefail
|
|
327
|
+
|
|
328
|
+
exec uv run -- bash -c "$1"
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
To load environment modules provided by the cluster:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
#!/usr/bin/env bash
|
|
335
|
+
set -euo pipefail
|
|
336
|
+
|
|
337
|
+
module load python/3.12 cuda/12.4
|
|
338
|
+
exec bash -c "$1"
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Replace the example environment names, image path, and module versions with
|
|
342
|
+
those available on the cluster. Add `--nv` to `apptainer exec` when the
|
|
343
|
+
container needs NVIDIA GPU access.
|
|
344
|
+
|
|
345
|
+
## Local backend
|
|
346
|
+
|
|
347
|
+
`--backend local` is intended for development and CI validation of klej's
|
|
348
|
+
planning and execution path. It is not a full alternative to `dvc repro` and
|
|
349
|
+
does not promise Slurm backend parity.
|
|
350
|
+
|
|
351
|
+
## Examples
|
|
352
|
+
|
|
353
|
+
Runnable pipelines are available in [`examples`](examples/README.md). Each
|
|
354
|
+
example is an independent DVC repository with its own `dvc.yaml` and
|
|
355
|
+
`klej.yaml`.
|
|
356
|
+
|
|
357
|
+
## Workflow status
|
|
358
|
+
|
|
359
|
+
`klej status` lists active Slurm workflows recorded in the current `.dawgz`
|
|
360
|
+
directory. A workflow is active while any job is pending or running. The
|
|
361
|
+
summary shows the workflow ID, DVC pipeline, and counts of pending, running,
|
|
362
|
+
succeeded, failed, cancelled, and unknown jobs. Counts include compute,
|
|
363
|
+
commit, and reservation-cleanup jobs. Local-backend workflows are omitted.
|
|
364
|
+
|
|
365
|
+
`klej status WORKFLOW_ID` prints the aggregate state and every DAWGZ job in
|
|
366
|
+
stable zero-based order. It deliberately does not truncate or page large
|
|
367
|
+
foreach or matrix workflows. New compute jobs are identified by their exact
|
|
368
|
+
expanded DVC target, such as `dvc.yaml:simulate@0`; internal jobs retain their
|
|
369
|
+
descriptive DAWGZ name. Older records without exact-target metadata remain
|
|
370
|
+
readable using their recorded names. The `START TIME` column contains Slurm's
|
|
371
|
+
unmodified accounting start date-time, or `-` when it is unavailable. Rows
|
|
372
|
+
with known start times are ordered from oldest to newest; missing start times
|
|
373
|
+
appear last in stable DAWGZ order.
|
|
374
|
+
|
|
375
|
+
For alternative resource profiles, status shows one logical row and summary
|
|
376
|
+
count per stage. The winning attempt and success gate determine that row;
|
|
377
|
+
losing attempts do not count as failed workloads. Cancelling a claimed stage
|
|
378
|
+
is reported as cancelled unless its payload failure was already recorded or
|
|
379
|
+
the claimant failed in Slurm. Use
|
|
380
|
+
`klej status WORKFLOW_ID --physical` to append every attempt, gate, commit, and
|
|
381
|
+
cleanup job with its raw Slurm state and exit code. Losing siblings appear as
|
|
382
|
+
`superseded`. Workflow terminality and safe record clearing still account for
|
|
383
|
+
all physical jobs, including rows hidden from the default logical view.
|
|
384
|
+
|
|
385
|
+
`klej status --failed` lists terminal Slurm workflows containing at least one
|
|
386
|
+
failed or cancelled job. A workflow containing an unknown job is not known to
|
|
387
|
+
be terminal. Slurm accounting has a cluster-defined retention window: once a
|
|
388
|
+
job disappears from `sacct`, klej reports it as unknown, so sufficiently old
|
|
389
|
+
failed workflows may no longer appear in this listing.
|
|
390
|
+
|
|
391
|
+
`klej status --finished` lists every recorded workflow known to be terminal,
|
|
392
|
+
including local-backend records, with an aggregate status of `succeeded`,
|
|
393
|
+
`failed`, or `cancelled`. Its `SUBMISSION` column contains the DAWGZ workflow
|
|
394
|
+
submission date-time, and rows are ordered from oldest to newest. Legacy
|
|
395
|
+
records without that timestamp show `-` after timestamped workflows. Pending,
|
|
396
|
+
running, and unknown workflows are omitted.
|
|
397
|
+
|
|
398
|
+
Slurm states are normalized to pending, running, succeeded, failed, cancelled,
|
|
399
|
+
or unknown while the complete scheduler value remains visible in detailed
|
|
400
|
+
status. For example, `COMPLETED+` is succeeded, `CANCELLED by 12345` is
|
|
401
|
+
cancelled, and timeout, out-of-memory, and node failures are failed.
|
|
402
|
+
|
|
403
|
+
## Job logs
|
|
404
|
+
|
|
405
|
+
`klej logs WORKFLOW_ID JOB` writes the currently available DAWGZ log directly
|
|
406
|
+
to standard output without a heading. `JOB` may be the zero-based index from
|
|
407
|
+
detailed status, an exact Slurm ID, or the exact displayed target/name when it
|
|
408
|
+
is unique. Internal jobs, including separate commit jobs, use their job names
|
|
409
|
+
as identities. For an alternative-profile stage, its target, name, or logical
|
|
410
|
+
index selects the attempt that claimed the race, including a claimant whose
|
|
411
|
+
payload failed. An exact Slurm ID instead selects that physical job directly,
|
|
412
|
+
so superseded attempts and internal gate, commit, or cleanup jobs remain
|
|
413
|
+
inspectable. Exact Slurm IDs take precedence over logical indexes. Ambiguous
|
|
414
|
+
selectors are rejected with the matching indices.
|
|
415
|
+
|
|
416
|
+
Use `--tail N` to start with the last `N` lines and `--follow` to stream new
|
|
417
|
+
content. Combining them follows from the tailed content; without `--tail`,
|
|
418
|
+
following starts with the complete existing log. If an active job has not
|
|
419
|
+
created its log yet, follow mode waits and reports that once on standard error.
|
|
420
|
+
Following stops after the job becomes terminal and all available bytes have
|
|
421
|
+
been emitted. Submission tracebacks recorded by DAWGZ are printed when no
|
|
422
|
+
Slurm log was created. If an alternative race is unresolved, a normal request
|
|
423
|
+
lists its attempt IDs, profiles, and states. Follow mode waits while an attempt
|
|
424
|
+
can still claim the race and then follows the claimant. When accounting has no
|
|
425
|
+
state for an attempt, follow mode checks whether it remains in the Slurm queue
|
|
426
|
+
before waiting. It does not choose an attempt merely because its log appeared
|
|
427
|
+
first. Detailed status and logs are not supported for local-backend workflow
|
|
428
|
+
records.
|
|
429
|
+
|
|
430
|
+
`klej logs --clear WORKFLOW_ID` removes a known-terminal workflow's complete
|
|
431
|
+
DAWGZ record, including its logs, and removes its rows from `workflows.csv`.
|
|
432
|
+
`klej logs --clear-all` does the same for every known-terminal Slurm and local
|
|
433
|
+
workflow while retaining pending, running, and unknown records. Both commands
|
|
434
|
+
ask for confirmation; `--force` skips that prompt but never permits deletion
|
|
435
|
+
of an active or unknown workflow. For versioned plans, this safety check
|
|
436
|
+
includes every physical attempt and internal gate, commit, and cleanup job,
|
|
437
|
+
including jobs hidden by the logical status view. Cleanup does not cancel
|
|
438
|
+
jobs, release klej locks, or delete DVC outputs.
|
|
439
|
+
|
|
440
|
+
Do not run record cleanup concurrently with workflow submission. DAWGZ does
|
|
441
|
+
not coordinate updates to its `workflows.csv` index with external cleanup.
|