podstack 1.3.17__tar.gz → 1.3.18__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.
- {podstack-1.3.17 → podstack-1.3.18}/PKG-INFO +1 -1
- {podstack-1.3.17 → podstack-1.3.18}/podstack/annotations.py +6 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/gpu_runner.py +10 -1
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/__init__.py +17 -3
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/client.py +30 -7
- {podstack-1.3.17 → podstack-1.3.18}/podstack.egg-info/PKG-INFO +1 -1
- {podstack-1.3.17 → podstack-1.3.18}/pyproject.toml +1 -1
- {podstack-1.3.17 → podstack-1.3.18}/LICENSE +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/README.md +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/__init__.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/client.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/exceptions.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/execution.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/models.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/notebook.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/autolog.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/exceptions.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/experiment.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/model.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack/registry/model_utils.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack.egg-info/SOURCES.txt +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack.egg-info/dependency_links.txt +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack.egg-info/requires.txt +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack.egg-info/top_level.txt +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/__init__.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/app.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/exceptions.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/image.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/runner.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/secret.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/utils.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/podstack_gpu/volume.py +0 -0
- {podstack-1.3.17 → podstack-1.3.18}/setup.cfg +0 -0
|
@@ -90,6 +90,7 @@ class GPUConfig:
|
|
|
90
90
|
conda: Union[str, list] = None,
|
|
91
91
|
requirements: str = None,
|
|
92
92
|
use_uv: bool = False,
|
|
93
|
+
env_vars: Optional[Dict[str, str]] = None,
|
|
93
94
|
remote: bool = None
|
|
94
95
|
):
|
|
95
96
|
"""
|
|
@@ -121,6 +122,7 @@ class GPUConfig:
|
|
|
121
122
|
self.conda = conda
|
|
122
123
|
self.requirements = requirements
|
|
123
124
|
self.use_uv = use_uv
|
|
125
|
+
self.env_vars = env_vars or {}
|
|
124
126
|
self.remote = remote if remote is not None else _remote_execution_enabled
|
|
125
127
|
|
|
126
128
|
# Store in global config
|
|
@@ -138,6 +140,7 @@ class GPUConfig:
|
|
|
138
140
|
"conda": conda,
|
|
139
141
|
"requirements": requirements,
|
|
140
142
|
"use_uv": use_uv,
|
|
143
|
+
"env_vars": env_vars or {},
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
def __call__(self, func: Callable) -> Callable:
|
|
@@ -249,6 +252,7 @@ if __podstack_result__ is not None:
|
|
|
249
252
|
conda=effective_conda,
|
|
250
253
|
requirements=self.requirements,
|
|
251
254
|
use_uv=self.use_uv,
|
|
255
|
+
env_vars=self.env_vars,
|
|
252
256
|
runner=runner_name,
|
|
253
257
|
wait=True,
|
|
254
258
|
stream=None # Auto-detect: True in Jupyter, False otherwise
|
|
@@ -340,6 +344,7 @@ def gpu(
|
|
|
340
344
|
conda: Union[str, list] = None,
|
|
341
345
|
requirements: str = None,
|
|
342
346
|
use_uv: bool = False,
|
|
347
|
+
env_vars: Optional[Dict[str, str]] = None,
|
|
343
348
|
remote: bool = None
|
|
344
349
|
) -> GPUConfig:
|
|
345
350
|
"""
|
|
@@ -421,6 +426,7 @@ def gpu(
|
|
|
421
426
|
conda=conda,
|
|
422
427
|
requirements=requirements,
|
|
423
428
|
use_uv=use_uv,
|
|
429
|
+
env_vars=env_vars,
|
|
424
430
|
remote=remote
|
|
425
431
|
)
|
|
426
432
|
|
|
@@ -361,6 +361,7 @@ class GPURunner:
|
|
|
361
361
|
conda: Union[str, list] = None,
|
|
362
362
|
requirements: str = None,
|
|
363
363
|
use_uv: bool = False,
|
|
364
|
+
env_vars: Dict[str, str] = None,
|
|
364
365
|
add_annotation: bool = True,
|
|
365
366
|
runner: str = None
|
|
366
367
|
) -> Dict[str, Any]:
|
|
@@ -395,6 +396,13 @@ class GPURunner:
|
|
|
395
396
|
annotation = self._build_annotation(gpu, count, fraction, timeout, env, pip, uv, conda, requirements, use_uv, runner)
|
|
396
397
|
code = f"{annotation}\n\n{code}"
|
|
397
398
|
|
|
399
|
+
# Inject environment variables
|
|
400
|
+
if env_vars:
|
|
401
|
+
env_lines = ["import os"]
|
|
402
|
+
for k, v in env_vars.items():
|
|
403
|
+
env_lines.append(f"os.environ[{repr(k)}] = {repr(str(v))}")
|
|
404
|
+
code = "\n".join(env_lines) + "\n\n" + code
|
|
405
|
+
|
|
398
406
|
# Build installation code for packages
|
|
399
407
|
install_parts = []
|
|
400
408
|
|
|
@@ -672,6 +680,7 @@ _stream_install(
|
|
|
672
680
|
conda: Union[str, list] = None,
|
|
673
681
|
requirements: str = None,
|
|
674
682
|
use_uv: bool = False,
|
|
683
|
+
env_vars: Dict[str, str] = None,
|
|
675
684
|
wait: bool = True,
|
|
676
685
|
poll_interval: float = 2.0,
|
|
677
686
|
max_retries: int = 3,
|
|
@@ -713,7 +722,7 @@ _stream_install(
|
|
|
713
722
|
ValueError: If parameters are invalid
|
|
714
723
|
"""
|
|
715
724
|
# Submit the code
|
|
716
|
-
submission = self.submit(code, gpu, count, fraction, timeout, env, pip, uv, conda, requirements, use_uv, runner=runner)
|
|
725
|
+
submission = self.submit(code, gpu, count, fraction, timeout, env, pip, uv, conda, requirements, use_uv, env_vars=env_vars, runner=runner)
|
|
717
726
|
execution_id = submission.get("execution_id")
|
|
718
727
|
|
|
719
728
|
if not execution_id:
|
|
@@ -558,9 +558,23 @@ def create_trial(sweep_id: str, run_id: str, params: dict) -> dict:
|
|
|
558
558
|
return _get_client().create_trial(sweep_id, run_id, params)
|
|
559
559
|
|
|
560
560
|
|
|
561
|
-
def complete_trial(
|
|
562
|
-
|
|
563
|
-
|
|
561
|
+
def complete_trial(
|
|
562
|
+
sweep_id: str,
|
|
563
|
+
trial_id: str,
|
|
564
|
+
value: float = None,
|
|
565
|
+
metrics: dict = None,
|
|
566
|
+
run_id: str = None,
|
|
567
|
+
) -> None:
|
|
568
|
+
"""Mark a trial as completed with its objective metric value.
|
|
569
|
+
|
|
570
|
+
Args:
|
|
571
|
+
sweep_id: Sweep ID.
|
|
572
|
+
trial_id: Trial ID (from suggest_trial_params).
|
|
573
|
+
value: Scalar objective value.
|
|
574
|
+
metrics: Dict of metric name → value; first entry used if value not set.
|
|
575
|
+
run_id: Optional run ID to link to this trial.
|
|
576
|
+
"""
|
|
577
|
+
_get_client().complete_trial(sweep_id, trial_id, value, metrics, run_id)
|
|
564
578
|
|
|
565
579
|
|
|
566
580
|
def list_trials(sweep_id: str) -> list:
|
|
@@ -1372,9 +1372,12 @@ class RegistryClient:
|
|
|
1372
1372
|
return data.get("sweeps", [])
|
|
1373
1373
|
|
|
1374
1374
|
def suggest_trial_params(self, sweep_id: str) -> Dict[str, Any]:
|
|
1375
|
-
"""Get suggested hyperparameter values for the next trial.
|
|
1375
|
+
"""Get suggested hyperparameter values for the next trial.
|
|
1376
|
+
|
|
1377
|
+
Returns a dict with ``id`` (trial ID) and ``params`` (hyperparameter map).
|
|
1378
|
+
"""
|
|
1376
1379
|
data = self._request("GET", f"/sweeps/{sweep_id}/suggest")
|
|
1377
|
-
return data.get("
|
|
1380
|
+
return data.get("trial", data)
|
|
1378
1381
|
|
|
1379
1382
|
def create_trial(
|
|
1380
1383
|
self,
|
|
@@ -1389,11 +1392,31 @@ class RegistryClient:
|
|
|
1389
1392
|
})
|
|
1390
1393
|
return data.get("trial", data)
|
|
1391
1394
|
|
|
1392
|
-
def complete_trial(
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1395
|
+
def complete_trial(
|
|
1396
|
+
self,
|
|
1397
|
+
sweep_id: str,
|
|
1398
|
+
trial_id: str,
|
|
1399
|
+
value: float = None,
|
|
1400
|
+
metrics: Dict[str, float] = None,
|
|
1401
|
+
run_id: str = None,
|
|
1402
|
+
) -> None:
|
|
1403
|
+
"""Mark a trial as completed with its objective metric value.
|
|
1404
|
+
|
|
1405
|
+
Args:
|
|
1406
|
+
sweep_id: Sweep ID.
|
|
1407
|
+
trial_id: Trial ID (from suggest_trial_params).
|
|
1408
|
+
value: Scalar objective value.
|
|
1409
|
+
metrics: Dict of metric name → value; first entry used if value not set.
|
|
1410
|
+
run_id: Optional run ID to link to this trial.
|
|
1411
|
+
"""
|
|
1412
|
+
body: Dict[str, Any] = {}
|
|
1413
|
+
if value is not None:
|
|
1414
|
+
body["value"] = value
|
|
1415
|
+
if metrics:
|
|
1416
|
+
body["metrics"] = metrics
|
|
1417
|
+
if run_id:
|
|
1418
|
+
body["run_id"] = run_id
|
|
1419
|
+
self._request("POST", f"/sweeps/{sweep_id}/trials/{trial_id}/complete", json=body)
|
|
1397
1420
|
|
|
1398
1421
|
def list_trials(self, sweep_id: str) -> List[Dict[str, Any]]:
|
|
1399
1422
|
"""List all trials for a sweep."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|