dask-setup 2.0.0__tar.gz → 2.2.0__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.
Files changed (62) hide show
  1. {dask_setup-2.0.0/src/dask_setup.egg-info → dask_setup-2.2.0}/PKG-INFO +31 -7
  2. dask_setup-2.0.0/PKG-INFO → dask_setup-2.2.0/README.md +26 -26
  3. {dask_setup-2.0.0 → dask_setup-2.2.0}/pyproject.toml +17 -2
  4. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/__init__.py +3 -1
  5. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/benchmark.py +236 -73
  6. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/cli.py +9 -4
  7. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/client.py +420 -172
  8. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/cluster.py +92 -19
  9. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/config.py +35 -4
  10. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/config_manager.py +54 -26
  11. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/dashboard.py +32 -1
  12. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/error_handling.py +18 -4
  13. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/io_patterns.py +41 -40
  14. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/legacy.py +3 -1
  15. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/logging.py +22 -11
  16. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/multinode.py +350 -33
  17. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/parquet.py +3 -4
  18. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/rechunk.py +126 -14
  19. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/reporting.py +31 -7
  20. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/resources.py +64 -5
  21. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/tempdir.py +31 -2
  22. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/topology.py +2 -2
  23. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/tune.py +84 -29
  24. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/workload.py +4 -4
  25. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/xarray.py +126 -50
  26. dask_setup-2.0.0/README.md → dask_setup-2.2.0/src/dask_setup.egg-info/PKG-INFO +50 -5
  27. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup.egg-info/SOURCES.txt +4 -0
  28. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup.egg-info/requires.txt +5 -1
  29. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_benchmark.py +210 -5
  30. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_cli.py +14 -3
  31. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_client.py +465 -39
  32. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_cluster.py +102 -0
  33. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_config_manager.py +151 -6
  34. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_dashboard.py +47 -0
  35. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_error_handling.py +61 -0
  36. dask_setup-2.2.0/tests/test_logging.py +105 -0
  37. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_multinode.py +642 -8
  38. dask_setup-2.2.0/tests/test_rechunk.py +70 -0
  39. dask_setup-2.2.0/tests/test_reporting.py +103 -0
  40. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_resources.py +184 -11
  41. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_setup_dask_client.py +74 -59
  42. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_tempdir.py +62 -0
  43. dask_setup-2.2.0/tests/test_tune.py +167 -0
  44. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_xarray_chunks.py +269 -8
  45. {dask_setup-2.0.0 → dask_setup-2.2.0}/LICENSE +0 -0
  46. {dask_setup-2.0.0 → dask_setup-2.2.0}/setup.cfg +0 -0
  47. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/callbacks.py +0 -0
  48. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/environment.py +0 -0
  49. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/exceptions.py +0 -0
  50. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/py.typed +0 -0
  51. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/schema/__init__.py +0 -0
  52. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/schema/profile_schema.json +0 -0
  53. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup/types.py +0 -0
  54. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup.egg-info/dependency_links.txt +0 -0
  55. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup.egg-info/entry_points.txt +0 -0
  56. {dask_setup-2.0.0 → dask_setup-2.2.0}/src/dask_setup.egg-info/top_level.txt +0 -0
  57. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_compression.py +0 -0
  58. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_config.py +0 -0
  59. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_exceptions.py +0 -0
  60. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_io_patterns.py +0 -0
  61. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_topology.py +0 -0
  62. {dask_setup-2.0.0 → dask_setup-2.2.0}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dask_setup
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: HPC-tuned Dask helpers for single-node runs on NCI Gadi.
5
5
  Author: Sam Green
6
6
  Project-URL: Homepage, https://github.com/21centuryweather/dask_setup
@@ -11,12 +11,15 @@ Requires-Dist: dask>=2024.1.0
11
11
  Requires-Dist: distributed>=2024.1.0
12
12
  Requires-Dist: psutil>=5.9
