pathwaysutils 0.1.13__tar.gz → 0.1.14__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 (81) hide show
  1. pathwaysutils-0.1.14/PKG-INFO +90 -0
  2. pathwaysutils-0.1.14/README.md +50 -0
  3. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/__init__.py +1 -1
  4. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/_initialize.py +3 -1
  5. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/elastic/elastic.py +4 -0
  6. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/elastic/manager.py +11 -16
  7. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/concatenate_by_mesh_axis.py +25 -1
  8. pathwaysutils-0.1.14/pathwaysutils/experimental/gke/README.md +142 -0
  9. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/gke/jobset.py +394 -117
  10. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/profiling.py +11 -10
  11. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/reshard.py +1 -1
  12. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/README.md +2 -2
  13. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/deploy_pathways_service.py +8 -2
  14. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/dockerfiles/sample_sidecar.dockerfile +2 -2
  15. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/gke_utils.py +236 -32
  16. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/isc_pathways.py +17 -4
  17. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/split_by_mesh_axis.py +2 -2
  18. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/persistence/helper.py +7 -2
  19. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/profiling.py +20 -7
  20. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/proxy_backend.py +13 -1
  21. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/reshard.py +3 -3
  22. pathwaysutils-0.1.14/pathwaysutils/test/elastic_simulated_fault_integration_test.py +128 -0
  23. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/gke/jobset_test.py +611 -61
  24. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/gke/testdata/model_lite_tpuv5e_4x8.yaml +4 -4
  25. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/deploy_pathways_service_test.py +36 -0
  26. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/gke_utils_test.py +486 -69
  27. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/isc_pathways_test.py +188 -34
  28. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/initialize_test.py +4 -2
  29. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/mock_fault_injection.py +51 -8
  30. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/mock_fault_injection_test.py +47 -0
  31. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/persistence_test.py +20 -0
  32. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/profiling_test.py +59 -3
  33. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/proxy_backend_test.py +12 -0
  34. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/reshard_test.py +13 -0
  35. pathwaysutils-0.1.14/pathwaysutils/test/tpu_utils_test.py +44 -0
  36. pathwaysutils-0.1.14/pathwaysutils/tpu_utils.py +32 -0
  37. pathwaysutils-0.1.13/PKG-INFO +0 -61
  38. pathwaysutils-0.1.13/README.md +0 -21
  39. pathwaysutils-0.1.13/pathwaysutils/extras/elastic/model_comparison.html +0 -2052
  40. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/__init__.py +0 -48
  41. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/compile.py +0 -142
  42. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/config.py +0 -58
  43. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/data.py +0 -63
  44. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/model.py +0 -101
  45. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model.py +0 -78
  46. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/simple_model_test.py +0 -356
  47. pathwaysutils-0.1.13/pathwaysutils/extras/simple_model/workload.py +0 -219
  48. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/LICENSE +0 -0
  49. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/collect_profile.py +0 -0
  50. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/debug/__init__.py +0 -0
  51. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/debug/timing.py +0 -0
  52. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/debug/watchdog.py +0 -0
  53. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/elastic/__init__.py +0 -0
  54. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/__init__.py +0 -0
  55. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/gke/__init__.py +0 -0
  56. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/__init__.py +0 -0
  57. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/metrics_collector.py +0 -0
  58. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/run_connect_example.py +0 -0
  59. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/run_workload.py +0 -0
  60. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/start_vscode_on_cpu_np.py +0 -0
  61. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/tpu_specs.py +0 -0
  62. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/validators.py +0 -0
  63. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/yamls/code-server.yaml +0 -0
  64. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/experimental/shared_pathways_service/yamls/pw-proxy.yaml +0 -0
  65. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/jax/__init__.py +0 -0
  66. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/lru_cache.py +0 -0
  67. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/persistence/__init__.py +0 -0
  68. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/plugin_executable.py +0 -0
  69. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/__init__.py +0 -0
  70. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/debug/__init__.py +0 -0
  71. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/debug/timing_test.py +0 -0
  72. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/debug/watchdog_test.py +0 -0
  73. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/reshard_test.py +0 -0
  74. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/metrics_collector_test.py +0 -0
  75. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/run_workload_test.py +0 -0
  76. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/start_vscode_on_cpu_np_test.py +0 -0
  77. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/tpu_specs_test.py +0 -0
  78. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/experimental/shared_pathways_service/validators_test.py +0 -0
  79. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/lru_cache_test.py +0 -0
  80. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pathwaysutils/test/plugin_executable_test.py +0 -0
  81. {pathwaysutils-0.1.13 → pathwaysutils-0.1.14}/pyproject.toml +0 -0
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.4
2
+ Name: pathwaysutils
3
+ Version: 0.1.14
4
+ Summary: Package of Pathways-on-Cloud utilities.
5
+ Keywords:
6
+ Author-email: Pathways-on-Cloud Utilities Developers <pathwaysutils-dev@google.com>
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ License-File: LICENSE
11
+ Requires-Dist: absl-py
12
+ Requires-Dist: fastapi
13
+ Requires-Dist: jax>=0.10.0
14
+ Requires-Dist: orbax-checkpoint>=0.12.3
15
+ Requires-Dist: uvicorn
16
+ Requires-Dist: requests
17
+ Requires-Dist: packaging
18
+ Requires-Dist: pylint>=2.6.0 ; extra == "dev"
19
+ Requires-Dist: pyink ; extra == "dev"
20
+ Requires-Dist: kubernetes ; extra == "gke"
21
+ Requires-Dist: pyyaml ; extra == "gke"
22
+ Requires-Dist: portpicker ; extra == "sps"
23
+ Requires-Dist: google-cloud-monitoring ; extra == "sps"
24
+ Requires-Dist: portpicker ; extra == "sps-without-monitoring"
25
+ Requires-Dist: google-cloud-monitoring ; extra == "test"
26
+ Requires-Dist: httpx ; extra == "test"
27
+ Requires-Dist: kubernetes ; extra == "test"
28
+ Requires-Dist: portpicker ; extra == "test"
29
+ Requires-Dist: pyyaml ; extra == "test"
30
+ Requires-Dist: pytest ; extra == "test"
31
+ Project-URL: changelog, https://github.com/AI-Hypercomputer/pathways-utils/blob/main/CHANGELOG.md
32
+ Project-URL: homepage, https://github.com/AI-Hypercomputer/pathways-utils
33
+ Project-URL: repository, https://github.com/AI-Hypercomputer/pathways-utils
34
+ Provides-Extra: dev
35
+ Provides-Extra: gke
36
+ Provides-Extra: sps
37
+ Provides-Extra: sps-without-monitoring
38
+ Provides-Extra: test
39
+
40
+ # APIs to get started with using Pathways on Cloud
41
+
42
+ Pathways is a compute orchestration runtime for single-controller ML workloads
43
+ across multiple Cloud TPU slices. A single Python controller orchestrates
44
+ computation across hundreds or thousands of TPU chips, unlocking slice-level
45
+ training resiliency, fast cross-slice data movement, and interactive
46
+ multi-slice development.
47
+
48
+ This package bundles the Python client integrations, resharding and elasticity
49
+ helpers, and GKE deployment builders for running JAX workloads on Pathways on
50
+ Cloud.
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ pip install pathwaysutils
56
+ # Optional GKE JobSet generator and kubectl/Kubernetes client dependencies:
57
+ pip install 'pathwaysutils[gke]'
58
+ # Optional experimental Shared Pathways Service (SPS) dependencies:
59
+ pip install 'pathwaysutils[sps]'
60
+ ```
61
+
62
+ ## Core Modules
63
+
64
+ - `pathwaysutils.initialize()` registers the Pathways IFRT proxy backend,
65
+ configures the compilation cache and XProf trace hooks, and registers Orbax
66
+ checkpoint handlers.
67
+ - `pathwaysutils.reshard.reshard` reshards arrays and PyTrees across device
68
+ meshes directly on Pathways workers via the IFRT `RemapArray` API without
69
+ routing tensors through controller memory.
70
+ - `pathwaysutils.elastic.manager.Manager` monitors slice health in the
71
+ background and provides `@elastic_retry` and `ScaleUpSignalError` for
72
+ step-level fault recovery and dynamic slice scaling.
73
+ - [`PathwaysJobSet`][gke-readme] (`pathwaysutils.experimental.gke.jobset`)
74
+ builds, customizes, exports, and deploys Kubernetes `JobSet` manifests for
75
+ Pathways workloads on GKE.
76
+ - [Shared Pathways Service][sps-readme]
77
+ (`pathwaysutils.experimental.shared_pathways_service`) deploys a persistent
78
+ multi-tenant Pathways service on GKE for interactive JAX sessions.
79
+
80
+ ## Further Reading
81
+
82
+ - [Get started with Pathways on Google Cloud][cloud-docs]
83
+ - [Pathways Research Paper](https://arxiv.org/abs/2203.12533)
84
+
85
+ [gke-readme]: https://github.com/AI-Hypercomputer/pathways-utils/tree/main/pathwaysutils/experimental/gke
86
+ [sps-readme]: https://github.com/AI-Hypercomputer/pathways-utils/tree/main/pathwaysutils/experimental/shared_pathways_service
87
+ [cloud-docs]: https://docs.cloud.google.com/ai-hypercomputer/docs/workloads/pathways-on-cloud/pathways-intro
88
+
89
+
90
+
@@ -0,0 +1,50 @@
1
+ # APIs to get started with using Pathways on Cloud
2
+
3
+ Pathways is a compute orchestration runtime for single-controller ML workloads
4
+ across multiple Cloud TPU slices. A single Python controller orchestrates
5
+ computation across hundreds or thousands of TPU chips, unlocking slice-level
6
+ training resiliency, fast cross-slice data movement, and interactive
7
+ multi-slice development.
8
+
9
+ This package bundles the Python client integrations, resharding and elasticity
10
+ helpers, and GKE deployment builders for running JAX workloads on Pathways on
11
+ Cloud.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install pathwaysutils
17
+ # Optional GKE JobSet generator and kubectl/Kubernetes client dependencies:
18
+ pip install 'pathwaysutils[gke]'
19
+ # Optional experimental Shared Pathways Service (SPS) dependencies:
20
+ pip install 'pathwaysutils[sps]'
21
+ ```
22
+
23
+ ## Core Modules
24
+
25
+ - `pathwaysutils.initialize()` registers the Pathways IFRT proxy backend,
26
+ configures the compilation cache and XProf trace hooks, and registers Orbax
27
+ checkpoint handlers.
28
+ - `pathwaysutils.reshard.reshard` reshards arrays and PyTrees across device
29
+ meshes directly on Pathways workers via the IFRT `RemapArray` API without
30
+ routing tensors through controller memory.
31
+ - `pathwaysutils.elastic.manager.Manager` monitors slice health in the
32
+ background and provides `@elastic_retry` and `ScaleUpSignalError` for
33
+ step-level fault recovery and dynamic slice scaling.
34
+ - [`PathwaysJobSet`][gke-readme] (`pathwaysutils.experimental.gke.jobset`)
35
+ builds, customizes, exports, and deploys Kubernetes `JobSet` manifests for
36
+ Pathways workloads on GKE.
37
+ - [Shared Pathways Service][sps-readme]
38
+ (`pathwaysutils.experimental.shared_pathways_service`) deploys a persistent
39
+ multi-tenant Pathways service on GKE for interactive JAX sessions.
40
+
41
+ ## Further Reading
42
+
43
+ - [Get started with Pathways on Google Cloud][cloud-docs]
44
+ - [Pathways Research Paper](https://arxiv.org/abs/2203.12533)
45
+
46
+ [gke-readme]: https://github.com/AI-Hypercomputer/pathways-utils/tree/main/pathwaysutils/experimental/gke
47
+ [sps-readme]: https://github.com/AI-Hypercomputer/pathways-utils/tree/main/pathwaysutils/experimental/shared_pathways_service
48
+ [cloud-docs]: https://docs.cloud.google.com/ai-hypercomputer/docs/workloads/pathways-on-cloud/pathways-intro
49
+
50
+
@@ -21,4 +21,4 @@ is_pathways_backend_used: Callable[[], bool] = _initialize.is_pathways_backend_u
21
21
  del _initialize
22
22
 
23
23
  # When changing this, also update the CHANGELOG.md.
24
- __version__ = "v0.1.13"
24
+ __version__ = "v0.1.14"
@@ -40,7 +40,9 @@ def is_pathways_backend_used() -> bool:
40
40
  is not necessarily which backend is ultimately selected or there may be more
41
41
  than one platform specified and another may have higher priority.
42
42
  """
43
- return jax.config.jax_platforms and "proxy" in jax.config.jax_platforms
43
+ return bool(
44
+ jax.config.jax_platforms and "proxy" in jax.config.jax_platforms
45
+ )
44
46
 
45
47
 
46
48
  def _is_persistence_enabled() -> bool:
@@ -198,6 +198,10 @@ def wait_for_slices(
198
198
  TimeoutError: If the timeout is reached before the slices become
199
199
  active.
200
200
  """
201
+ if poll_interval < 0:
202
+ raise ValueError(f"poll_interval must be non-negative, got {poll_interval}")
203
+ if timeout is not None and timeout < 0:
204
+ raise ValueError(f"timeout must be non-negative, got {timeout}")
201
205
  if slice_to_devices is None:
202
206
  _logger.debug("slice_to_devices is None. Getting from jax.devices().")
203
207
  slice_to_devices = get_slice_to_devices(jax.devices())
@@ -158,8 +158,9 @@ class Manager:
158
158
  pass
159
159
  else:
160
160
  raise
161
- self._monitor_thread = None
162
- self._stop_event = None
161
+ finally:
162
+ self._monitor_thread = None
163
+ self._stop_event = None
163
164
 
164
165
  @functools.cached_property
165
166
  def total_slice_count(self) -> int:
@@ -197,6 +198,14 @@ class Manager:
197
198
  """The number of active slices."""
198
199
  return len(self.active_slice_indices)
199
200
 
201
+ @property
202
+ def active_devices(self) -> list[jax.Device]:
203
+ """The devices belonging to the active slices, ordered by slice index."""
204
+ devices = []
205
+ for slice_index in sorted(self.active_slice_indices):
206
+ devices.extend(self.slice_to_devices[slice_index])
207
+ return devices
208
+
200
209
  def scale_by_active_slices(self, x: int | float) -> int | float:
201
210
  """Scale x by the number of active slices."""
202
211
  if isinstance(x, int):
@@ -214,20 +223,6 @@ class Manager:
214
223
  else:
215
224
  raise ValueError(f"Unsupported type: {type(x)=}")
216
225
 
217
- def _cleanup_on_retry(self):
218
- """Cleans up JAX caches and traces on retry."""
219
- try:
220
- _logger.debug("Cleaning up any ongoing traces")
221
- jax.profiler.stop_trace()
222
- except (RuntimeError, ValueError):
223
- _logger.debug("No ongoing traces to clean up")
224
- except Exception: # pylint: disable=broad-exception-caught
225
- _logger.exception("Error cleaning up ongoing traces")
226
-
227
- jax.clear_caches()
228
- for array in jax.live_arrays():
229
- array.delete()
230
-
231
226
  def _check_inactive_slices(self) -> None:
232
227
  """Checks inactive slices and updates available_inactive_slices."""
233
228
  if not self.inactive_slice_indices:
@@ -68,10 +68,21 @@ def concatenate_by_mesh_axis(
68
68
  if not flattened_arrays[0]:
69
69
  return array_trees[0]
70
70
 
71
- # Extract the shared mesh from each PyTree (from an arbitrary array in each).
71
+ # Extract the shared mesh from each PyTree and verify all leaves in a PyTree
72
+ # share that mesh.
72
73
  meshes_to_concatenate = [
73
74
  _get_named_sharding(array).mesh for array in input_flat_arrays[0]
74
75
  ]
76
+ for tree_arrays, expected_mesh in zip(
77
+ flattened_arrays, meshes_to_concatenate
78
+ ):
79
+ for array in tree_arrays:
80
+ sharding = _get_named_sharding(array)
81
+ if sharding.mesh != expected_mesh:
82
+ raise ValueError(
83
+ "All arrays in each PyTree must have the same mesh. Got"
84
+ f" {sharding.mesh} vs. {expected_mesh}."
85
+ )
75
86
 
76
87
  # Validate that the meshes are compatible.
77
88
  reference_mesh = meshes_to_concatenate[0]
@@ -117,6 +128,19 @@ def concatenate_by_mesh_axis(
117
128
  ) -> jax.sharding.NamedSharding:
118
129
  reference_sharding = _get_named_sharding(arrays[0])
119
130
  reference_spec = reference_sharding.spec
131
+ for array in arrays[1:]:
132
+ sharding = _get_named_sharding(array)
133
+ if sharding.spec != reference_spec:
134
+ raise ValueError(
135
+ "Corresponding arrays across PyTrees must have the same"
136
+ f" PartitionSpec. Got {sharding.spec} vs. {reference_spec}."
137
+ )
138
+ if sharding.memory_kind != reference_sharding.memory_kind:
139
+ raise ValueError(
140
+ "Corresponding arrays across PyTrees must have the same"
141
+ f" memory_kind. Got {sharding.memory_kind} vs."
142
+ f" {reference_sharding.memory_kind}."
143
+ )
120
144
  return jax.sharding.NamedSharding(
121
145
  concatenated_mesh,
122
146
  reference_spec,
@@ -0,0 +1,142 @@
1
+ # PathwaysJobSet Builder
2
+
3
+ `PathwaysJobSet` generates and deploys Kubernetes `JobSet` resources (`jobset.x-k8s.io`) for running distributed Pathways workloads on Google Kubernetes Engine (GKE) without requiring custom controllers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install 'pathwaysutils[gke]'
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ ```python
14
+ from pathwaysutils.experimental.gke import jobset
15
+
16
+ pw_jobset = jobset.PathwaysJobSet(
17
+ name="my-workload",
18
+ namespace="default",
19
+ pathways_dir="gs://my-bucket/pathways-scratch",
20
+ tpu_type="v5e",
21
+ topology="2x4",
22
+ num_slices=1,
23
+ )
24
+
25
+ # Export to YAML or deploy directly to the active cluster
26
+ pw_jobset.export_yaml("jobset.yaml")
27
+ pw_jobset.apply(recreate=True)
28
+ ```
29
+
30
+ ## Features
31
+
32
+ ### Elasticity & Multislice
33
+ Scale across multiple TPU slices with dynamic resilience:
34
+
35
+ ```python
36
+ pw_jobset = jobset.PathwaysJobSet(
37
+ name="elastic-v6e",
38
+ namespace="default",
39
+ pathways_dir="gs://my-bucket/scratch",
40
+ tpu_type="v6e",
41
+ topology="4x4",
42
+ num_slices=4,
43
+ elastic_slices=2, # Configures Pathways Proxy for dynamic slice recovery
44
+ )
45
+ ```
46
+
47
+ ### Heterogeneous Multi-Topology Slices
48
+ Combine multiple TPU slice topologies as separate worker `replicatedJobs`
49
+ within a single `JobSet`. Call `add_worker_topology` before worker mutators
50
+ (`add_colocated_python`, `add_gcsfuse`, or `with_custom_libtpu`) so they apply
51
+ across all worker templates:
52
+
53
+ ```python
54
+ pw_jobset = (
55
+ jobset.PathwaysJobSet(
56
+ name="heterogeneous-v5e",
57
+ namespace="default",
58
+ pathways_dir="gs://my-bucket/scratch",
59
+ tpu_type="v5e",
60
+ topology="4x8",
61
+ num_slices=1,
62
+ )
63
+ .add_worker_topology(
64
+ tpu_type="ct5lp-hightpu-8t",
65
+ topology="2x4",
66
+ num_slices=1,
67
+ )
68
+ )
69
+ ```
70
+
71
+ ### In-Pod User Workload
72
+ Run training or inference directly in the head pod alongside the Resource Manager and Proxy sidecars:
73
+
74
+ ```python
75
+ pw_jobset.add_user_workload(
76
+ image="us-docker.pkg.dev/my-project/images/my-trainer:latest",
77
+ command="python3 train.py --batch_size=32",
78
+ env={"LOG_LEVEL": "INFO"},
79
+ )
80
+ ```
81
+
82
+ ### Colocated Python Sidecar
83
+ Inject a sidecar container onto worker pods sharing memory with
84
+ `pathways-worker` for zero-copy tensor transfers:
85
+
86
+ ```python
87
+ pw_jobset.add_colocated_python(
88
+ image="us-docker.pkg.dev/my-project/images/worker-sidecar:latest",
89
+ shm_mount_path="/tmp/shared-memory",
90
+ shm_size_limit="16Gi",
91
+ )
92
+ ```
93
+
94
+ ### GCSFuse Cloud Storage Mounts
95
+ Mount GCS buckets to head, worker, or all containers:
96
+
97
+ ```python
98
+ pw_jobset.add_gcsfuse(
99
+ containers="all",
100
+ mount_path="/data",
101
+ bucket="my-data-bucket",
102
+ read_only=True,
103
+ )
104
+ ```
105
+
106
+ ### Custom `libtpu.so` Runtime Override
107
+ Set `TPU_LIBRARY_PATH` across the Pathways containers (`pathways-rm`,
108
+ `pathways-proxy`, and `pathways-worker` when `containers="all"`) without
109
+ injecting it into user or sidecar containers:
110
+
111
+ ```python
112
+ pw_jobset.with_custom_libtpu(
113
+ libtpu_path="/data/libtpu/libtpu.so",
114
+ containers="all",
115
+ )
116
+ ```
117
+
118
+ ### Container & Pod Spec Overrides
119
+ Customize arguments, environment variables, resources, or volumes on any container or pod:
120
+
121
+ ```python
122
+ pw_jobset = jobset.PathwaysJobSet(
123
+ ...,
124
+ rm_container_kwargs={"args": ["--v=1"]},
125
+ proxy_container_kwargs={"env": {"XLA_FLAGS": "--xla_dump_to=/tmp"}},
126
+ worker_container_kwargs={"args": ["--stderrthreshold=0"]},
127
+ worker_pod_spec_kwargs={"priority_class_name": "high-priority"},
128
+ )
129
+ ```
130
+
131
+ ## Serialization & Round-Tripping
132
+
133
+ Convert between Python objects, YAML files, and dictionaries:
134
+
135
+ ```python
136
+ # Save and load JobSet configurations
137
+ pw_jobset.export_yaml("jobset.yaml")
138
+ loaded_jobset = jobset.PathwaysJobSet.import_yaml("jobset.yaml")
139
+
140
+ # Inspect raw Kubernetes resource dictionary
141
+ config_dict = pw_jobset.to_dict()
142
+ ```