resubmit 0.0.4__tar.gz → 0.0.6__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: resubmit
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: Small wrapper around submitit to simplify cluster submissions
5
5
  Author: Amir Mehrpanah
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "resubmit"
7
- version = "0.0.4"
7
+ version = "0.0.6"
8
8
  description = "Small wrapper around submitit to simplify cluster submissions"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -5,27 +5,6 @@ from itertools import product
5
5
  import logging
6
6
 
7
7
 
8
- def _is_regex_spec(val: Any) -> bool:
9
- """Return True if val looks like a regex specifier.
10
-
11
- Accepted forms:
12
- - compiled `re.Pattern`
13
- - tuple (`re.Pattern`, exclude: bool)
14
- - dict with keys `pattern` (re.Pattern) and optional `exclude` (bool)
15
- - string starting with 're:' (e.g. 're:^foo.*') meaning include matches
16
- - string starting with '!re:' meaning exclude matches
17
- """
18
- if hasattr(val, "search") and callable(val.search):
19
- return True
20
- if isinstance(val, tuple) and len(val) >= 1 and hasattr(val[0], "search"):
21
- return True
22
- if isinstance(val, dict) and "pattern" in val:
23
- return True
24
- if isinstance(val, str) and (val.startswith("re:") or val.startswith("!re:")):
25
- return True
26
- return False
27
-
28
-
29
8
  def _normalize_regex_spec(val: Any) -> Tuple[re.Pattern, bool]:
30
9
  """Return (compiled_pattern, exclude_flag) for a given regex spec.
31
10
 
@@ -115,11 +94,6 @@ def create_jobs_dataframe(params: Dict[str, Any]) -> pd.DataFrame:
115
94
  base = k[: -len("_unique")]
116
95
  unique_items[base] = v
117
96
  continue
118
- elif callable(v):
119
- callables[k] = v
120
- elif _is_regex_spec(v):
121
- # treat a regex spec provided under the same key as a filter for that column
122
- regex_specs[k] = v
123
97
  else:
124
98
  static_items[k] = v
125
99
 
@@ -206,7 +180,7 @@ def submit_jobs(
206
180
 
207
181
  jobs_df = create_jobs_dataframe(jobs_args)
208
182
  records = jobs_df.to_dict(orient="records")
209
- from .__submit import submit_jobs as _submit_jobs
183
+ from .__submit import _submit_jobs
210
184
 
211
185
  return _submit_jobs(
212
186
  records,
@@ -3,7 +3,7 @@
3
3
  from typing import Any, Callable, Iterable, List, Optional, Dict
4
4
 
5
5
 
6
- def submit_jobs(
6
+ def _submit_jobs(
7
7
  jobs_args: Iterable[dict],
8
8
  func: Callable[[List[dict]], Any],
9
9
  *,
@@ -15,6 +15,7 @@ def submit_jobs(
15
15
  block: bool,
16
16
  prompt: bool,
17
17
  local_run: bool,
18
+ job_name: Optional[str] = "resubmit",
18
19
  slurm_additional_parameters: Optional[Dict] = None,
19
20
  ):
20
21
  """Submit jobs described by `jobs_args` where each entry is a dict of kwargs for `func`.
