experimaestro 1.9.1__py3-none-any.whl → 1.10.1__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.

@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import logging
2
3
  from typing import Any, Callable, Dict, List, Optional
3
4
  import pyparsing as pp
4
5
  from pathlib import Path
@@ -16,7 +17,11 @@ class JobInformation:
16
17
 
17
18
  @cached_property
18
19
  def params(self):
19
- return json.loads((self.path / "params.json").read_text())
20
+ try:
21
+ return json.loads((self.path / "params.json").read_text())
22
+ except Exception:
23
+ logging.warning("Could not load params.json in %s", self.path)
24
+ return {"tags": {}}
20
25
 
21
26
  @cached_property
22
27
  def tags(self) -> List[str]:
@@ -51,7 +51,12 @@ def cpu():
51
51
 
52
52
 
53
53
  def duration():
54
- return "duration", "=", RegExMatch(r"\d+"), RegExMatch(r"h(ours)?|d(ays)?")
54
+ return (
55
+ "duration",
56
+ "=",
57
+ RegExMatch(r"\d+"),
58
+ RegExMatch(r"h(ours?)?|d(ays?)?|m(ins?)?"),
59
+ )
55
60
 
56
61
 
57
62
  def one_spec():
@@ -67,7 +72,7 @@ def grammar():
67
72
 
68
73
  class Visitor(PTNodeVisitor):
69
74
  def visit_grammar(self, node, children):
70
- return [child for child in children]
75
+ return specs.RequirementUnion(*[child for child in children])
71
76
 
72
77
  def visit_one_spec(self, node, children):
73
78
  return reduce(lambda x, el: x & el, children)
@@ -9,7 +9,7 @@ from omegaconf import DictConfig, OmegaConf, SCMode
9
9
  import pkg_resources
10
10
  from experimaestro.utils import logger
11
11
  from .base import ConnectorConfiguration, TokenConfiguration
12
- from .specs import HostRequirement
12
+ from .specs import HostRequirement, RequirementUnion
13
13
 
14
14
  if typing.TYPE_CHECKING:
15
15
  from experimaestro.launchers import Launcher
@@ -150,18 +150,18 @@ class LauncherRegistry:
150
150
  # Parse specs
151
151
  from .parser import parse
152
152
 
153
- specs = []
153
+ specs = RequirementUnion()
154
154
  for spec in input_specs:
155
155
  if isinstance(spec, str):
156
- specs.extend(parse(spec))
156
+ specs.add(parse(spec))
157
157
  else:
158
- specs.append(spec)
158
+ specs.add(spec)
159
159
 
160
160
  # Use launcher function
161
161
  from experimaestro.launchers import Launcher
162
162
 
163
163
  if self.find_launcher_fn is not None:
164
- for spec in specs:
164
+ for spec in specs.requirements:
165
165
  if launcher := self.find_launcher_fn(spec, tags):