13
13
  Requires-Dist: pyyaml>=6.0
14
+ Provides-Extra: multinode
15
+ Requires-Dist: dask-jobqueue>=0.8; extra == "multinode"
14
16
  Provides-Extra: dev
15
- Requires-Dist: ruff~=0.4; extra == "dev"
17
+ Requires-Dist: ruff==0.16.4; extra == "dev"
16
18
  Requires-Dist: pytest~=8.2; extra == "dev"
17
19
  Requires-Dist: pytest-cov~=5.0; extra == "dev"
18
20
  Requires-Dist: xarray; extra == "dev"
19
21
  Requires-Dist: numpy; extra == "dev"
22
+ Requires-Dist: dask-jobqueue>=0.8; extra == "dev"
20
23
  Dynamic: license-file
21
24
 
22
25
  # dask_setup
@@ -35,9 +38,9 @@ HPC-tuned Dask helpers for **NCI Gadi** and other PBS/SLURM systems. Wraps `dask
35
38
  from dask_setup import setup_dask_client
36
39
 
37
40
  # Pick a workload type and go
38
- client, cluster, dask_tmp = setup_dask_client("cpu") # heavy compute
39
- client, cluster, dask_tmp = setup_dask_client("io") # heavy file I/O
40
- client, cluster, dask_tmp = setup_dask_client("mixed") # both
41
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="cpu") # heavy compute
42
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="io") # heavy file I/O
43
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="mixed") # both
41
44
  ```
42
45
 
43
46
  `dask_tmp` is the path to the spill/temp directory (on `$PBS_JOBFS` if available). Pass it to Rechunker, Zarr, or anywhere else you want fast local I/O.
