experimaestro 1.8.8__py3-none-any.whl → 1.9.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.
Potentially problematic release.
This version of experimaestro might be problematic. Click here for more details.
- experimaestro/cli/filter.py +8 -1
- experimaestro/cli/jobs.py +10 -2
- experimaestro/connectors/__init__.py +5 -2
- experimaestro/connectors/local.py +2 -2
- experimaestro/launchers/slurm/base.py +4 -4
- experimaestro/mkdocs/__init__.py +1 -1
- {experimaestro-1.8.8.dist-info → experimaestro-1.9.0.dist-info}/METADATA +1 -1
- {experimaestro-1.8.8.dist-info → experimaestro-1.9.0.dist-info}/RECORD +11 -11
- {experimaestro-1.8.8.dist-info → experimaestro-1.9.0.dist-info}/LICENSE +0 -0
- {experimaestro-1.8.8.dist-info → experimaestro-1.9.0.dist-info}/WHEEL +0 -0
- {experimaestro-1.8.8.dist-info → experimaestro-1.9.0.dist-info}/entry_points.txt +0 -0
experimaestro/cli/filter.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
from typing import Any, Callable, Dict, List, Optional
|
|
2
3
|
import pyparsing as pp
|
|
3
4
|
from pathlib import Path
|
|
@@ -8,9 +9,10 @@ from experimaestro.scheduler import JobState
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class JobInformation:
|
|
11
|
-
def __init__(self, path: Path, scriptname: str):
|
|
12
|
+
def __init__(self, path: Path, scriptname: str, check: bool = False):
|
|
12
13
|
self.path = path
|
|
13
14
|
self.scriptname = scriptname
|
|
15
|
+
self.check = check
|
|
14
16
|
|
|
15
17
|
@cached_property
|
|
16
18
|
def params(self):
|
|
@@ -27,6 +29,11 @@ class JobInformation:
|
|
|
27
29
|
if (self.path / f"{self.scriptname}.failed").is_file():
|
|
28
30
|
return JobState.ERROR
|
|
29
31
|
if (self.path / f"{self.scriptname}.pid").is_file():
|
|
32
|
+
if self.check:
|
|
33
|
+
process = self.getprocess()
|
|
34
|
+
state = asyncio.run(process.aio_state(0))
|
|
35
|
+
if state.finished:
|
|
36
|
+
return JobState.ERROR
|
|
30
37
|
return JobState.RUNNING
|
|
31
38
|
else:
|
|
32
39
|
return None
|
experimaestro/cli/jobs.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# flake8: noqa: T201
|
|
2
|
+
import asyncio
|
|
2
3
|
import subprocess
|
|
3
4
|
from typing import Optional
|
|
4
5
|
from shutil import rmtree
|
|
@@ -49,6 +50,7 @@ def process(
|
|
|
49
50
|
filter="",
|
|
50
51
|
perform=False,
|
|
51
52
|
fullpath=False,
|
|
53
|
+
check=False,
|
|
52
54
|
):
|
|
53
55
|
from .filter import createFilter, JobInformation
|
|
54
56
|
from experimaestro.scheduler import JobState
|
|
@@ -69,7 +71,9 @@ def process(
|
|
|
69
71
|
if (p / "jobs.bak").is_dir():
|
|
70
72
|
cprint(f" Experiment {p.name} has not finished yet", "red")
|
|
71
73
|
if (not perform) and (kill or clean):
|
|
72
|
-
cprint(
|
|
74
|
+
cprint(
|
|
75
|
+
" Preventing kill/clean (use --perform if you want to)", "yellow"
|
|
76
|
+
)
|
|
73
77
|
kill = False
|
|
74
78
|
clean = False
|
|
75
79
|
|
|
@@ -83,7 +87,7 @@ def process(
|
|
|
83
87
|
if experiment and experiment not in xps:
|
|
84
88
|
continue
|
|
85
89
|
|
|
86
|
-
info = JobInformation(p, scriptname)
|
|
90
|
+
info = JobInformation(p, scriptname, check=check)
|
|
87
91
|
job_str = (
|
|
88
92
|
(str(job.resolve()) if fullpath else f"{job.parent.name}/{job.name}")
|
|
89
93
|
+ " "
|
|
@@ -151,6 +155,7 @@ def process(
|
|
|
151
155
|
@click.option("--ready", is_flag=True, help="Include tasks which are not yet scheduled")
|
|
152
156
|
@click.option("--filter", default="", help="Filter expression")
|
|
153
157
|
@click.option("--fullpath", is_flag=True, help="Prints full paths")
|
|
158
|
+
@click.option("--no-check", is_flag=True, help="Check that running jobs")
|
|
154
159
|
@jobs.command()
|
|
155
160
|
@click.pass_context
|
|
156
161
|
def list(
|
|
@@ -160,6 +165,7 @@ def list(
|
|
|
160
165
|
tags: bool,
|
|
161
166
|
ready: bool,
|
|
162
167
|
fullpath: bool,
|
|
168
|
+
no_check: bool,
|
|
163
169
|
):
|
|
164
170
|
process(
|
|
165
171
|
ctx.obj.workspace,
|
|
@@ -168,6 +174,7 @@ def list(
|
|
|
168
174
|
tags=tags,
|
|
169
175
|
ready=ready,
|
|
170
176
|
fullpath=fullpath,
|
|
177
|
+
check=not no_check,
|
|
171
178
|
)
|
|
172
179
|
|
|
173
180
|
|
|
@@ -187,6 +194,7 @@ def kill(
|
|
|
187
194
|
ready: bool,
|
|
188
195
|
fullpath: bool,
|
|
189
196
|
perform: bool,
|
|
197
|
+
check: bool,
|
|
190
198
|
):
|
|
191
199
|
process(
|
|
192
200
|
ctx.obj.workspace,
|
|
@@ -114,8 +114,11 @@ class Process:
|
|
|
114
114
|
"""Wait until the process finishes and returns the error code"""
|
|
115
115
|
raise NotImplementedError(f"Not implemented: {self.__class__}.wait")
|
|
116
116
|
|
|
117
|
-
async def aio_state(self) -> ProcessState:
|
|
118
|
-
"""Returns the job state
|
|
117
|
+
async def aio_state(self, timeout: float | None = None) -> ProcessState:
|
|
118
|
+
"""Returns the job state
|
|
119
|
+
|
|
120
|
+
:param timeout: maximum waiting time for a refresh
|
|
121
|
+
"""
|
|
119
122
|
raise NotImplementedError(f"Not implemented: {self.__class__}.aio_state")
|
|
120
123
|
|
|
121
124
|
async def aio_isrunning(self):
|
|
@@ -39,7 +39,7 @@ class PsutilProcess(Process):
|
|
|
39
39
|
)
|
|
40
40
|
return code
|
|
41
41
|
|
|
42
|
-
async def aio_state(self):
|
|
42
|
+
async def aio_state(self, timeout: float | None = None) -> ProcessState:
|
|
43
43
|
if self._process.is_running():
|
|
44
44
|
return ProcessState.RUNNING
|
|
45
45
|
return ProcessState.FINISHED
|
|
@@ -65,7 +65,7 @@ class LocalProcess(Process):
|
|
|
65
65
|
)
|
|
66
66
|
return code
|
|
67
67
|
|
|
68
|
-
async def aio_state(self):
|
|
68
|
+
async def aio_state(self, timeout: float | None = None) -> ProcessState:
|
|
69
69
|
code = self._process.poll()
|
|
70
70
|
if code is None:
|
|
71
71
|
return ProcessState.RUNNING
|
|
@@ -87,7 +87,7 @@ class SlurmProcessWatcher(threading.Thread):
|
|
|
87
87
|
WATCHERS: Dict[Tuple[Tuple[str, Any]], "SlurmProcessWatcher"] = {}
|
|
88
88
|
|
|
89
89
|
def __init__(self, launcher: "SlurmLauncher"):
|
|
90
|
-
super().__init__()
|
|
90
|
+
super().__init__(daemon=True)
|
|
91
91
|
self.launcher = launcher
|
|
92
92
|
self.count = 1
|
|
93
93
|
self.jobs: Dict[str, SlurmJobState] = {}
|
|
@@ -184,10 +184,10 @@ class BatchSlurmProcess(Process):
|
|
|
184
184
|
if state and state.finished():
|
|
185
185
|
return 0 if state.slurm_state == "COMPLETED" else 1
|
|
186
186
|
|
|
187
|
-
async def aio_state(self):
|
|
187
|
+
async def aio_state(self, timeout: float | None = None) -> ProcessState:
|
|
188
188
|
def check():
|
|
189
189
|
with SlurmProcessWatcher.get(self.launcher) as watcher:
|
|
190
|
-
jobinfo = watcher.getjob(self.jobid)
|
|
190
|
+
jobinfo = watcher.getjob(self.jobid, timeout=timeout)
|
|
191
191
|
return jobinfo.state if jobinfo else ProcessState.SCHEDULED
|
|
192
192
|
|
|
193
193
|
return await asyncThreadcheck("slurm.aio_isrunning", check)
|
|
@@ -212,7 +212,7 @@ class BatchSlurmProcess(Process):
|
|
|
212
212
|
|
|
213
213
|
# Checks that the process is running
|
|
214
214
|
with SlurmProcessWatcher.get(launcher) as watcher:
|
|
215
|
-
logger.
|
|
215
|
+
logger.debug("Checking SLURM job %s", process.jobid)
|
|
216
216
|
jobinfo = watcher.getjob(process.jobid, timeout=0.1)
|
|
217
217
|
if jobinfo and jobinfo.state.running:
|
|
218
218
|
logger.debug(
|
experimaestro/mkdocs/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
from .base import Documentation # noqa: F401
|
|
@@ -3,13 +3,13 @@ experimaestro/__main__.py,sha256=Dv9lFl03yt1dswd0Xb9NIJRgHpA5_IwH4RfQPEHyFz0,158
|
|
|
3
3
|
experimaestro/annotations.py,sha256=wyVmPlkXuoT6IxJ-ti8bFo6HxhGY1BYBxM5-pib6shU,8773
|
|
4
4
|
experimaestro/checkers.py,sha256=ZCMbnE_GFC5compWjt-fuHhPImi9fCPjImF8Ow9NqK8,696
|
|
5
5
|
experimaestro/cli/__init__.py,sha256=mzc-qqTFtZnFwCQl7IiwlYXEx08kLGwdntWayCerZ6E,9610
|
|
6
|
-
experimaestro/cli/filter.py,sha256=
|
|
7
|
-
experimaestro/cli/jobs.py,sha256=
|
|
6
|
+
experimaestro/cli/filter.py,sha256=dKRhEsIdEYv_WfLtTJkl0a6uiCg9Q-K5YxWjVSU1af8,6050
|
|
7
|
+
experimaestro/cli/jobs.py,sha256=5BcEy0c2CQzZkG6Q4mzOWQPYxMKf-zK89DHFFB9FqBY,7993
|
|
8
8
|
experimaestro/click.py,sha256=6BkeQHEgcxaxzq3xEvEEzwzuBj5-dkfrpOGikuA8L00,1377
|
|
9
9
|
experimaestro/commandline.py,sha256=MJIJcfppGCjNA8ozxXUzbUSeDOlTExuzhxryGx3_lIo,9314
|
|
10
10
|
experimaestro/compat.py,sha256=dQqE2ZNHLM2wtdfp7fBRYMfC33qNehVf9J6FGRBUQhs,171
|
|
11
|
-
experimaestro/connectors/__init__.py,sha256=
|
|
12
|
-
experimaestro/connectors/local.py,sha256=
|
|
11
|
+
experimaestro/connectors/__init__.py,sha256=UKhDU3uv9jFH37oUb0JiejrekA85xtEirn79pA7DFhI,6125
|
|
12
|
+
experimaestro/connectors/local.py,sha256=lCGIubqmUJZ1glLtLRXOgakTMfEaEmFtNkEcw9qV5vw,6143
|
|
13
13
|
experimaestro/connectors/ssh.py,sha256=5giqvv1y0QQKF-GI0IFUzI_Z5H8Bj9EuL_Szpvk899Q,8600
|
|
14
14
|
experimaestro/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
experimaestro/core/arguments.py,sha256=7hpkU1f8LJ7JL8kQaD514h9CFSfMotYLsVfMsMmdpWk,6487
|
|
@@ -41,9 +41,9 @@ experimaestro/launchers/__init__.py,sha256=lXn544sgJExr6uirILWzAXu_IfmfyqFZOt4Oz
|
|
|
41
41
|
experimaestro/launchers/direct.py,sha256=JZh6WOPnO6ED_xlOs8pL4MRFmnRhmXzpVxTl-ByaD2A,258
|
|
42
42
|
experimaestro/launchers/oar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
experimaestro/launchers/slurm/__init__.py,sha256=R1Zwd4phZaXV8FwCYhzfB44n0V4cf-hBQzOc6NkFQ0s,41
|
|
44
|
-
experimaestro/launchers/slurm/base.py,sha256=
|
|
44
|
+
experimaestro/launchers/slurm/base.py,sha256=2CPNJeTNuwPOjqgmdkZ3MfdZbKQTIwlJtu_JL-IClg8,15753
|
|
45
45
|
experimaestro/locking.py,sha256=hPT-LuDGZTijpbme8O0kEoB9a3WjdVzI2h31OT44UxE,1477
|
|
46
|
-
experimaestro/mkdocs/__init__.py,sha256=
|
|
46
|
+
experimaestro/mkdocs/__init__.py,sha256=L9UDM7vOrRZl41zXTBOaHKSINEEsbmxwjIMIGESmLfU,46
|
|
47
47
|
experimaestro/mkdocs/annotations.py,sha256=qpDw8lzrxpsOShXcpcP_LAeR3UhiIXAybG8UvS64-OU,263
|
|
48
48
|
experimaestro/mkdocs/base.py,sha256=SwLh9s7BZfrTAZdBaealSqVeLAroDSwLLMOHmLCxMPQ,16716
|
|
49
49
|
experimaestro/mkdocs/metaloader.py,sha256=qCqnTWhlgxql-oe46E8AbvYdoM311-lQh-msmPnbllQ,1481
|
|
@@ -150,8 +150,8 @@ experimaestro/utils/jupyter.py,sha256=JcEo2yQK7x3Cr1tNl5FqGMZOICxCv9DwMvL5xsWdQP
|
|
|
150
150
|
experimaestro/utils/resources.py,sha256=j-nvsTFwmgENMoVGOD2Ap-UD3WU85WkI0IgeSszMCX4,1328
|
|
151
151
|
experimaestro/utils/settings.py,sha256=jpFMqF0DLL4_P1xGal0zVR5cOrdD8O0Y2IOYvnRgN3k,793
|
|
152
152
|
experimaestro/xpmutils.py,sha256=S21eMbDYsHfvmZ1HmKpq5Pz5O-1HnCLYxKbyTBbASyQ,638
|
|
153
|
-
experimaestro-1.
|
|
154
|
-
experimaestro-1.
|
|
155
|
-
experimaestro-1.
|
|
156
|
-
experimaestro-1.
|
|
157
|
-
experimaestro-1.
|
|
153
|
+
experimaestro-1.9.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
154
|
+
experimaestro-1.9.0.dist-info/METADATA,sha256=L-po2w1CEX5e70CFu6G35rOrqKThfuo-hidKJ5bOvgc,6170
|
|
155
|
+
experimaestro-1.9.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
156
|
+
experimaestro-1.9.0.dist-info/entry_points.txt,sha256=TppTNiz5qm5xm1fhAcdLKdCLMrlL-eQggtCrCI00D9c,446
|
|
157
|
+
experimaestro-1.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|