thds.mops 3.9.20250904205929__py3-none-any.whl → 3.9.20250908154102__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 thds.mops might be problematic. Click here for more details.
- thds/mops/k8s/_launch.py +7 -5
- thds/mops/k8s/batching.py +15 -8
- {thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/METADATA +1 -1
- {thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/RECORD +7 -7
- {thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/WHEEL +0 -0
- {thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/entry_points.txt +0 -0
- {thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/top_level.txt +0 -0
thds/mops/k8s/_launch.py
CHANGED
|
@@ -30,14 +30,14 @@ def sanitize_str(name: str) -> str:
|
|
|
30
30
|
|
|
31
31
|
def construct_job_name(user_prefix: str, job_num: str) -> str:
|
|
32
32
|
# we want some consistency here, but also some randomness in case the prefixes don't exist or aren't unique.
|
|
33
|
-
mops_name_part = "-".join([sanitize_str(job_num), str(
|
|
33
|
+
mops_name_part = "-".join([sanitize_str(job_num), str(uuid.uuid4())[:8]])
|
|
34
34
|
if len(mops_name_part) > 63:
|
|
35
|
-
# this should be
|
|
35
|
+
# this should be _unlikely_, because having a job num longer than even 20 digits would be an impossibly large
|
|
36
36
|
# number of jobs. but just in case, we'll truncate it to the last 63 characters.
|
|
37
|
-
mops_name_part = mops_name_part[-63:] #
|
|
37
|
+
mops_name_part = mops_name_part[-63:] # prefer the most random part, to avoid collisions
|
|
38
38
|
|
|
39
39
|
user_prefix = sanitize_str(user_prefix)
|
|
40
|
-
if user_prefix:
|
|
40
|
+
if user_prefix and len(mops_name_part) < 62:
|
|
41
41
|
name = f"{user_prefix[:63 - 1 - len(mops_name_part)]}-{mops_name_part}"
|
|
42
42
|
else:
|
|
43
43
|
name = mops_name_part
|
|
@@ -90,7 +90,9 @@ def launch(
|
|
|
90
90
|
raise ValueError("You cannot specify both full_name and name_prefix; use one or the other.")
|
|
91
91
|
|
|
92
92
|
if not full_name:
|
|
93
|
-
name = construct_job_name(
|
|
93
|
+
name = construct_job_name(
|
|
94
|
+
"-".join([name_prefix, str(os.getpid())]), counts.to_name(counts.inc(counts.LAUNCH_COUNT))
|
|
95
|
+
)
|
|
94
96
|
else:
|
|
95
97
|
name = full_name
|
|
96
98
|
|
thds/mops/k8s/batching.py
CHANGED
|
@@ -14,6 +14,7 @@ import atexit
|
|
|
14
14
|
import concurrent.futures
|
|
15
15
|
import itertools
|
|
16
16
|
import multiprocessing
|
|
17
|
+
import os
|
|
17
18
|
import threading
|
|
18
19
|
import typing as ty
|
|
19
20
|
|
|
@@ -56,7 +57,7 @@ class K8sJobBatchingShim(_AtExitBatcher[str]):
|
|
|
56
57
|
submit_func: ty.Callable[[ty.Collection[str]], ty.Any],
|
|
57
58
|
max_batch_size: int,
|
|
58
59
|
job_counter: counts.MpValue[int],
|
|
59
|
-
|
|
60
|
+
job_prefix: str = "",
|
|
60
61
|
) -> None:
|
|
61
62
|
"""submit_func in particular should be a closure around whatever setup you need to
|
|
62
63
|
do to call back into a function that is locally wrapped with a k8s shim that will
|
|
@@ -66,13 +67,13 @@ class K8sJobBatchingShim(_AtExitBatcher[str]):
|
|
|
66
67
|
self._max_batch_size = max_batch_size
|
|
67
68
|
self._job_counter = job_counter
|
|
68
69
|
self._job_name = ""
|
|
69
|
-
self.
|
|
70
|
+
self._job_prefix = job_prefix
|
|
70
71
|
self._submit_func = submit_func
|
|
71
72
|
|
|
72
73
|
def _get_new_name(self) -> str:
|
|
73
74
|
# counts.inc takes a multiprocess lock. do not forget this!
|
|
74
75
|
job_num = counts.inc(self._job_counter)
|
|
75
|
-
return _launch.construct_job_name(self.
|
|
76
|
+
return _launch.construct_job_name(self._job_prefix, counts.to_name(job_num))
|
|
76
77
|
|
|
77
78
|
def add_to_named_job(self, mops_invocation: ty.Sequence[str]) -> str:
|
|
78
79
|
"""Returns job name for the invocation."""
|
|
@@ -103,7 +104,7 @@ def init_batcher(
|
|
|
103
104
|
submit_func: ty.Callable[[ty.Collection[str]], ty.Any],
|
|
104
105
|
func_max_batch_size: int,
|
|
105
106
|
job_counter: counts.MpValue[int],
|
|
106
|
-
|
|
107
|
+
job_prefix: str = "",
|
|
107
108
|
) -> None:
|
|
108
109
|
# for use with multiprocessing pool initializer
|
|
109
110
|
global _BATCHER
|
|
@@ -111,7 +112,7 @@ def init_batcher(
|
|
|
111
112
|
logger.warning("Batcher is already initialized; reinitializing will reset the job name.")
|
|
112
113
|
return
|
|
113
114
|
|
|
114
|
-
_BATCHER = K8sJobBatchingShim(submit_func, func_max_batch_size, job_counter,
|
|
115
|
+
_BATCHER = K8sJobBatchingShim(submit_func, func_max_batch_size, job_counter, job_prefix)
|
|
115
116
|
|
|
116
117
|
|
|
117
118
|
def init_batcher_with_unpicklable_submit_func(
|
|
@@ -119,13 +120,13 @@ def init_batcher_with_unpicklable_submit_func(
|
|
|
119
120
|
submit_func_arg: T,
|
|
120
121
|
func_max_batch_size: int,
|
|
121
122
|
job_counter: counts.MpValue[int],
|
|
122
|
-
|
|
123
|
+
job_prefix: str = "",
|
|
123
124
|
) -> None:
|
|
124
125
|
"""Use this if you want to have an unpicklable submit function - because applying make_submit_func(submit_func_arg)
|
|
125
126
|
will happen inside the pool worker process after all the pickling/unpickling has happened.
|
|
126
127
|
"""
|
|
127
128
|
return init_batcher(
|
|
128
|
-
make_submit_func(submit_func_arg), func_max_batch_size, job_counter,
|
|
129
|
+
make_submit_func(submit_func_arg), func_max_batch_size, job_counter, job_prefix=job_prefix
|
|
129
130
|
)
|
|
130
131
|
|
|
131
132
|
|
|
@@ -170,7 +171,13 @@ def make_counting_process_pool_executor(
|
|
|
170
171
|
return concurrent.futures.ProcessPoolExecutor(
|
|
171
172
|
max_workers=max_workers or cpus.available_cpu_count(),
|
|
172
173
|
initializer=init_batcher_with_unpicklable_submit_func,
|
|
173
|
-
initargs=(
|
|
174
|
+
initargs=(
|
|
175
|
+
make_submit_func,
|
|
176
|
+
submit_func_arg,
|
|
177
|
+
max_batch_size,
|
|
178
|
+
launch_count,
|
|
179
|
+
"-".join([name_prefix, str(os.getpid())]),
|
|
180
|
+
),
|
|
174
181
|
mp_context=mp_context,
|
|
175
182
|
)
|
|
176
183
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thds.mops
|
|
3
|
-
Version: 3.9.
|
|
3
|
+
Version: 3.9.20250908154102
|
|
4
4
|
Summary: ML Ops tools for Trilliant Health
|
|
5
5
|
Author-email: Trilliant Health <info@trillianthealth.com>
|
|
6
6
|
Project-URL: Repository, https://github.com/TrilliantHealth/ds-monorepo
|
|
@@ -16,11 +16,11 @@ thds/mops/impure/__init__.py,sha256=VnrHPVgbOYUjkrVnnVicvNV39G6K6ENcWtCuV-BedW4,
|
|
|
16
16
|
thds/mops/impure/keyfunc.py,sha256=6VRa44qW95mH-cWkwPaU-aarXv6Nz0EwBOn4Aowy73s,525
|
|
17
17
|
thds/mops/impure/runner.py,sha256=UI1NZWMZ_5TQHfFKLnoiSm2zDR3zCunTKFmJoybkyCo,2840
|
|
18
18
|
thds/mops/k8s/__init__.py,sha256=zl4GVcCFRvPscyo6gvv5Lx0OKB7d3QjtVFjYurnxMuE,764
|
|
19
|
-
thds/mops/k8s/_launch.py,sha256=
|
|
19
|
+
thds/mops/k8s/_launch.py,sha256=hgPty47CdwryPHKMmEnoxSsSvcSpXhHYSVYnLC2QJb0,10956
|
|
20
20
|
thds/mops/k8s/_shared.py,sha256=MR-s6ijWUHZGjxK_fsOpHuRDB6kuofjo5xiIb7ul2VM,86
|
|
21
21
|
thds/mops/k8s/apply_yaml.py,sha256=hVW6dIVbNdzHdbGlc2VAPGkdByv_rH2oPybyIm7tKIM,820
|
|
22
22
|
thds/mops/k8s/auth.py,sha256=0zs4TQgkD6VPrhDD43xt7JGwP6uWf3ctySGLcPKN7iw,1691
|
|
23
|
-
thds/mops/k8s/batching.py,sha256=
|
|
23
|
+
thds/mops/k8s/batching.py,sha256=Djt17ffxWyTq4Q7XcAKQdCe9JIIfPahHwm0wqgFqevI,8368
|
|
24
24
|
thds/mops/k8s/config.py,sha256=_znocX5BW8kfG_Cbq6f3apx5FqSihD7Tmic-SBkVjMQ,2992
|
|
25
25
|
thds/mops/k8s/container_registry.py,sha256=qOiGCE4t_tLYgJDGrhKV9KNv48lF_AlwCDHyFgucd2s,539
|
|
26
26
|
thds/mops/k8s/counts.py,sha256=D-OVHY_dhsgJ2YHApy2qvrcSKzE5mlweDPredFU6tOU,572
|
|
@@ -109,8 +109,8 @@ thds/mops/pure/tools/summarize/cli.py,sha256=7kDtn24ok8oBO3jFjlMmOK3jnZYpMoE_5Y8
|
|
|
109
109
|
thds/mops/pure/tools/summarize/run_summary.py,sha256=w45qiQr7elrHDiK9Hgs85gtU3gwLuXa447ih1Y23BBY,5776
|
|
110
110
|
thds/mops/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
111
|
thds/mops/testing/deferred_imports.py,sha256=f0ezCgQAtzTqW1yAOb0OWgsB9ZrlztLB894LtpWDaVw,3780
|
|
112
|
-
thds_mops-3.9.
|
|
113
|
-
thds_mops-3.9.
|
|
114
|
-
thds_mops-3.9.
|
|
115
|
-
thds_mops-3.9.
|
|
116
|
-
thds_mops-3.9.
|
|
112
|
+
thds_mops-3.9.20250908154102.dist-info/METADATA,sha256=hvJu7tdH_mELqF73dc_jUd0RLtCTAfdXg54lYIAhH6Q,2225
|
|
113
|
+
thds_mops-3.9.20250908154102.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
114
|
+
thds_mops-3.9.20250908154102.dist-info/entry_points.txt,sha256=qKvCAaB80syXfxVR3xx6x9J0YJdaQWkIbVSw-NwFgMw,322
|
|
115
|
+
thds_mops-3.9.20250908154102.dist-info/top_level.txt,sha256=LTZaE5SkWJwv9bwOlMbIhiS-JWQEEIcjVYnJrt-CriY,5
|
|
116
|
+
thds_mops-3.9.20250908154102.dist-info/RECORD,,
|
|
File without changes
|
{thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{thds_mops-3.9.20250904205929.dist-info → thds_mops-3.9.20250908154102.dist-info}/top_level.txt
RENAMED
|
File without changes
|