haliax 1.4.dev400__tar.gz → 1.4.dev402__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.
- {haliax-1.4.dev400 → haliax-1.4.dev402}/PKG-INFO +1 -1
- haliax-1.4.dev402/src/haliax/__about__.py +1 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/__init__.py +2 -0
- haliax-1.4.dev402/src/haliax/field.py +38 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/partitioning.py +57 -29
- haliax-1.4.dev402/tests/test_field.py +19 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_partitioning.py +20 -1
- haliax-1.4.dev400/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.coveragerc +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.flake8 +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.github/workflows/run_tests.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.gitignore +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.playbooks/add-types.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.playbooks/wrap-non-named.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/AGENTS.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/LICENSE +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/README.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/api.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/css/material.css +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/faq.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/fp8.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/index.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/indexing.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/matmul.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/nn.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/partitioning.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/primer.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/rearrange.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/requirements.txt +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/scan.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/state-dict.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/tutorial.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/typing.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/docs/vmap.md +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/mkdocs.yml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/pyproject.toml +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/scan.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/state_dict.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/axis.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/core.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/haxtyping.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/hof.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/embedding.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/linear.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/mlp.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/ops.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/random.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/state_dict.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/types.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/util.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/core_test.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_attention.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_axis.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_conv.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_debug.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_dot.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_dtype_typing.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_fp8.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_hof.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_int8.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_moe_linear.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_namedarray_typing.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_nn.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_ops.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_pool.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_random.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_scan.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_scatter_gather.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_state_dict.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_utils.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/tests/test_visualize_sharding.py +0 -0
- {haliax-1.4.dev400 → haliax-1.4.dev402}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: haliax
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.dev402
|
|
4
4
|
Summary: Named Tensors for Legible Deep Learning in JAX
|
|
5
5
|
Project-URL: Homepage, https://github.com/stanford-crfm/haliax
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/stanford-crfm/haliax/issues/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.dev402"
|
|
@@ -17,6 +17,7 @@ import haliax.random as random
|
|
|
17
17
|
import haliax.state_dict as state_dict
|
|
18
18
|
import haliax.tree_util as tree_util
|
|
19
19
|
import haliax.util as util
|
|
20
|
+
from .field import field
|
|
20
21
|
|
|
21
22
|
from ._src.dot import dot
|
|
22
23
|
from ._src.einsum import einsum
|
|
@@ -932,6 +933,7 @@ __all__ = [
|
|
|
932
933
|
"tree_util",
|
|
933
934
|
"nn",
|
|
934
935
|
"state_dict",
|
|
936
|
+
"field",
|
|
935
937
|
"Axis",
|
|
936
938
|
"AxisSpec",
|
|
937
939
|
"AxisSelection",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
import equinox as eqx
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def field(
|
|
9
|
+
*,
|
|
10
|
+
converter: Callable[[Any], Any] | None = None,
|
|
11
|
+
static: bool = False,
|
|
12
|
+
axis_names: tuple[str, ...] | None = None,
|
|
13
|
+
**kwargs,
|
|
14
|
+
):
|
|
15
|
+
"""Wrapper around :func:`equinox.field` with optional ``axis_names`` metadata.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
converter: Optional function applied to the value during dataclass initialisation.
|
|
19
|
+
static: Whether the field is static in the PyTree.
|
|
20
|
+
axis_names: Optional axis names associated with array fields. Cannot be
|
|
21
|
+
specified together with ``static=True``.
|
|
22
|
+
**kwargs: Additional keyword arguments forwarded to :func:`dataclasses.field`.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
A dataclasses field configured like :func:`equinox.field` with additional
|
|
26
|
+
``axis_names`` metadata.
|
|
27
|
+
"""
|
|
28
|
+
if static and axis_names is not None:
|
|
29
|
+
raise ValueError("axis_names cannot be specified together with static=True")
|
|
30
|
+
|
|
31
|
+
metadata = dict(kwargs.pop("metadata", {}))
|
|
32
|
+
metadata["axis_names"] = axis_names
|
|
33
|
+
|
|
34
|
+
field_kwargs = {}
|
|
35
|
+
if converter is not None:
|
|
36
|
+
field_kwargs["converter"] = converter
|
|
37
|
+
|
|
38
|
+
return eqx.field(static=static, metadata=metadata, **field_kwargs, **kwargs)
|
|
@@ -177,24 +177,21 @@ def shard_with_axis_mapping(x: T, mapping: ResourceMapping, mesh: Optional[Mesh]
|
|
|
177
177
|
return shard(x, mapping, mesh)
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
def
|
|
180
|
+
def pspec_for(
|
|
181
181
|
tree: PyTree,
|
|
182
182
|
resource_mapping: Optional[ResourceMapping] = None,
|
|
183
183
|
preserve_existing_shardings: bool = True,
|
|
184
184
|
use_auto_sharding: bool = True,
|
|
185
|
-
mesh: Optional[Mesh] = None,
|
|
186
185
|
) -> PyTree:
|
|
187
|
-
"""
|
|
188
|
-
Infer the sharding for a module, to be used with named_jit.
|
|
189
|
-
The basic idea is to tree all NamedArrays as leaves for the purposes of this function,
|
|
190
|
-
and to create NamedShardings from those names plus the resource_mapping.
|
|
191
|
-
If preserve_existing_shardings is True, then NamedArrays that are already sharded are left alone.
|
|
186
|
+
"""Infer the :class:`PartitionSpec` for a module.
|
|
192
187
|
|
|
193
|
-
|
|
188
|
+
This behaves like :func:`infer_resource_partitions` but returns ``PartitionSpec``
|
|
189
|
+
objects instead of :class:`~jax.sharding.NamedSharding`. It is primarily a helper
|
|
190
|
+
for :func:`infer_resource_partitions` but may be useful when only the partition
|
|
191
|
+
specification is required.
|
|
194
192
|
|
|
195
|
-
If
|
|
196
|
-
|
|
197
|
-
don't have a sharding.
|
|
193
|
+
If ``preserve_existing_shardings`` is ``True``, then arrays that already have a
|
|
194
|
+
sharding are left untouched and ``None`` is returned for those leaves.
|
|
198
195
|
"""
|
|
199
196
|
if resource_mapping is None:
|
|
200
197
|
resource_mapping = current_thread_local_mapping()
|
|
@@ -202,35 +199,26 @@ def infer_resource_partitions(
|
|
|
202
199
|
if resource_mapping is None:
|
|
203
200
|
raise ValueError("No resource mapping found")
|
|
204
201
|
|
|
205
|
-
mesh = mesh or _get_mesh()
|
|
206
|
-
assert not isinstance(mesh, dict)
|
|
207
|
-
|
|
208
202
|
def partition_spec(node: typing.Any):
|
|
209
203
|
if isinstance(node, NamedArray):
|
|
210
204
|
# If our NamedArray doesn't have an array (or a shapedtypestruct), we can't shard it
|
|
211
|
-
# so better to not try
|
|
212
205
|
if not is_jax_array_like(node.array):
|
|
213
206
|
return None
|
|
214
207
|
|
|
215
|
-
if preserve_existing_shardings
|
|
216
|
-
current_sharding = getattr(node.array, "sharding", None)
|
|
217
|
-
else:
|
|
218
|
-
current_sharding = None
|
|
219
|
-
|
|
208
|
+
current_sharding = getattr(node.array, "sharding", None) if preserve_existing_shardings else None
|
|
220
209
|
if current_sharding is not None:
|
|
221
|
-
return
|
|
210
|
+
return None
|
|
222
211
|
else:
|
|
223
|
-
|
|
224
|
-
return sharding
|
|
212
|
+
return pspec_for_axis(node.axes, resource_mapping)
|
|
225
213
|
elif is_jax_array_like(node):
|
|
226
214
|
sharding = getattr(node, "sharding", None)
|
|
227
215
|
# TODO: these are usually replicated. Is there a better way to tell?
|
|
228
216
|
if node.shape == ():
|
|
229
|
-
return
|
|
217
|
+
return PartitionSpec()
|
|
230
218
|
elif isinstance(sharding, SingleDeviceSharding):
|
|
231
|
-
return
|
|
232
|
-
elif sharding is not None:
|
|
233
|
-
return
|
|
219
|
+
return PartitionSpec(None)
|
|
220
|
+
elif sharding is not None and preserve_existing_shardings:
|
|
221
|
+
return None
|
|
234
222
|
# elif use_auto_sharding:
|
|
235
223
|
# TODO: auto doesn't seem to really work reliably yet
|
|
236
224
|
# compat between 0.4.10 and 0.4.11
|
|
@@ -238,15 +226,54 @@ def infer_resource_partitions(
|
|
|
238
226
|
# return AUTO(mesh)
|
|
239
227
|
# else:
|
|
240
228
|
# return AUTO
|
|
241
|
-
return
|
|
229
|
+
return PartitionSpec(None)
|
|
242
230
|
elif isinstance(node, (bool, float, complex, int)):
|
|
243
|
-
return
|
|
231
|
+
return PartitionSpec()
|
|
244
232
|
else:
|
|
245
233
|
return None
|
|
246
234
|
|
|
247
235
|
return htu.tree_map(partition_spec, tree)
|
|
248
236
|
|
|
249
237
|
|
|
238
|
+
def infer_resource_partitions(
|
|
239
|
+
tree: PyTree,
|
|
240
|
+
resource_mapping: Optional[ResourceMapping] = None,
|
|
241
|
+
preserve_existing_shardings: bool = True,
|
|
242
|
+
use_auto_sharding: bool = True,
|
|
243
|
+
mesh: Optional[Mesh] = None,
|
|
244
|
+
) -> PyTree:
|
|
245
|
+
"""
|
|
246
|
+
Infer the sharding for a module, to be used with ``named_jit``.
|
|
247
|
+
|
|
248
|
+
This first calls :func:`pspec_for` to compute ``PartitionSpec`` objects and then
|
|
249
|
+
wraps them in :class:`~jax.sharding.NamedSharding` using the provided mesh. If
|
|
250
|
+
``preserve_existing_shardings`` is ``True``, then arrays that are already sharded
|
|
251
|
+
retain their current sharding.
|
|
252
|
+
"""
|
|
253
|
+
pspecs = pspec_for(
|
|
254
|
+
tree,
|
|
255
|
+
resource_mapping=resource_mapping,
|
|
256
|
+
preserve_existing_shardings=preserve_existing_shardings,
|
|
257
|
+
use_auto_sharding=use_auto_sharding,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
mesh = mesh or _get_mesh()
|
|
261
|
+
assert not isinstance(mesh, dict)
|
|
262
|
+
|
|
263
|
+
def to_sharding(node: typing.Any, spec: typing.Any):
|
|
264
|
+
if spec is None:
|
|
265
|
+
if isinstance(node, NamedArray):
|
|
266
|
+
return getattr(node.array, "sharding", None)
|
|
267
|
+
elif is_jax_array_like(node):
|
|
268
|
+
return getattr(node, "sharding", None)
|
|
269
|
+
else:
|
|
270
|
+
return None
|
|
271
|
+
else:
|
|
272
|
+
return NamedSharding(mesh, spec)
|
|
273
|
+
|
|
274
|
+
return htu.tree_map(to_sharding, tree, pspecs)
|
|
275
|
+
|
|
276
|
+
|
|
250
277
|
class WrappedCallable(typing.Protocol[Args, R]):
|
|
251
278
|
"""
|
|
252
279
|
A wrapper for a callable that preserves the original function's name and qualname.
|
|
@@ -659,6 +686,7 @@ __all__ = [
|
|
|
659
686
|
"auto_sharded",
|
|
660
687
|
"shard",
|
|
661
688
|
"shard_with_axis_mapping",
|
|
689
|
+
"pspec_for",
|
|
662
690
|
"infer_resource_partitions",
|
|
663
691
|
"named_jit",
|
|
664
692
|
"fsdp",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import jax.numpy as jnp
|
|
2
|
+
import equinox as eqx
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
import haliax as hax
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class M(eqx.Module):
|
|
9
|
+
a: jnp.ndarray = hax.field(axis_names=("batch",))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_axis_names_metadata():
|
|
13
|
+
field = M.__dataclass_fields__["a"]
|
|
14
|
+
assert field.metadata["axis_names"] == ("batch",)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_axis_names_static_exclusive():
|
|
18
|
+
with pytest.raises(ValueError):
|
|
19
|
+
hax.field(static=True, axis_names=("x",))
|
|
@@ -7,7 +7,13 @@ from jaxtyping import Array
|
|
|
7
7
|
|
|
8
8
|
import haliax as hax
|
|
9
9
|
from haliax import Axis, NamedArray
|
|
10
|
-
from haliax.partitioning import
|
|
10
|
+
from haliax.partitioning import (
|
|
11
|
+
ResourceAxis,
|
|
12
|
+
axis_mapping,
|
|
13
|
+
infer_resource_partitions,
|
|
14
|
+
named_jit,
|
|
15
|
+
pspec_for,
|
|
16
|
+
)
|
|
11
17
|
from test_utils import skip_if_not_enough_devices
|
|
12
18
|
|
|
13
19
|
|
|
@@ -40,6 +46,19 @@ def test_infer_named_axes():
|
|
|
40
46
|
assert axes.unnamed1.is_fully_replicated
|
|
41
47
|
|
|
42
48
|
|
|
49
|
+
def test_pspec_for_named_axes():
|
|
50
|
+
mesh = Mesh(np.array(jax.devices()).reshape(-1, 1), (ResourceAxis.DATA, ResourceAxis.MODEL))
|
|
51
|
+
with axis_mapping(resource_map), mesh:
|
|
52
|
+
mod = MyModule(named=hax.ones((Dim1, Dim2, Dim3)), unnamed1=jnp.ones(Dim2.size), static_field=1)
|
|
53
|
+
|
|
54
|
+
specs: MyModule = pspec_for(mod, preserve_existing_shardings=False)
|
|
55
|
+
|
|
56
|
+
spec = PartitionSpec(None, ResourceAxis.DATA, ResourceAxis.MODEL)
|
|
57
|
+
|
|
58
|
+
assert specs.named == spec
|
|
59
|
+
assert specs.unnamed1 == PartitionSpec(None)
|
|
60
|
+
|
|
61
|
+
|
|
43
62
|
class MyModuleInit(eqx.Module):
|
|
44
63
|
named: NamedArray
|
|
45
64
|
unnamed1: Array
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev400"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|