Skip to content

Commit f48de7e

Browse files
committed
Release 1.0.0
1 parent 742565c commit f48de7e

3 files changed

Lines changed: 81 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Changelog
2+
3+
## v1.0.0 - 2026-04-17
4+
5+
Initial public release.
6+
7+
### Core
8+
9+
- **LPT scheduling** - tasks sorted by weight descending; heavy experiments start first, short ones fill gaps at the end.
10+
- **Load-aware dispatch** - each new task goes to the GPU with the smallest active workload (sum of `Task.weight`).
11+
- **Per-GPU worker pools** - configurable `workers_per_gpu` (default: 1) to overlap CPU-bound preprocessing with GPU kernels.
12+
- **Subprocess isolation** - every task runs in its own process with `CUDA_VISIBLE_DEVICES` set; no shared CUDA contexts.
13+
- **`Task` dataclass** - `(weight, name, seed, cmd)` with comparison by weight for LPT, `.label` property for logging.
14+
- **`build_task_matrix()`** - generates a deduplicated, LPT-sorted task list from a `names * seeds` grid with `cmd_factory` callback; optional `available_names` whitelist.
15+
- **`run_schedule()`** - main entry point; returns `(gpu_id, label, return_code, elapsed_sec)` per task.
16+
17+
### Resume & progress
18+
19+
- **`--resume`** - skip tasks whose `seed_*.json` already exists in the results directory.
20+
- **`scan_completed()`** - walks `results_dir/<timestamp>/<name>/seed_N.json`; supports custom prefix/suffix and optional JSON validation of corrupt/incomplete files.
21+
- **Progress tracking** - `[done/total pct%]` tag injected into every log line via `ProgressFormatter`; ETA based on completed weight; failure count shown as `N!`.
22+
23+
### Robustness
24+
25+
- **`--task-timeout`** - per-task timeout in seconds; timed-out tasks report `rc=-1`.
26+
- **`--max-failures`** - stop scheduling new tasks after N failures, drain in-flight work, report summary.
27+
- **Stall detection** (`stall_warning`) - warns when a GPU has no activity for a configurable duration; logs in-flight task labels.
28+
- **Dead worker recovery** - detects crashed worker processes; marks their in-flight tasks as failed (`rc=-9`) and continues.
29+
30+
### CLI (`python -m lab_orchestrator`)
31+
32+
- Config loading from YAML (`.yaml`/`.yml`, requires `pyyaml`), JSON, or Python (`.py` with `CONFIG` dict).
33+
- Two command formats: `cmd_template` (string with `{name}`/`{seed}` placeholders) and `cmd_parts` (structured `base` + `per_name` + `common`).
34+
- `--gpus 0,1,2,3` - explicit GPU selection; auto-detect via `torch.cuda.device_count()` when omitted.
35+
- `--dry-run` - simulate scheduling with heap-based timeline; print per-GPU task assignments and estimated wall-clock.
36+
- `--workers-per-gpu N` - concurrent workers sharing each GPU.
37+
- `--results-dir` - custom results directory for resume scanning.
38+
39+
### tmux mode
40+
41+
- `--tmux` / `--tmux-session` / `--venv` / `--cwd` - generate a bash script with one tmux window per task instead of running programmatically.
42+
- `generate_tmux_script()` - programmatic API with LPT-based GPU assignment, virtualenv activation, custom `renderer` callback, and `extra_context` passthrough.
43+
44+
### GPU utilities
45+
46+
- `detect_gpus()` - auto-detect CUDA devices via PyTorch; warns about fork-mode CUDA initialization.
47+
- `parse_gpu_ids()` - parse `"0,1,2"` strings or fall back to auto-detect.
48+
49+
### Seed management
50+
51+
- `set_seed()` - fix random state across stdlib `random`, NumPy, PyTorch, TensorFlow, and JAX; auto-detects installed frameworks.
52+
- `deterministic=True` - enable `torch.use_deterministic_algorithms`, set `CUBLAS_WORKSPACE_CONFIG` and `TF_DETERMINISTIC_OPS`.
53+
- `frameworks=` filter and `warn_missing=` flag for selective seeding.
54+
55+
### Logging
56+
57+
- Per-task log files: `logs/<run_timestamp>/gpu<N>_<name>_seed<S>.log` capturing stdout+stderr.
58+
- Summary at end: total GPU-hours, wall-clock time, list of failed tasks with return codes.
59+
- `fmt_duration()` - human-readable duration formatting (`45s`, `2m`, `1h01m`).
60+
61+
### Examples
62+
63+
- `examples/sklearn_digits/` - minimal working example (no GPU needed): 3 models * 5 seeds with SVM, Random Forest, KNN on digits dataset.
64+
- `examples/sweep/` - GPU sweep template with `train.py` + `sweep.py` + `experiments.yaml`.
65+
- `examples/experiment_template.py` - self-contained launcher + training in one file with checkpointing.
66+
- `examples/tmux_example.py` - tmux script generation from code.
67+
68+
### Packaging
69+
70+
- Zero hard dependencies - stdlib `multiprocessing` + `subprocess` only.
71+
- Optional extras: `gpu` (torch >= 2.0), `yaml` (pyyaml >= 6.0), `dev` (ruff, mypy, pytest, flake8).
72+
- `lab-orchestrator` CLI entry point via `pyproject.toml`.
73+
- Python >= 3.10 required.
74+
- MIT license.
75+
- Full type annotations; passes `mypy --disallow-untyped-defs`.
76+
- Test suite: 30+ tests covering task building, GPU parsing, tmux generation, seed reproducibility, resume scanning, progress formatting, dry-run, config loading, and integration.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# lab-orchestrator
1+
# gpu-experiment-scheduler
22

3-
Lightweight single-node GPU experiment scheduler. Zero hard dependencies
4-
(stdlib only), copy-paste ready.
3+
Lightweight single-node multi-GPU experiment scheduler for Python ML research.
4+
Zero dependencies (stdlib only), copy-paste ready.
55

66
Schedules a `name * seed` task matrix across multiple GPUs on one machine
77
using **LPT ordering** (heavy tasks first) and **load-aware dispatch**

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ build-backend = "hatchling.build"
55
[project]
66
name = "lab-orchestrator"
77
version = "1.0.0"
8-
description = "Lightweight single-node GPU experiment scheduler with LPT ordering and load-aware dispatch"
8+
description = "Lightweight single-node multi-GPU experiment scheduler for ML research. LPT ordering, load-aware dispatch, resume, zero dependencies."
99
readme = "README.md"
1010
license = "MIT"
1111
requires-python = ">=3.10"
12-
keywords = ["gpu", "scheduler", "experiment", "research", "deep-learning"]
12+
keywords = ["gpu", "scheduler", "experiment", "research", "deep-learning", "multi-gpu", "machine-learning", "task-scheduler", "mlops", "pytorch"]
1313
classifiers = [
1414
"Development Status :: 5 - Production/Stable",
1515
"Intended Audience :: Science/Research",

0 commit comments

Comments
 (0)