@@ -48,18 +49,13 @@ def submit_jobs(
48
49
  print("submitting jobs")
49
50
  executor = submitit.AutoExecutor(folder=folder)
50
51
 
51
- # default slurm params (keep cluster-specific options out unless explicitly set)
52
- if slurm_additional_parameters is None:
53
- slurm_additional_parameters = {"gpus": num_gpus}
54
- else:
55
- slurm_additional_parameters = dict(slurm_additional_parameters)
56
- slurm_additional_parameters.setdefault("gpus", num_gpus)
57
-
58
52
  print("Slurm additional parameters:", slurm_additional_parameters)
59
53
 
60
54
  executor.update_parameters(
55
+ name=job_name,
61
56
  timeout_min=timeout_min,
62
57
  cpus_per_task=cpus_per_task,
58
+ gpus_per_node=num_gpus,
63
59
  mem_gb=mem_gb,
64
60
  slurm_additional_parameters=slurm_additional_parameters,
65
61
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: resubmit
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: Small wrapper around submitit to simplify cluster submissions
5
5
  Author: Amir Mehrpanah
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  import re
2
2
  import pandas as pd
3
- from src.resubmit.__bookkeeping import create_jobs_dataframe, ensure_unique_combinations
3
+ from resubmit.__bookkeeping import create_jobs_dataframe, ensure_unique_combinations
4
4
 
5
5
 
6
6
  def test_create_jobs_basic():
@@ -11,7 +11,7 @@ def test_create_jobs_basic():
11
11
 
12
12
 
13
13
  def test_create_jobs_callable():
14
- params = {"a": [1, 2], "b": lambda df: df["a"] * 10}
14
+ params = {"a": [1, 2], "b__callable": lambda df: df["a"] * 10}
15
15
  df = create_jobs_dataframe(params)
16
16
  assert list(df["b"]) == [10, 20]
17
17
 
@@ -0,0 +1,115 @@
1
+ import pytest
2
+ from resubmit import maybe_attach_debugger
3
+ from resubmit.__submit import _submit_jobs
4
+
5
+
6
+ def dummy_func(jobs):
7
+ # return a list of strings to show behavior
8
+ return [f"ok-{j['id']}" for j in jobs]
9
+
10
+
11
+ def test_submit_local_run():
12
+ jobs = [{"id": 1}, {"id": 2}]
13
+ res = _submit_jobs(
14
+ jobs,
15
+ dummy_func,
16
+ timeout_min=1,
17
+ local_run=True,
18
+ num_gpus=0,
19
+ cpus_per_task=1,
20
+ mem_gb=8,
21
+ folder="dummy/%j",
22
+ block=False,
23
+ prompt=False,
24
+ )
25
+ assert res == ["ok-1", "ok-2"]
26
+
27
+
28
+ def test_maybe_attach_debugger_noop():
29
+ # should not raise when port is None or 0
30
+ maybe_attach_debugger(None)
31
+ maybe_attach_debugger(0)
32
+
33
+
34
+ def test_slurm_parameters_optional(monkeypatch):
35
+ events = {}
36
+
37
+ class DummyExecutor:
38
+ def __init__(self, folder):
39
+ events["folder"] = folder
40
+
41
+ def update_parameters(self, **kwargs):
42
+ # capture the parameters passed to the executor
43
+ events["update"] = kwargs
44
+
45
+ def map_array(self, func, jobs_list):
46
+ return []
47
+
48
+ class DummyModule:
49
+ AutoExecutor = DummyExecutor
50
+
51
+ import sys
52
+
53
+ monkeypatch.setitem(sys.modules, "submitit", DummyModule)
54
+
55
+ jobs = [{"id": 1}]
56
+ # default: no constraint/reservation keys
57
+ _submit_jobs(
58
+ jobs,
59
+ dummy_func,
60
+ timeout_min=1,
61
+ local_run=False,
62
+ num_gpus=2,
63
+ prompt=False,
64
+ cpus_per_task=4,
65
+ mem_gb=16,
66
+ folder="logs/%j",
67
+ block=False,
68
+ )
69
+ slurm = events["update"]["slurm_additional_parameters"]
70
+ assert slurm["gpus"] == 2
71
+ assert "constraint" not in slurm
72
+ assert "reservation" not in slurm
73
+
74
+
75
+ def test_slurm_parameters_settable(monkeypatch):
76
+ events = {}
77
+
78
+ class DummyExecutor:
79
+ def __init__(self, folder):
80
+ events["folder"] = folder
81
+
82
+ def update_parameters(self, **kwargs):
83
+ events["update"] = kwargs
84
+
85
+ def map_array(self, func, jobs_list):
86
+ return []
87
+
88
+ class DummyModule:
89
+ AutoExecutor = DummyExecutor
90
+
91
+ import sys
92
+
93
+ monkeypatch.setitem(sys.modules, "submitit", DummyModule)
94
+
95
+ jobs = [{"id": 1}]
96
+ _submit_jobs(
97
+ jobs,
98
+ dummy_func,
99
+ timeout_min=1,
100
+ local_run=False,
101
+ prompt=False,
102
+ slurm_additional_parameters={
103
+ "constraint": "thin",
104
+ "reservation": "safe",
105
+ },
106
+ cpus_per_task=4,
107
+ mem_gb=16,
108
+ folder="logs/%j",
109
+ block=False,
110
+ num_gpus=1,
111
+ )
112
+ slurm = events["update"]["slurm_additional_parameters"]
113
+ assert slurm["constraint"] == "thin"
114
+ assert slurm["reservation"] == "safe"
115
+
@@ -1,117 +0,0 @@
1
- import pytest
2
- from resubmit import maybe_attach_debugger
3
- from resubmit.__submit import submit_jobs
4
-
5
-
6
- def dummy_func(jobs):
7
- # return a list of strings to show behavior
8
- return [f"ok-{j['id']}" for j in jobs]
9
-
10
-
11
- def test_submit_local_run():
12
- jobs = [{"id": 1}, {"id": 2}]
13
- res = submit_jobs(jobs, dummy_func, timeout_min=1, local_run=True)
14
- assert res == ["ok-1", "ok-2"]
15
-
16
-
17
- def test_maybe_attach_debugger_noop():
18
- # should not raise when port is None or 0
19
- maybe_attach_debugger(None)
20
- maybe_attach_debugger(0)
21
-
22
-
23
- def test_slurm_parameters_optional(monkeypatch):
24
- events = {}
25
-
26
- class DummyExecutor:
27
- def __init__(self, folder):
28
- events['folder'] = folder
29
-
30
- def update_parameters(self, **kwargs):
31
- # capture the parameters passed to the executor
32
- events['update'] = kwargs
33
-
34
- def map_array(self, func, jobs_list):
35
- return []
36
-
37
- class DummyModule:
38
- AutoExecutor = DummyExecutor
39
-
40
- import sys
41
- monkeypatch.setitem(sys.modules, 'submitit', DummyModule)
42
-
43
- jobs = [{"id": 1}]
44
- # default: no constraint/reservation keys
45
- submit_jobs(jobs, dummy_func, timeout_min=1, local_run=False, num_gpus=2, prompt=False)
46
- slurm = events['update']['slurm_additional_parameters']
47
- assert slurm['gpus'] == 2
48
- assert 'constraint' not in slurm
49
- assert 'reservation' not in slurm
50
-
51
-
52
- def test_slurm_parameters_settable(monkeypatch):
53
- events = {}
54
-
55
- class DummyExecutor:
56
- def __init__(self, folder):
57
- events['folder'] = folder
58
-
59
- def update_parameters(self, **kwargs):
60
- events['update'] = kwargs
61
-
62
- def map_array(self, func, jobs_list):
63
- return []
64
-
65
- class DummyModule:
66
- AutoExecutor = DummyExecutor
67
-
68
- import sys
69
- monkeypatch.setitem(sys.modules, 'submitit', DummyModule)
70
-
71
- jobs = [{"id": 1}]
72
- submit_jobs(
73
- jobs,
74
- dummy_func,
75
- timeout_min=1,
76
- local_run=False,
77
- constraint='thin',
78
- reservation='safe',
79
- prompt=False,
80
- )
81
- slurm = events['update']['slurm_additional_parameters']
82
- assert slurm['constraint'] == 'thin'
83
- assert slurm['reservation'] == 'safe'
84
-
85
-
86
- def test_slurm_parameters_arg_precedence(monkeypatch):
87
- events = {}
88
-
89
- class DummyExecutor:
90
- def __init__(self, folder):
91
- events['folder'] = folder
92
-
93
- def update_parameters(self, **kwargs):
94
- events['update'] = kwargs
95
-
96
- def map_array(self, func, jobs_list):
97
- return []
98
-
99
- class DummyModule:
100
- AutoExecutor = DummyExecutor
101
-
102
- import sys
103
- monkeypatch.setitem(sys.modules, 'submitit', DummyModule)
104
-
105
- jobs = [{"id": 1}]
106
- # slurm_additional_parameters has constraint='foo' but explicit arg should override
107
- submit_jobs(
108
- jobs,
109
- dummy_func,
110
- timeout_min=1,
111
- local_run=False,
112
- slurm_additional_parameters={'constraint': 'foo'},
113
- constraint='bar',
114
- prompt=False,
115
- )
116
- slurm = events['update']['slurm_additional_parameters']
117
- assert slurm['constraint'] == 'bar'
File without changes
File without changes
File without changes