166
166
  assert isinstance(
167
167
  launcher, Launcher
@@ -1,4 +1,6 @@
1
+ from abc import ABC, abstractmethod
1
2
  import logging
3
+ import math
2
4
  from attr import Factory
3
5
  from attrs import define
4
6
  from copy import copy, deepcopy
@@ -88,7 +90,7 @@ class MatchRequirement:
88
90
  requirement: "HostSimpleRequirement"
89
91
 
90
92
 
91
- class HostRequirement:
93
+ class HostRequirement(ABC):
92
94
  """A requirement must be a disjunction of host requirements"""
93
95
 
94
96
  requirements: List["HostSimpleRequirement"]
@@ -103,6 +105,12 @@ class HostRequirement:
103
105
  def match(self, host: HostSpecification) -> Optional[MatchRequirement]:
104
106
  raise NotImplementedError()
105
107
 
108
+ @abstractmethod
109
+ def multiply_duration(self, coefficient: float) -> "HostRequirement":
110
+ """Returns a new HostRequirement with a duration multiplied by the
111
+ provided coefficient"""
112
+ ...
113
+
106
114
 
107
115
  class RequirementUnion(HostRequirement):
108
116
  """Ordered list of simple host requirements -- the first one is the priority"""
@@ -112,6 +120,16 @@ class RequirementUnion(HostRequirement):
112
120
  def __init__(self, *requirements: "HostSimpleRequirement"):
113
121
  self.requirements = list(requirements)
114
122
 
123
+ def add(self, requirement: "HostRequirement"):
124
+ match requirement:
125
+ case HostSimpleRequirement():
126
+ self.requirements.extend(*requirement.requirements)
127
+ case RequirementUnion():
128
+ self.requirements.append(requirement)
129
+ case _:
130
+ raise RuntimeError("Cannot handle type %s", type(requirement))
131
+ return self
132
+
115
133
  def match(self, host: HostSpecification) -> Optional[MatchRequirement]:
116
134
  """Returns the matched requirement (if any)"""
117
135
 
@@ -126,6 +144,14 @@ class RequirementUnion(HostRequirement):
126
144
 
127
145
  return argmax
128
146
 
147
+ def multiply_duration(self, coefficient: float) -> "RequirementUnion":
148
+ return RequirementUnion(
149
+ *[r.multiply_duration(coefficient) for r in self.requirements]
150
+ )
151
+
152
+ def __repr__(self):
153
+ return " | ".join(repr(r) for r in self.requirements)
154
+
129
155
 
130
156
  class HostSimpleRequirement(HostRequirement):
131
157
  """Simple host requirement"""
@@ -142,6 +168,11 @@ class HostSimpleRequirement(HostRequirement):
142
168
  def __repr__(self):
143
169
  return f"Req(cpu={self.cpu}, cuda={self.cuda_gpus}, duration={self.duration})"
144
170
 
171
+ def multiply_duration(self, coefficient: float) -> "HostSimpleRequirement":
172
+ r = HostSimpleRequirement(self)
173
+ r.duration = math.ceil(self.duration * coefficient)
174
+ return r
175
+
145
176
  def __init__(self, *reqs: "HostSimpleRequirement"):
146
177
  self.cuda_gpus = []
147
178
  self.cpu = CPUSpecification(0, 0)
@@ -3,9 +3,9 @@ from experimaestro.launcherfinder.specs import (
3
3
  CPUSpecification,
4
4
  CudaSpecification,
5
5
  HostSpecification,
6
+ RequirementUnion,
6
7
  cpu,
7
8
  cuda_gpu,
8
- HostSimpleRequirement,
9
9
  )
10
10
  from experimaestro.launcherfinder import parse
11
11
  from humanfriendly import parse_size, parse_timespan
@@ -39,6 +39,11 @@ def test_findlauncher_specs():
39
39
  assert m is not None
40
40
  assert m.requirement is req2
41
41
 
42
+ # Multiply
43
+ req2 = req.multiply_duration(2)
44
+ for i in range(2):
45
+ assert req2.requirements[i].duration == req.requirements[i].duration * 2
46
+
42
47
 
43
48
  def test_findlauncher_specs_gpu_mem():
44
49
  host = HostSpecification(
@@ -60,8 +65,10 @@ def test_findlauncher_specs_gpu_mem():
60
65
 
61
66
 
62
67
  def test_findlauncher_parse():
63
- (r,) = parse("""duration=4 d & cuda(mem=4G) * 2 & cpu(mem=400M, cores=4)""")
64
- assert isinstance(r, HostSimpleRequirement)
68
+ r = parse("""duration=4 d & cuda(mem=4G) * 2 & cpu(mem=400M, cores=4)""")
69
+ assert isinstance(r, RequirementUnion)
70
+
71
+ r = r.requirements[0]
65
72
 
66
73
  assert len(r.cuda_gpus) == 2
67
74
  assert r.cuda_gpus[0].memory == parse_size("4G")
@@ -79,7 +86,7 @@ def slurm_constraint_split(constraint: str):
79
86
 
80
87
 
81
88
  def test_findlauncher_slurm():
82
- path = ResourcePathWrapper.create(f"{__package__ }.launchers", "config_slurm")
89
+ path = ResourcePathWrapper.create(f"{__package__}.launchers", "config_slurm")
83
90
 
84
91
  assert (path / "launchers.py").is_file()
85
92
 
@@ -1,52 +1,45 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: experimaestro
3
- Version: 1.9.1
3
+ Version: 1.10.1
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
5
  License: GPL-3
6
6
  Keywords: experiment manager
7
7
  Author: Benjamin Piwowarski
8
8
  Author-email: benjamin@piwowarski.fr
9
- Requires-Python: >=3.9,<4.0
9
+ Requires-Python: >=3.10
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Science/Research
12
12
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
- Classifier: License :: Other/Proprietary License
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Programming Language :: Python
16
15
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
21
- Classifier: Programming Language :: Python :: 3.13
22
16
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
17
  Requires-Dist: arpeggio (>=2,<3)
24
- Requires-Dist: attrs (>=23.1.0,<24.0.0)
18
+ Requires-Dist: attrs (>=23.1.0,<24)
25
19
  Requires-Dist: click (>=8)
26
20
  Requires-Dist: decorator (>=5,<6)
27
- Requires-Dist: docstring-parser (>=0.15,<0.16)
28
- Requires-Dist: fasteners (>=0.19,<0.20)
29
- Requires-Dist: flask (>=2.3,<3.0)
30
- Requires-Dist: flask-socketio (>=5.3,<6.0)
31
- Requires-Dist: gevent (>=24.11.1,<25.0.0)
32
- Requires-Dist: gevent-websocket (>=0.10,<0.11)
21
+ Requires-Dist: docstring-parser (>=0.15,<1)
22
+ Requires-Dist: fasteners (>=0.19,<1)
23
+ Requires-Dist: flask (>=2.3,<3)
24
+ Requires-Dist: flask-socketio (>=5.3,<6)
25
+ Requires-Dist: gevent (>=25)
26
+ Requires-Dist: gevent-websocket (>=0.10)
33
27
  Requires-Dist: huggingface-hub (>0.17)
34
- Requires-Dist: humanfriendly (>=10,<11)
35
- Requires-Dist: marshmallow (>=3.20,<4.0)
36
- Requires-Dist: omegaconf (>=2.3,<3.0)
37
- Requires-Dist: psutil (>=7)
38
- Requires-Dist: pyparsing (>=3.1,<4.0)
39
- Requires-Dist: pytools (>=2023.1.1,<2024.0.0)
40
- Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
41
- Requires-Dist: requests (>=2.31,<3.0)
28
+ Requires-Dist: humanfriendly (>=10)
29
+ Requires-Dist: marshmallow (>=3.20,<4)
30
+ Requires-Dist: mkdocs (>=1.5,<2)
31
+ Requires-Dist: omegaconf (>=2.3,<3)
32
+ Requires-Dist: psutil (>=7,<8)
33
+ Requires-Dist: pyparsing (>=3.1,<4)
34
+ Requires-Dist: pytools (>=2023.1.1,<2024)
35
+ Requires-Dist: pyyaml (>=6.0.1,<7)
36
+ Requires-Dist: requests (>=2.31,<3)
42
37
  Requires-Dist: rpyc (>=5,<7)
43
- Requires-Dist: sortedcontainers (>=2.4,<3.0)
44
- Requires-Dist: termcolor (>=2.3)
45
- Requires-Dist: tqdm (>=4.66.1,<5.0.0)
38
+ Requires-Dist: sortedcontainers (>=2.4,<3)
39
+ Requires-Dist: termcolor (>=2.3,<3)
40
+ Requires-Dist: tqdm (>=4.66.1,<5)
46
41
  Requires-Dist: typing-extensions (>=4.2) ; python_version < "3.12"
47
- Requires-Dist: watchdog (>=2,<3)
48
- Project-URL: Documentation, https://experimaestro-python.readthedocs.io/
49
- Project-URL: Repository, https://github.com/experimaestro/experimaestro-python
42
+ Requires-Dist: watchdog (>=2)
50
43
  Description-Content-Type: text/markdown
51
44
 
52
45
  [![PyPI version](https://badge.fury.io/py/experimaestro.svg)](https://badge.fury.io/py/experimaestro)
@@ -3,7 +3,7 @@ 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=WsoaxnwgkcbMRlWJdV55333F3cLg7W-9Zbx9e66ZmvY,6148
6
+ experimaestro/cli/filter.py,sha256=bINAF-O7CwJ2u3T6xG_Q_niqDbPeoEASyYLuCeNlbFw,6313
7
7
  experimaestro/cli/jobs.py,sha256=BnejUnhKAgMBVgwANfQYj5mLzknXVohveg7NpovNZ8o,7925
8
8
  experimaestro/click.py,sha256=6BkeQHEgcxaxzq3xEvEEzwzuBj5-dkfrpOGikuA8L00,1377
9
9
  experimaestro/commandline.py,sha256=MJIJcfppGCjNA8ozxXUzbUSeDOlTExuzhxryGx3_lIo,9314
@@ -34,9 +34,9 @@ experimaestro/huggingface.py,sha256=gnVlr6SZnbutYz4PLH0Q77n1TRF-uk-dR-3UFzFqAY0,
34
34
  experimaestro/ipc.py,sha256=Xn3tYME83jLEB0nFak3DwEIhpL5IRZpCl3jirBF_jl4,1570
35
35
  experimaestro/launcherfinder/__init__.py,sha256=qRUDyv3B9UsAM8Q31mRrZrTZox0AptwdmOY4f2K-TUo,279
36
36
  experimaestro/launcherfinder/base.py,sha256=q47SsF_cXdo5O6ZhFKn5385WVFcx8Wd-BcEpd6tRpbs,515
37
- experimaestro/launcherfinder/parser.py,sha256=w8JyrBtiD15SYSPmzv06H64WDZAOdrz0xyV703mQ6TQ,2287
38
- experimaestro/launcherfinder/registry.py,sha256=mhFAVgk8t2qWemUlhgM4nftn2x1THm7LTKSyDVsQQ9M,6379
39
- experimaestro/launcherfinder/specs.py,sha256=j3rObYRUi8WbU9n8220usOIWJ9p68Uti0BjkQRqGiZc,6560
37
+ experimaestro/launcherfinder/parser.py,sha256=MIHhjs2sTVxLHLcc1CgFid9XxhInXker8QdA-GBA-Bk,2364
38
+ experimaestro/launcherfinder/registry.py,sha256=F16A7SE_CgzaTBC-LBlurbthTDvYUa5iyjJftkDNN4M,6420
39
+ experimaestro/launcherfinder/specs.py,sha256=484S4-N22Y10BsyTpNwW0l369ALAJUrXQK9LsYSYsaQ,7705
40
40
  experimaestro/launchers/__init__.py,sha256=lXn544sgJExr6uirILWzAXu_IfmfyqFZOt4OzRnjHXg,2525
41
41
  experimaestro/launchers/direct.py,sha256=JZh6WOPnO6ED_xlOs8pL4MRFmnRhmXzpVxTl-ByaD2A,258
42
42
  experimaestro/launchers/oar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -119,7 +119,7 @@ experimaestro/tests/tasks/foreign.py,sha256=uhXDOcWozkcm26ybbeEU9RElJpbhjC-zdzml
119
119
  experimaestro/tests/test_checkers.py,sha256=Kg5frDNRE3pvWVmmYzyk0tJFNO885KOrK48lSu-NlYA,403
120
120
  experimaestro/tests/test_dependencies.py,sha256=xfWrSkvjT45G4FSCL535m1huLT2ghmyW7kvP_XvvCJQ,2005
121
121
  experimaestro/tests/test_experiment.py,sha256=QWF9aHewL9hepagrKKFyfikKn3iiZ_lRRXl1LLttta0,1687
122
- experimaestro/tests/test_findlauncher.py,sha256=8tjpR8bLMi6Gjs7KpY2t64izZso6bmY7vIivMflm-Bc,2965
122
+ experimaestro/tests/test_findlauncher.py,sha256=KPy8ow--NXS1KFCIpxrmEJFRvjo-v-PwlVHVyoVKLPg,3134
123
123
  experimaestro/tests/test_forward.py,sha256=9y1zYm7hT_Lx5citxnK7n20cMZ2WJbsaEeY5irCZ9U4,735
124
124
  experimaestro/tests/test_identifier.py,sha256=zgfpz5UumQftQTHhdw3nmr044Xd7Ntrh7e2hIAoS_PA,13862
125
125
  experimaestro/tests/test_instance.py,sha256=h-8UeoOlNsD-STWq5jbhmxw35CyiwJxtKAaUGmLPgB8,1521
@@ -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.9.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
154
- experimaestro-1.9.1.dist-info/METADATA,sha256=iwhee9G1vBhkBCM-zMWL_FgRwyZSBV7bZJLsnmVgCwk,6170
155
- experimaestro-1.9.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
156
- experimaestro-1.9.1.dist-info/entry_points.txt,sha256=TppTNiz5qm5xm1fhAcdLKdCLMrlL-eQggtCrCI00D9c,446
157
- experimaestro-1.9.1.dist-info/RECORD,,
153
+ experimaestro-1.10.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
154
+ experimaestro-1.10.1.dist-info/METADATA,sha256=5RTdMyryQUQXXnO3VQbI1i0pKFgaVG89LZsyQzaomgw,5689
155
+ experimaestro-1.10.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
156
+ experimaestro-1.10.1.dist-info/entry_points.txt,sha256=TppTNiz5qm5xm1fhAcdLKdCLMrlL-eQggtCrCI00D9c,446
157
+ experimaestro-1.10.1.dist-info/RECORD,,