@@ -95,14 +98,27 @@ client, cluster, shared_tmp = setup_dask_client(
95
98
  |-----------|---------|-------------|
96
99
  | `workload_type` | `"io"` | Worker topology: `"cpu"`, `"io"`, `"mixed"`, `"gpu"`, `"auto"` |
97
100
  | `max_workers` | all cores | Hard cap on worker count |
98
- | `reserve_mem_gb` | auto (20% RAM) | Memory held back for OS/cache (GiB) |
101
+ | `reserve_mem_gb` | auto | Memory held back for OS/cache (GiB): 20% of RAM, clamped to [4, 50] |
99
102
  | `max_mem_gb` | total RAM | Upper bound on Dask's total memory use |
100
103
  | `dashboard` | `True` | Start dashboard and print SSH tunnel hint |
101
104
  | `profile` | `None` | Named config profile |
102
- | `config` | `None` | Pre-built `DaskSetupConfig` object — mutually exclusive with `profile` |
105
+ | `config` | `None` | Pre-built `DaskSetupConfig` object — same layer as `profile`; if both are given, `profile` wins |
103
106
  | `mode` | `"auto"` | `"local"`, `"pbs"`, `"slurm"`, or `"auto"` (v2.0) |
104
107
  | `multi_node_config` | `None` | `MultiNodeConfig` for PBS/SLURM multi-node jobs (v2.0) |
105
108
 
109
+ Settings are layered, lowest to highest:
110
+
111
+ ```
112
+ library defaults < config= or profile= < explicit keyword arguments
113
+ ```
114
+
115
+ A parameter you leave unset inherits from the layer below. Passing a value
116
+ always overrides, even when that value happens to equal the default — so
117
+ `reserve_mem_gb=50.0` overrides a profile that says 40.0.
118
+
119
+ `config=` and `profile=` share a layer rather than stacking: pass one or the
120
+ other, and use explicit keyword arguments for the differences.
121
+
106
122
  ---
107
123
 
108
124
  ## Common Patterns
@@ -177,6 +193,14 @@ Tunnel from your laptop:
177
193
  Then open: http://localhost:8787
178
194
  ```
179
195
 
196
+ The login host is inferred from the compute node's DNS domain, so it is correct
197
+ at other sites too. Override it with `$DASK_SETUP_LOGIN_HOST` if the guess is
198
+ wrong:
199
+
200
+ ```bash
201
+ export DASK_SETUP_LOGIN_HOST=login.mycluster.edu
202
+ ```
203
+
180
204
  ---
181
205
 
182
206
  ## CLI
@@ -1,24 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: dask_setup
3
- Version: 2.0.0
4
- Summary: HPC-tuned Dask helpers for single-node runs on NCI Gadi.
5
- Author: Sam Green
6
- Project-URL: Homepage, https://github.com/21centuryweather/dask_setup
7
- Requires-Python: >=3.11
8
- Description-Content-Type: text/markdown
9
- License-File: LICENSE
10
- Requires-Dist: dask>=2024.1.0
11
- Requires-Dist: distributed>=2024.1.0
12
- Requires-Dist: psutil>=5.9
13
- Requires-Dist: pyyaml>=6.0
14
- Provides-Extra: dev
15
- Requires-Dist: ruff~=0.4; extra == "dev"
16
- Requires-Dist: pytest~=8.2; extra == "dev"
17
- Requires-Dist: pytest-cov~=5.0; extra == "dev"
18
- Requires-Dist: xarray; extra == "dev"
19
- Requires-Dist: numpy; extra == "dev"
20
- Dynamic: license-file
21
-
22
1
  # dask_setup
23
2
 
24
3
  [![CI](https://github.com/21centuryweather/dask_setup/workflows/CI/badge.svg)](https://github.com/21centuryweather/dask_setup/actions)
@@ -35,9 +14,9 @@ HPC-tuned Dask helpers for **NCI Gadi** and other PBS/SLURM systems. Wraps `dask
35
14
  from dask_setup import setup_dask_client
36
15
 
37
16
  # Pick a workload type and go
38
- client, cluster, dask_tmp = setup_dask_client("cpu") # heavy compute
39
- client, cluster, dask_tmp = setup_dask_client("io") # heavy file I/O
40
- client, cluster, dask_tmp = setup_dask_client("mixed") # both
17
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="cpu") # heavy compute
18
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="io") # heavy file I/O
19
+ client, cluster, dask_tmp = setup_dask_client(mode="interactive", workload_type="mixed") # both
41
20
  ```
42
21
 
43
22
  `dask_tmp` is the path to the spill/temp directory (on `$PBS_JOBFS` if available). Pass it to Rechunker, Zarr, or anywhere else you want fast local I/O.
@@ -95,14 +74,27 @@ client, cluster, shared_tmp = setup_dask_client(
95
74
  |-----------|---------|-------------|
96
75
  | `workload_type` | `"io"` | Worker topology: `"cpu"`, `"io"`, `"mixed"`, `"gpu"`, `"auto"` |
97
76
  | `max_workers` | all cores | Hard cap on worker count |
98
- | `reserve_mem_gb` | auto (20% RAM) | Memory held back for OS/cache (GiB) |
77
+ | `reserve_mem_gb` | auto | Memory held back for OS/cache (GiB): 20% of RAM, clamped to [4, 50] |
99
78
  | `max_mem_gb` | total RAM | Upper bound on Dask's total memory use |
100
79
  | `dashboard` | `True` | Start dashboard and print SSH tunnel hint |
101
80
  | `profile` | `None` | Named config profile |
102
- | `config` | `None` | Pre-built `DaskSetupConfig` object — mutually exclusive with `profile` |
81
+ | `config` | `None` | Pre-built `DaskSetupConfig` object — same layer as `profile`; if both are given, `profile` wins |
103
82
  | `mode` | `"auto"` | `"local"`, `"pbs"`, `"slurm"`, or `"auto"` (v2.0) |
104
83
  | `multi_node_config` | `None` | `MultiNodeConfig` for PBS/SLURM multi-node jobs (v2.0) |
105
84
 
85
+ Settings are layered, lowest to highest:
86
+
87
+ ```
88
+ library defaults < config= or profile= < explicit keyword arguments
89
+ ```
90
+
91
+ A parameter you leave unset inherits from the layer below. Passing a value
92
+ always overrides, even when that value happens to equal the default — so
93
+ `reserve_mem_gb=50.0` overrides a profile that says 40.0.
94
+
95
+ `config=` and `profile=` share a layer rather than stacking: pass one or the
96
+ other, and use explicit keyword arguments for the differences.
97
+
106
98
  ---
107
99
 
108
100
  ## Common Patterns
@@ -177,6 +169,14 @@ Tunnel from your laptop:
177
169
  Then open: http://localhost:8787
178
170
  ```
