haliax 1.4.dev402__tar.gz → 1.4.dev404__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.dev402 → haliax-1.4.dev404}/PKG-INFO +1 -1
- haliax-1.4.dev404/src/haliax/__about__.py +1 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/scan.py +72 -1
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/partitioning.py +33 -1
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_hof.py +33 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_partitioning.py +28 -0
- haliax-1.4.dev402/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.coveragerc +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.flake8 +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.github/workflows/run_tests.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.gitignore +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.playbooks/add-types.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.playbooks/wrap-non-named.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/AGENTS.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/LICENSE +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/README.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/api.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/css/material.css +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/faq.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/fp8.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/index.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/indexing.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/matmul.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/nn.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/partitioning.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/primer.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/rearrange.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/requirements.txt +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/scan.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/state-dict.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/tutorial.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/typing.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/docs/vmap.md +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/mkdocs.yml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/pyproject.toml +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/__init__.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/state_dict.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/axis.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/core.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/field.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/haxtyping.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/hof.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/embedding.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/linear.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/mlp.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/ops.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/random.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/state_dict.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/types.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/util.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/core_test.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_attention.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_axis.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_conv.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_debug.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_dot.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_dtype_typing.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_field.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_fp8.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_int8.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_moe_linear.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_namedarray_typing.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_nn.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_ops.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_pool.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_random.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_scan.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_scatter_gather.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_state_dict.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_utils.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/tests/test_visualize_sharding.py +0 -0
- {haliax-1.4.dev402 → haliax-1.4.dev404}/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.dev404
|
|
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.dev404"
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import functools as ft
|
|
3
|
+
import inspect
|
|
3
4
|
from typing import Any, Callable, Literal, ParamSpec, Protocol, Sequence, Tuple, TypeVar, Union, overload
|
|
4
5
|
|
|
5
6
|
import equinox as eqx
|
|
6
7
|
import jax
|
|
8
|
+
import jax.tree_util as jtu
|
|
7
9
|
from jaxtyping import PyTree
|
|
8
10
|
|
|
9
11
|
import haliax
|
|
@@ -357,7 +359,46 @@ def scan(
|
|
|
357
359
|
return carry, y
|
|
358
360
|
|
|
359
361
|
true_axis = _infer_axis_size_from_tree(axis_first_xs, axis)
|
|
360
|
-
axis_size =
|
|
362
|
+
axis_size = true_axis.size
|
|
363
|
+
|
|
364
|
+
# build a mapping from positional argument indices to their names for friendlier error messages
|
|
365
|
+
sig = inspect.signature(f)
|
|
366
|
+
arg_pos_names: dict[int, str] = {}
|
|
367
|
+
params = list(sig.parameters.values())[1:] # skip carry
|
|
368
|
+
pos_count = 0
|
|
369
|
+
var_pos_name: str | None = None
|
|
370
|
+
for param in params:
|
|
371
|
+
if param.kind in (
|
|
372
|
+
inspect.Parameter.POSITIONAL_ONLY,
|
|
373
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
374
|
+
):
|
|
375
|
+
arg_pos_names[pos_count] = param.name
|
|
376
|
+
pos_count += 1
|
|
377
|
+
elif param.kind == inspect.Parameter.VAR_POSITIONAL:
|
|
378
|
+
var_pos_name = param.name
|
|
379
|
+
break
|
|
380
|
+
if var_pos_name is not None:
|
|
381
|
+
for i in range(pos_count, len(args)):
|
|
382
|
+
arg_pos_names[i] = f"{var_pos_name}[{i - pos_count}]"
|
|
383
|
+
|
|
384
|
+
path_leaves, _ = jtu.tree_flatten_with_path(axis_first_xs, is_leaf=is_named_array)
|
|
385
|
+
mismatched = []
|
|
386
|
+
for path, leaf in path_leaves:
|
|
387
|
+
if isinstance(leaf, NamedArray):
|
|
388
|
+
lead_size = leaf.array.shape[0]
|
|
389
|
+
elif is_jax_array_like(leaf):
|
|
390
|
+
lead_size = leaf.shape[0]
|
|
391
|
+
else:
|
|
392
|
+
continue
|
|
393
|
+
if lead_size != axis_size:
|
|
394
|
+
mismatched.append((path, lead_size))
|
|
395
|
+
if mismatched:
|
|
396
|
+
details = ", ".join(
|
|
397
|
+
f"{_format_tree_path(p, arg_pos_names)} has leading dimension {s}" for p, s in mismatched
|
|
398
|
+
)
|
|
399
|
+
raise ValueError(
|
|
400
|
+
f"scan got `length` argument of {axis_size} but some inputs had different leading axis sizes: {details}"
|
|
401
|
+
)
|
|
361
402
|
|
|
362
403
|
nested_scan = checkpoint.nested
|
|
363
404
|
outer_block_size = nested_scan_outer_block(nested_scan, axis_size)
|
|
@@ -508,6 +549,36 @@ def _zero_if_array_else_none(x: Any) -> ResolvedUnnamedAxisSpec:
|
|
|
508
549
|
return 0 if is_jax_array_like(x) else None
|
|
509
550
|
|
|
510
551
|
|
|
552
|
+
def _format_tree_path(
|
|
553
|
+
path: tuple[jtu.KeyEntry, ...], arg_pos_names: dict[int, str] | None = None
|
|
554
|
+
) -> str:
|
|
555
|
+
parts: list[str] = []
|
|
556
|
+
i = 0
|
|
557
|
+
if len(path) >= 2 and isinstance(path[0], jtu.SequenceKey):
|
|
558
|
+
if path[0].idx == 0 and isinstance(path[1], jtu.SequenceKey):
|
|
559
|
+
name = (arg_pos_names or {}).get(path[1].idx)
|
|
560
|
+
if name is not None:
|
|
561
|
+
parts.append(name)
|
|
562
|
+
else:
|
|
563
|
+
parts.append(f"[{path[1].idx}]")
|
|
564
|
+
i = 2
|
|
565
|
+
elif path[0].idx == 1 and isinstance(path[1], jtu.DictKey):
|
|
566
|
+
parts.append(str(path[1].key))
|
|
567
|
+
i = 2
|
|
568
|
+
for p in path[i:]:
|
|
569
|
+
if isinstance(p, jtu.GetAttrKey):
|
|
570
|
+
parts.append("." + p.name)
|
|
571
|
+
elif isinstance(p, jtu.DictKey):
|
|
572
|
+
parts.append(f"[{p.key!r}]")
|
|
573
|
+
elif isinstance(p, jtu.SequenceKey):
|
|
574
|
+
parts.append(f"[{p.idx}]")
|
|
575
|
+
else: # pragma: no cover - future-proofing
|
|
576
|
+
parts.append(str(p))
|
|
577
|
+
if parts and parts[0].startswith("."):
|
|
578
|
+
parts[0] = parts[0][1:]
|
|
579
|
+
return "".join(parts) or "<root>"
|
|
580
|
+
|
|
581
|
+
|
|
511
582
|
def _infer_axis_size_from_tree(result, axis):
|
|
512
583
|
if isinstance(axis, str):
|
|
513
584
|
result_leaves = jax.tree_util.tree_leaves(result, is_leaf=_is_passive_array)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
+
import dataclasses
|
|
2
3
|
import functools
|
|
3
4
|
import threading
|
|
4
5
|
import typing
|
|
@@ -210,6 +211,37 @@ def pspec_for(
|
|
|
210
211
|
return None
|
|
211
212
|
else:
|
|
212
213
|
return pspec_for_axis(node.axes, resource_mapping)
|
|
214
|
+
elif isinstance(node, eqx.Module):
|
|
215
|
+
# handle eqx.Module explicitly so that we can look at axis_names metadata
|
|
216
|
+
updates: dict[str, typing.Any] = {}
|
|
217
|
+
for field in dataclasses.fields(node):
|
|
218
|
+
if field.metadata.get("static", False):
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
value = getattr(node, field.name)
|
|
222
|
+
axis_names = field.metadata.get("axis_names") if field.metadata is not None else None
|
|
223
|
+
if axis_names is not None and is_jax_array_like(value):
|
|
224
|
+
current_sharding = (
|
|
225
|
+
getattr(value, "sharding", None) if preserve_existing_shardings else None
|
|
226
|
+
)
|
|
227
|
+
if current_sharding is not None:
|
|
228
|
+
updates[field.name] = None
|
|
229
|
+
else:
|
|
230
|
+
updates[field.name] = pspec_for_axis(axis_names, resource_mapping)
|
|
231
|
+
else:
|
|
232
|
+
updates[field.name] = htu.tree_map(
|
|
233
|
+
partition_spec, value, is_leaf=lambda x: isinstance(x, eqx.Module)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
new_node = object.__new__(type(node))
|
|
237
|
+
for field in dataclasses.fields(node):
|
|
238
|
+
object.__setattr__(
|
|
239
|
+
new_node,
|
|
240
|
+
field.name,
|
|
241
|
+
updates.get(field.name, getattr(node, field.name)),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
return new_node
|
|
213
245
|
elif is_jax_array_like(node):
|
|
214
246
|
sharding = getattr(node, "sharding", None)
|
|
215
247
|
# TODO: these are usually replicated. Is there a better way to tell?
|
|
@@ -232,7 +264,7 @@ def pspec_for(
|
|
|
232
264
|
else:
|
|
233
265
|
return None
|
|
234
266
|
|
|
235
|
-
return htu.tree_map(partition_spec, tree)
|
|
267
|
+
return htu.tree_map(partition_spec, tree, is_leaf=lambda x: isinstance(x, eqx.Module))
|
|
236
268
|
|
|
237
269
|
|
|
238
270
|
def infer_resource_partitions(
|
|
@@ -5,6 +5,7 @@ from jax.random import PRNGKey
|
|
|
5
5
|
import haliax as hax
|
|
6
6
|
from haliax import Axis, NamedArray
|
|
7
7
|
from haliax.util import is_named_array
|
|
8
|
+
import pytest
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def test_scan():
|
|
@@ -136,6 +137,38 @@ def test_scan_hierarchical():
|
|
|
136
137
|
assert jnp.all(jnp.equal(selected.array, selected_blocked.array))
|
|
137
138
|
|
|
138
139
|
|
|
140
|
+
def test_scan_reports_mismatched_unnamed_array():
|
|
141
|
+
Height = Axis("Height", 2)
|
|
142
|
+
|
|
143
|
+
def f(c, x, y):
|
|
144
|
+
return c, x + y
|
|
145
|
+
|
|
146
|
+
good = jnp.zeros((Height.size, 3))
|
|
147
|
+
bad = jnp.zeros((Height.size - 1, 3))
|
|
148
|
+
|
|
149
|
+
with pytest.raises(ValueError) as e:
|
|
150
|
+
hax.scan(f, Height)(0, good, y=bad)
|
|
151
|
+
|
|
152
|
+
assert "y has leading dimension" in str(e.value)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_scan_reports_eqx_module_field_path():
|
|
156
|
+
Height = Axis("Height", 2)
|
|
157
|
+
|
|
158
|
+
class Foo(eqx.Module):
|
|
159
|
+
my_array: jnp.ndarray
|
|
160
|
+
|
|
161
|
+
foo = Foo(jnp.zeros((Height.size - 1, 3)))
|
|
162
|
+
|
|
163
|
+
def f(c, foo):
|
|
164
|
+
return c, foo.my_array
|
|
165
|
+
|
|
166
|
+
with pytest.raises(ValueError) as e:
|
|
167
|
+
hax.scan(f, Height)(0, foo)
|
|
168
|
+
|
|
169
|
+
assert "foo.my_array" in str(e.value)
|
|
170
|
+
|
|
171
|
+
|
|
139
172
|
def test_fold():
|
|
140
173
|
Height = Axis("Height", 10)
|
|
141
174
|
Width = Axis("Width", 3)
|
|
@@ -59,6 +59,34 @@ def test_pspec_for_named_axes():
|
|
|
59
59
|
assert specs.unnamed1 == PartitionSpec(None)
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
class ArrayModule(eqx.Module):
|
|
63
|
+
arr: Array = hax.field(axis_names=("dim2", "dim3"))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_pspec_for_plain_array_axis_names():
|
|
67
|
+
mesh = Mesh(np.array(jax.devices()).reshape(-1, 1), (ResourceAxis.DATA, ResourceAxis.MODEL))
|
|
68
|
+
with axis_mapping(resource_map), mesh:
|
|
69
|
+
mod = ArrayModule(jnp.ones((Dim2.size, Dim3.size)))
|
|
70
|
+
|
|
71
|
+
specs: ArrayModule = pspec_for(mod, preserve_existing_shardings=False)
|
|
72
|
+
|
|
73
|
+
assert specs.arr == PartitionSpec(ResourceAxis.DATA, ResourceAxis.MODEL)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class NestedArrayModule(eqx.Module):
|
|
77
|
+
inner: ArrayModule
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_pspec_for_plain_array_axis_names_nested_module():
|
|
81
|
+
mesh = Mesh(np.array(jax.devices()).reshape(-1, 1), (ResourceAxis.DATA, ResourceAxis.MODEL))
|
|
82
|
+
with axis_mapping(resource_map), mesh:
|
|
83
|
+
mod = NestedArrayModule(ArrayModule(jnp.ones((Dim2.size, Dim3.size))))
|
|
84
|
+
|
|
85
|
+
specs: NestedArrayModule = pspec_for(mod, preserve_existing_shardings=False)
|
|
86
|
+
|
|
87
|
+
assert specs.inner.arr == PartitionSpec(ResourceAxis.DATA, ResourceAxis.MODEL)
|
|
88
|
+
|
|
89
|
+
|
|
62
90
|
class MyModuleInit(eqx.Module):
|
|
63
91
|
named: NamedArray
|
|
64
92
|
unnamed1: Array
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev402"
|
|
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
|
|
File without changes
|