179
171
 
172
+ The login host is inferred from the compute node's DNS domain, so it is correct
173
+ at other sites too. Override it with `$DASK_SETUP_LOGIN_HOST` if the guess is
174
+ wrong:
175
+
176
+ ```bash
177
+ export DASK_SETUP_LOGIN_HOST=login.mycluster.edu
178
+ ```
179
+
180
180
  ---
181
181
 
182
182
  ## CLI
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dask_setup"
7
- version = "2.0.0"
7
+ version = "2.2.0"
8
8
  description = "HPC-tuned Dask helpers for single-node runs on NCI Gadi."
9
9
  authors = [{name="Sam Green"}]
10
10
  readme = "README.md"
@@ -23,13 +23,28 @@ Homepage = "https://github.com/21centuryweather/dask_setup"
23
23
  dask-setup = "dask_setup.cli:main"
24
24
 
25
25
  [project.optional-dependencies]
26
+ # Multi-node PBS/SLURM cluster support. Optional: the single-node path never
27
+ # imports it, and setup_pbs_cluster()/setup_slurm_cluster() raise a helpful
28
+ # ImportError if it is missing.
29
+ multinode = [
30
+ "dask-jobqueue>=0.8",
31
+ ]
32
+
26
33
  dev = [
27
- "ruff ~= 0.4",
34
+ # Pinned exactly, not a range. `ruff ~= 0.4` means >=0.4,<1.0, so CI picked
35
+ # up whatever ruff had released that morning -- and ruff's formatter changes
36
+ # between minor versions. That turns `ruff format --check` into a job that
37
+ # can fail on a commit that touched nothing. Bump this deliberately.
38
+ "ruff == 0.16.4",
28
39
  "pytest ~= 8.2",
29
40
  "pytest-cov ~= 5.0",
30
41
  # Xarray integration testing
31
42
  "xarray",
32
43
  "numpy",
44
+ # Multi-node tests exercise a real PBSJob. Without this, CI silently skipped
45
+ # the multi-node path -- including the regression test for the 4x worker
46
+ # under-provisioning fixed in 2.2.0.
47
+ "dask-jobqueue>=0.8",
33
48
  ]
34
49
 
35
50
  [tool.setuptools.package-data]
@@ -22,6 +22,7 @@ from .multinode import (
22
22
  detect_cluster_mode,
23
23
  generate_pbs_script,
24
24
  generate_slurm_script,
25
+ setup_interactive_cluster,
25
26
  setup_pbs_cluster,
26
27
  setup_slurm_cluster,
27
28
  )
@@ -280,7 +281,7 @@ except ImportError:
280
281
  )
281
282
 
282
283
 
283
- __version__ = "2.0.0"
284
+ __version__ = "2.2.0"
284
285
 
285
286
  __all__ = [
286
287
  # Core API — always available
@@ -326,6 +327,7 @@ __all__ = [
326
327
  "MultiNodeConfig",
327
328
  "SharedTempDir",
328
329
  "detect_cluster_mode",
330
+ "setup_interactive_cluster",
329
331
  "setup_pbs_cluster",
330
332
  "setup_slurm_cluster",
331
333
  "generate_pbs_script",